2020 runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
2121 timeout-minutes : 5
2222 steps :
23- - uses : actions/checkout@v4
24- - uses : actions/setup-node@v4
23+ - uses : actions/checkout@v5
24+ - uses : actions/setup-node@v5
2525 with :
2626 node-version : " 20"
2727 - name : Verify workspace config (.beads / .automaker / owned runners)
6464 runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
6565 timeout-minutes : 5
6666 steps :
67- - uses : actions/checkout@v4
68- - uses : actions/setup-python@v5
67+ - uses : actions/checkout@v5
68+ - uses : actions/setup-python@v6
6969 with :
7070 python-version : " 3.12"
7171 - name : Ruff check
8989 runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
9090 timeout-minutes : 15
9191 steps :
92- - uses : actions/checkout@v4
93- - uses : actions/setup-python@v5
92+ - uses : actions/checkout@v5
93+ - uses : actions/setup-python@v6
9494 with :
9595 python-version : " 3.12"
9696 cache : pip
@@ -107,13 +107,45 @@ jobs:
107107 . .venv/bin/activate
108108 python -m pytest tests/ -q
109109
110+ fleet-integration :
111+ name : Fleet integration (multi-instance)
112+ runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
113+ # These tests boot real `python -m server` hub+member processes (against the
114+ # local scripts/fake_openai_server.py) on free loopback ports + tmp roots, so
115+ # they're much slower than the unit suite — allow ~10 min. Kept a SEPARATE job
116+ # from `tests` so its real-boot slowness never gates the fast unit run.
117+ timeout-minutes : 12
118+ steps :
119+ - uses : actions/checkout@v5
120+ - uses : actions/setup-python@v6
121+ with :
122+ python-version : " 3.12"
123+ cache : pip
124+ - name : Install dependencies
125+ # Mirror the `tests` job: full requirements.txt in a venv so
126+ # tests/conftest.py's site.getsitepackages() reorder resolves (#175).
127+ run : |
128+ python -m venv .venv
129+ . .venv/bin/activate
130+ python -m pip install --upgrade pip
131+ pip install -r requirements.txt pytest pytest-asyncio
132+ - name : Boot real multi-instance fleet (hub + members) and exercise it
133+ # PA_RUN_INTEGRATION=1 flips on the real-subprocess harness the default
134+ # `pytest tests/` skips. Covers instance isolation, hub→member proxy
135+ # round-trip, cross-instance A2A delegation, and member crash→detect→restart
136+ # (POSIX zombie-reap — works on Linux). No network egress beyond loopback:
137+ # the fake gateway is local; mDNS advertise binds loopback only.
138+ run : |
139+ . .venv/bin/activate
140+ PA_RUN_INTEGRATION=1 python -m pytest tests/integration -q
141+
110142 live-smoke :
111143 name : A2A live smoke (lean tier)
112144 runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
113145 timeout-minutes : 10
114146 steps :
115- - uses : actions/checkout@v4
116- - uses : actions/setup-python@v5
147+ - uses : actions/checkout@v5
148+ - uses : actions/setup-python@v6
117149 with :
118150 python-version : " 3.12"
119151 cache : pip
@@ -139,8 +171,8 @@ jobs:
139171 runs-on : ubuntu-latest # workspace-config: allow-hosted-runner public repo — GH-hosted is free
140172 timeout-minutes : 10
141173 steps :
142- - uses : actions/checkout@v4
143- - uses : actions/setup-node@v4
174+ - uses : actions/checkout@v5
175+ - uses : actions/setup-node@v5
144176 with :
145177 node-version : " 20"
146178 cache : npm
@@ -151,8 +183,37 @@ jobs:
151183 # the uiStore persist migration). Fast — runs before the heavier
152184 # Playwright path so a reducer regression fails the job early.
153185 run : npm run test:unit --workspace @protoagent/web
154- - name : Install Playwright chromium
155- run : npm --workspace @protoagent/web exec -- playwright install --with-deps chromium
186+ - name : Resolve Playwright version
187+ id : pw
188+ run : echo "version=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_OUTPUT"
189+ - name : Cache Playwright browsers
190+ id : pw-cache
191+ uses : actions/cache@v5
192+ with :
193+ path : ~/.cache/ms-playwright
194+ key : playwright-${{ runner.os }}-${{ steps.pw.outputs.version }}
195+ - name : Install Playwright browser + deps
196+ # The chromium binary is the slow ~100MB CDN download that intermittently
197+ # stalled ~10min until the job-level orphan-kill fired (#1167). Cache it keyed
198+ # on the Playwright version (skips the download entirely on a hit — only the
199+ # fast apt system-deps run then), and hard-cap each attempt with `timeout` so
200+ # a stalled download fails fast and retries instead of hanging the whole job.
201+ timeout-minutes : 8
202+ run : |
203+ if [ "${{ steps.pw-cache.outputs.cache-hit }}" = "true" ]; then
204+ cmd="playwright install-deps chromium" # binary cached → apt deps only
205+ else
206+ cmd="playwright install --with-deps chromium"
207+ fi
208+ for attempt in 1 2 3; do
209+ if timeout 240 npm --workspace @protoagent/web exec -- $cmd; then
210+ exit 0
211+ fi
212+ echo "::warning::playwright install attempt $attempt stalled/failed; retrying…"
213+ sleep 5
214+ done
215+ echo "::error::playwright install failed after 3 attempts"
216+ exit 1
156217 - name : Run E2E smoke (built SPA vs mock backend)
157218 # Builds the web app, then drives it with Playwright against the
158219 # deterministic mock backend (apps/web/e2e/mock-server.mjs) — no Python,
0 commit comments