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`. |