Commit a5aaf30

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