Commit a5aaf30
Eric Bower
·
2026-08-15 09:36:51 -0400 EDT
parent 818edb5
docs: gha proposal
1 files changed,
+178,
-0
+178,
-0
1@@ -0,0 +1,178 @@
2+# Proposal: Integrating Pici with GitHub Actions & `pipe.pico.sh` Remote Debugging
3+
4+## 1. Executive Summary
5+
6+Migrating existing projects away from GitHub Actions to a dedicated self-hosted CI system is difficult due to ecosystem inertia and configuration friction.
7+
8+This proposal outlines a strategy to **integrate `pici` with GitHub Actions as a drop-in execution engine**. Developers write standard, parallel bash workflows (`pico.sh`) using `zmx`, execute them identically on both local workstations and GitHub Actions runners, and gain **live, interactive terminal debugging on failure** powered by `pipe.pico.sh`.
9+
10+```mermaid
11+flowchart TD
12+ subgraph Local Environment
13+ Dev[Developer] -->|Runs locally| LocalScript["./pico.sh (or pici run)"]
14+ LocalScript -->|PTY Sessions| LocalZMX["zmx (Parallel Tasks)"]
15+ end
16+
17+ subgraph GitHub Actions Runner
18+ GHA[GitHub Actions Workflow] --> InstallZMX["Install zmx"]
19+ InstallZMX --> RunScript["Run ./pici-debug.sh"]
20+ RunScript --> RunnerZMX["zmx sessions (Host & Docker)"]
21+
22+ RunnerZMX -->|Success| GHASuccess["Finish Job (0)"]
23+ RunnerZMX -->|Failure| CatchError["Catch non-zero exit code"]
24+
25+ CatchError --> StartBridge["Open bidirectional pipe to pipe.pico.sh"]
26+ StartBridge --> AllocPTY["Allocate interactive PTY (script / bash -i)"]
27+ end
28+
29+ subgraph Pico Cloud Relay
30+ PipeRelay["ssh pipe.pico.sh pipe {topic}"]
31+ end
32+
33+ StartBridge <-->|SSH stdin/stdout| PipeRelay
34+ Dev -.->|ssh -t pipe.pico.sh pipe {topic}| PipeRelay
35+```
36+
37+---
38+
39+## 2. Core Design Goals
40+
41+1. **1:1 Local & Remote Parity**: The exact same `./pico.sh` runs locally and on CI without emulation layers or proprietary YAML DSLs.
42+2. **Native Docker Compatibility**: Seamless support for `docker run ...` steps in `pico.sh` within standard GitHub-hosted runners (`ubuntu-latest`).
43+3. **Interactive Debug on Failure ("Attach")**: When a task fails on GitHub Actions, the runner pauses and establishes an outbound reverse PTY bridge via `pipe.pico.sh`.
44+4. **Zero-Config Pico Authentication**: Key-based authentication directly through the developer's SSH private key—no usernames or external tunnel tokens required.
45+
46+---
47+
48+## 3. Remote Debugging Architecture (`pipe.pico.sh`)
49+
50+### Why `pipe.pico.sh`?
51+`pipe.pico.sh` provides authenticated, bidirectional byte streaming (`io.ReadWriter`) across topics over SSH. Because connections are outbound from the runner, no inbound ports or complex firewall configurations are necessary.
52+
53+1. **Authentication & Topic Privacy**:
54+ - The GitHub Actions runner authenticates using the developer's `PICO_SSH_KEY` secret.
55+ - Topics created by an authenticated SSH key are automatically private and isolated to that account.
56+2. **PTY Bridging**:
57+ - Standard shell redirection (`A | B`) does not allocate a pseudo-terminal (PTY) and is unidirectional.
58+ - By creating named FIFOs (`mkfifo`) and wrapping an interactive shell with `script -q -f -c "bash -i"`, the bridge forwards full PTY escape sequences, window sizes, and raw terminal input.
59+
60+---
61+
62+## 4. Initial Implementation: `pici-debug.sh`
63+
64+A minimal, pure-bash wrapper that can be placed in any repository to execute CI and open the debug bridge on failure.
65+
66+```bash
67+#!/usr/bin/env bash
68+set -e
69+
70+TOPIC="pici-${GITHUB_RUN_ID:-$RANDOM}"
71+FIFO_IN=$(mktemp -u /tmp/pici-in.XXXXXX)
72+FIFO_OUT=$(mktemp -u /tmp/pici-out.XXXXXX)
73+
74+cleanup() {
75+ kill "$SSH_PID" 2>/dev/null || true
76+ rm -f "$FIFO_IN" "$FIFO_OUT"
77+}
78+trap cleanup EXIT
79+
80+# 1. Run the CI script
81+echo "==> Running pico.sh..."
82+if ./pico.sh; then
83+ echo "==> CI succeeded!"
84+ exit 0
85+fi
86+
87+CI_EXIT_CODE=$?
88+
89+# 2. Check if debug mode is enabled
90+if [ "${DEBUG_ON_FAIL:-1}" != "1" ]; then
91+ exit "$CI_EXIT_CODE"
92+fi
93+
94+echo "================================================================"
95+echo "🔴 CI FAILED! Debug bridge active on pipe.pico.sh"
96+echo "Connect from your terminal using:"
97+echo " ssh -t pipe.pico.sh pipe $TOPIC"
98+echo "================================================================"
99+
100+# 3. Create FIFOs for bidirectional PTY stream
101+mkfifo "$FIFO_IN" "$FIFO_OUT"
102+
103+# 4. Connect background bridge to pipe.pico.sh using SSH key
104+ssh -N -o StrictHostKeyChecking=no \
105+ -o ServerAliveInterval=15 \
106+ pipe.pico.sh "pipe $TOPIC" < "$FIFO_OUT" > "$FIFO_IN" &
107+SSH_PID=$!
108+
109+# 5. Spawn interactive PTY bash shell connected to the pipe
110+script -q -f -c "
111+ echo '=== Connected to GitHub Actions Debug Shell ==='
112+ echo ''
113+ echo 'Current zmx sessions:'
114+ zmx list || true
115+ echo ''
116+ echo 'Type exit to finish CI run.'
117+ bash -i
118+" /dev/null < "$FIFO_IN" > "$FIFO_OUT"
119+
120+exit "$CI_EXIT_CODE"
121+```
122+
123+---
124+
125+## 5. GitHub Actions Workflow Integration
126+
127+### Workflow Example (`.github/workflows/ci.yml`)
128+
129+```yaml
130+name: CI
131+on: [push, pull_request]
132+
133+jobs:
134+ pici:
135+ runs-on: ubuntu-latest
136+ steps:
137+ - uses: actions/checkout@v4
138+
139+ - name: Install zmx
140+ run: |
141+ # Fetch and install zmx binary
142+ sudo curl -fsSL https://github.com/picosh/zmx/releases/latest/download/zmx_linux_amd64 -o /usr/local/bin/zmx
143+ sudo chmod +x /usr/local/bin/zmx
144+
145+ - name: Setup Pico SSH Key
146+ if: always()
147+ env:
148+ PICO_SSH_KEY: ${{ secrets.PICO_SSH_KEY }}
149+ run: |
150+ mkdir -p ~/.ssh
151+ echo "$PICO_SSH_KEY" > ~/.ssh/id_ed25519
152+ chmod 600 ~/.ssh/id_ed25519
153+
154+ - name: Run CI with Pici Debug Bridge
155+ env:
156+ DEBUG_ON_FAIL: "1"
157+ run: ./pici-debug.sh
158+```
159+
160+---
161+
162+## 6. Docker Considerations
163+
164+- **Out of the box**: GitHub Actions `ubuntu-latest` runners come with Docker pre-installed and running. `docker run` commands inside `pico.sh` execute directly against the host Docker daemon.
165+- **Debugging Docker Containers**: When attached via the debug shell:
166+ - Users can inspect running/stopped containers via `docker ps -a`.
167+ - Users can enter failed containers using `docker exec -it <container_id> /bin/bash`.
168+ - For steps using `--rm`, users can rerun the command without `--rm` inside the debug shell to inspect intermediate layers.
169+
170+---
171+
172+## 7. Adoption & Evolution Roadmap
173+
174+| Phase | Deliverable | Description |
175+| :--- | :--- | :--- |
176+| **Phase 1 (Immediate)** | `pici-debug.sh` Bash Script | Pure script wrapper requiring zero changes to `pici` or Go codebases. |
177+| **Phase 2 (Packaging)** | `pico-sh/pici-action` | Dedicated GitHub Action packaging `zmx` installation, key setup, and step summary outputs. |
178+| **Phase 3 (Native Go Bridge)** | `pici debug` Subcommand | Built-in `pici` CLI command implementing native SSH dialing to `pipe.pico.sh` with `creack/pty`. |
179+| **Phase 4 (Reporting)** | Rich Step Summaries | Exporting `zmx` session history (`zmx history --html`) directly into `$GITHUB_STEP_SUMMARY`. |