Imported from BlackBeltTechnology/pi-agent-dashboard (
.github/workflows/AGENTS.md). Install upstream withnpx skills add BlackBeltTechnology/pi-agent-dashboard --skill workflows. Copyright stays with the author.
DOX — .github/workflows
Files in this directory. One row per file. Non-source area (migrated from docs/file-index-skills-misc.md; source of truth now here). See change: migrate-file-index-to-agents-tree.
| File | Purpose |
|---|---|
_electron-build.yml |
Reusable workflow_call. Encapsulates 6-leg Electron matrix (darwin/linux/win32 × arm64/x64) with per-leg… Top-level contents: read; use_dependency_cache input (default false) gates the pnpm cache. → see _electron-build.yml.AGENTS.md |
_smoke.yml |
Reusable workflow_call. Encapsulates 7-leg standalone-install-smoke matrix: Linux × 6 (Node 22/24/25 × bookworm-slim/alpine) + Windows × 1 (Node 22). Input ref (string, required) — git ref to check out. Consumers: ci-smoke.yml (manual dispatch), publish.yml smoke job (release gate). Pure artifact-free smoke; no npm publish, no GitHub Release, no tag push. Replaces inline standalone-install-smoke-{linux,windows} jobs deleted from ci.yml. standalone-install-smoke-windows adds step Windows introspection smoke (pwsh: npx tsx scripts/windows-introspection-smoke.ts) — exercises live PowerShell Get-CimInstance paths, asserts no wmic stderr leak. See change: gate-publish-on-smoke-and-tests, replace-wmic-with-powershell. standalone-install-smoke-windows also adds step Windows boot-parent-liveness smoke (pwsh: npx tsx scripts/windows-liveness-smoke.ts) — asserts koffi Tier-2 (OpenProcess+WaitForSingleObject) loads on real Windows (bootParentLivenessTier()==="tier2"), guarding a silent Tier-1 degrade. See change: electron-attach-ownership-fixes. See change: surface-denial-remedy-in-previews — Windows leg runs scripts/windows-forbidden-subjects-smoke.ts (host %SystemRoot% listed, no POSIX junk). Top-level permissions: contents: read. Keeps cache: pnpm (read token, no release artifact; design.md D5). See change: harden-ci-cache-poisoning. |
ci-electron.yml |
workflow_dispatch only. On-demand Electron build for feature branches. Computes version slug <base>-ci.<UTC-stamp>.<branch-slug>.<sha7> from root package.json#version + date -u +%Y%m%d-%H%M%S + sanitised GITHUB_REF_NAME (max 20 chars, [^a-zA-Z0-9.-] → -, leading/trailing .- stripped) + GITHUB_SHA[:7]. Validates slug against publish.yml's SemVer regex. Delegates entirely to _electron-build.yml with source_only_bundle: false, artifact_retention_days: 14, ref: ${{ github.sha }}. Optional legs input forwarded. Prerelease segment SemVer-ranks below <base> — electron-updater default allowPrerelease: false skips these slugs so installed-user update channel is unaffected. No npm publish, no GitHub Release, no tag. Post fix-ci-electron-runnable-bundles, CI-dispatched artefacts ship runnable installer layout identical to release builds; earlier true value (set by add-ci-electron-on-demand-build Decision 3) invalidated by eliminate-electron-runtime-install removing every runtime install path; locked by publish-workflow-contract.test.ts ci-electron.yml — runnable-bundle contract describe block (asserts literal source_only_bundle: false). See change: add-ci-electron-on-demand-build, fix-ci-electron-runnable-bundles. Top-level permissions: contents: read; passes use_dependency_cache: true to _electron-build.yml (dev builds, attached to no release). See change: harden-ci-cache-poisoning. |
ci-e2e-browser.yml |
Sharded browser-E2E (tests/e2e/, 168+ Playwright specs) against the Docker harness. Triggers: workflow_dispatch (+ informational shards input), pull_request on develop GATED on the e2e-browser label (types opened/synchronize/reopened/labeled), and schedule cron '30 7 * * *' COMMENTED (land-dark, like nightly.yml; enable at task 5.5 once the baseline is green — exactly one of active/commented, contract-enforced). No push. ADVISORY: continue-on-error on the PR path only; flipped to required in a separate change after two green nightlies. Jobs: e2e (matrix shard: [1..18], runs-on: ubuntu-latest, timeout-minutes: 120, fail-fast: false, PI_E2E_SEED=1, PW_E2E_BOOT_TIMEOUT_MS=1200000 (a cache-less runner spends ~6-8min building the image before the health poll can succeed), TEST_COPY_MODE=1 (GitHub runners refuse the entrypoint's mount -t overlay → the container crash-looped; copy-mode is the spec-sanctioned no-capability fallback, free here because globalSetup boots from an EMPTY workspace), pnpm exec playwright test --shard=${{ matrix.shard }}/18, uploads blob-report-<n> and harness-failure-<n> (globalSetup's container state+log snapshot when the boot never goes healthy — the bundle that made the overlay failure diagnosable), then if: always() Tear down harness reading the workspace from test-results/.e2e-managed as JSON (globalSetup writes JSON.stringify; require() of the extensionless file loads it as JS and throws, so the old form's ` |
ci-e2e-electron.yml |
Playwright-Electron suite for native-surface flows (zombie-adoption modal, Doctor version-skew row, tray foreign row) unreachable by web-client E2E + unit tests. Cadence: workflow_dispatch + pull_request path-filter (packages/electron/**, tests/e2e-electron/**, playwright.electron.config.ts, self) — ADVISORY (not a required check). Matrix os: [ubuntu-latest, windows-latest], fail-fast: false: ubuntu exercises POSIX decideIsZombie, windows the win32 branch (bootParentAlive-only) in the REAL app (task 7.4b). OS-split npm ci fallback (bash vs pwsh) → package → ubuntu adds playwright install-deps chromium + sysctl apparmor_restrict_unprivileged_userns=0 (noble) then xvfb-run; windows runs direct. Harness launches with --no-sandbox; Linux binary resolved by forge executableName pi-dashboard (NOT chrome-sandbox). Uploads playwright-report-electron-<os>. Second job job-object-windows (continue-on-error, advisory): downloads bundled Node + package + npx tsx scripts/windows-job-object-smoke.ts (spawn-mode Job Object kill-on-close, task 7.4a) — INFRA when a lightweight package can't boot the full spawn path (deep validation lives in qa VM smoke). Concurrency cancel-in-progress per ref. See change: electron-attach-ownership-fixes (harness), run-electron-e2e-native-surface (cadence + stabilization). Job runtime-overlay-e2e (ubuntu, 90 min; change: electron-runtime-release-pipeline): throwaway Verdaccio (scripts/runtime-e2e-registry.mjs config → VERDACCIO_CONFIG) → publish base → bundle-server.mjs with npm_config_registry → forge package → publish good/broken → playwright … runtime-overlay-update under xvfb (PW_ELECTRON_GLOBAL_TIMEOUT_MS 1 h). Paths filter adds packages/server/src/runtime-overlay/** + the two runtime scripts. Top-level permissions: contents: read (job-level block on runtime-overlay-e2e unchanged). See change: harden-ci-cache-poisoning. Event-keyed cadence (change: add-missing-ci-legs, #531): matrix is fromJSON on github.event_name — PR → ubuntu+windows, workflow_dispatch → +macOS, nightly schedule (17 3 * * *) → macOS only; runtime-overlay-e2e + job-object-windows carry if: github.event_name != 'schedule'; suite run step if: runner.os != 'Linux' (Windows + macOS); no labeled trigger; no continue-on-error on electron-e2e; header names the darwin zombie-adoption quarantine (#531). Locked by e2e-electron-workflow-contract.test.ts. |
ci-gateway-platform.yml |
workflow_dispatch + PR-on-paths (transport sources, the two arms, itself). Runs the gateway's transport contract on the OS that DECIDES it, which one runner structurally cannot see: posix matrix (ubuntu + macOS) shims pi-dashboard to this checkout and runs qa/tests/29-gateway-posix-no-tcp.sh (default start advertises a socket and binds NO TCP port); windows runs qa/tests/28-gateway-windows.ps1 (loopback fallback, no socket artifact, hard-drop reconnect as one session, second-standard-user credential read). Kept OUT of ci.yml on purpose — that is a cheap one-runner PR net, this boots real dashboards on three OSes. See change: add-pi-gateway-transport-identity (tasks 5.1/5.5/5.7/12.53/13.8). Top-level permissions: contents: read. See change: harden-ci-cache-poisoning. |
ci-smoke.yml |
workflow_dispatch only. Thin shim around _smoke.yml passing ref: ${{ github.ref }}. Concurrency ci-smoke-${{ github.ref }} cancel-in-progress so re-dispatch on same branch cancels prior run. Use for installer-shaped feature branches (lockfile, bundle-server.mjs, native deps, preload-fastify) where PR's cheap ci.yml job lacks coverage. Sibling of ci-electron.yml. No npm publish, no GitHub Release, no tag push. See change: gate-publish-on-smoke-and-tests. Top-level permissions: contents: read. See change: harden-ci-cache-poisoning. |
ci.yml |
PR + develop-push net on Node 22, parallel jobs (change: speed-up-ci-affected-tests, D5). Triggers: push develop, pull_request develop (default types — NO labeled, so a label can never publish a fake-green run), workflow_dispatch (always full). Top-level permissions contents:read. concurrency ci-${{ github.event.pull_request.number || github.sha }}, cancel-in-progress only for PRs. Jobs: select (fetch-depth: 0, pnpm install, node scripts/select-affected-tests.mjs — PR --base origin/<base> --merge-base, push --base <before>, dispatch or ci:full label --full; uploads artifact test-selection; outputs mode/has_real_process/ci_scenarios) · ci (guards, spec validate, skill/fixed-tick/settings-path/publish-import checks, PR plugin install-load, kb dist freshness, lint, lint:e2e, Biome, build + warning gate, post-build publish-imports — NO tests, NO chromium) · unit (matrix shard: [1,2,3,4] == SHARD_COUNT; assigned.mjs → empty shard skips steps; chromium; packages/client/dist/index.html assertion; pnpm run test:parallel <files> or --shard=n/4 when enumerated=false; verify-executed.mjs; uploads vitest-report-unit-<n> if: always()) · real-process (if: has_real_process; pnpm run test:real-process <files>; uploads vitest-report-real-process) · ci-scenarios (if: ci_scenarios — false only for OpenSpec-only diffs; pnpm run test:ci-scenarios <gated files>; uploads vitest-report-ci-scenarios) · docker-plugin-load · music-pytest · ci-result (if: always(), needs EVERY job incl. select, runs check-result.mjs with NEEDS_JSON: ${{ toJSON(needs) }}). Locked by packages/shared/src/__tests__/ci-affected-selection-contract.test.ts + ci-vitest-report-artifact.test.ts. See changes: isolate-real-process-tests, speed-up-ci-affected-tests. |
codeql.yml |
CodeQL advanced setup (replaces default setup). Triggers: push + pull_request on develop, weekly schedule. Matrix actions/javascript-typescript/python, build-mode: none, config-file: ./.github/codeql/codeql-config.yml, analyze category /language:${{ matrix.language }} (pinned = default-setup categories, keeps dismissals). Top-level permissions: contents: read, security-events: write, actions: read. No cache, no install step. Not a required check. Contract: packages/shared/src/__tests__/codeql-workflow-contract.test.ts. See change: add-local-codeql-ratchet. |
deploy-site.yml |
Builds + deploys site/ (hand-written static page; npm run build = node build.mjs copy + reference check) plus the neutral shell (packages/shell → site/dist/app/) to GitHub Pages via actions/deploy-pages@v4. Triggers: push to develop under site/** (minus design-scratch/), packages/shell/**, or the workflow itself; workflow_dispatch. No release: trigger — the default Actions token cannot start runs from release events (never has); the release path is publish.yml's site-redeploy job dispatching this workflow on develop. Runs npm run check-release non-blocking. Locked by site-deploy-workflow-contract.test.ts (E9/E10/E12/E14) + pnpm-migration-contract.test.ts X6. See change: fix-deploy-site-ship-shell. Build writes site/dist/deploy-sha.txt (${{ github.sha }}) before upload and runs only on github.ref == 'refs/heads/develop' (deploy needs: build); daily site-drift-check.yml backstops the push trigger. See change: add-missing-ci-legs (#579). |
nightly.yml |
Scheduled full-fidelity Verdaccio round-trip (workflow_dispatch active; cron '0 7 * * *' present but COMMENTED per land-dark rollout — enable after one clean manual run). Jobs: resolve (compute <base>-nightly.<YYYYMMDD>.<sha7>, <base> = next patch of package.json version) → verify-publish (npm publish --dry-run all workspaces, cheap pack pre-gate, no network write) → electron (uses: _electron-build.yml with registry_url: http://localhost:4873, source_only_bundle: false, legs: all, artifact_retention_days: 7) → report (if: failure(), github-script opens/updates a single issue labelled nightly naming the failed leg(s) + run URL). ZERO public npm writes / NO Release / NO tag push / NO version-bump commit — locked by nightly-workflow-contract.test.ts. See change: add-nightly-verdaccio-build. electron passes use_dependency_cache: true (nightly artifacts attached to no release). See change: harden-ci-cache-poisoning. |
nightly-tests.yml |
Full vitest suite every night (change: speed-up-ci-affected-tests, D6) — the safety net under affected-only selection. Triggers: ACTIVE cron '0 3 * * *' + workflow_dispatch. Top-level permissions contents:read; only report adds issues:write + actions:read (least privilege). Jobs: select (--full) → unit ×4 (chromium, dist assertion, verify-executed, slow tier included) · real-process · ci-scenarios (plain pnpm run test:ci-scenarios) → report (if: always(), fetch-depth: 0, scripts/test-selection/nightly-report.mjs: failing files per job, jobs with NO report, bisect range since the last green SCHEDULED develop run; on a scheduled run opens/updates the single open nightly-tests issue or comments+closes it on green; uploads refreshed test-timings). Independent of land-dark nightly.yml; never publishes/tags. Locked by packages/shared/src/__tests__/nightly-tests-workflow-contract.test.ts. |
publish.yml |
CI: builds DMG × 2 (macOS arm64 + x64), DEB+AppImage (Linux), NSIS+ZIP+portable (Windows) on native runners;… Top-level contents: read; release-privileged jobs install cold (no cache); electron passes use_dependency_cache: false. → see publish.yml.AGENTS.md |
site-drift-check.yml |
Daily schedule (23 5 * * *) + workflow_dispatch backstop for deploy-site.yml's single push trigger. Checks out develop (full history), runs node scripts/site-drift-decision.mjs --ref origin/develop: live deploy-sha.txt vs last site-relevant commit; stale → ::warning:: + gh workflow run deploy-site.yml --ref develop (skips with ::notice:: while a deploy is queued/in progress or gh run list fails; red when the dispatch is rejected). Top contents: read, job exactly contents: read + actions: write, no cache, outside the pages-deploy group. Locked by site-deploy-workflow-contract.test.ts + workflow-token-cache-contract.test.ts. See change: add-missing-ci-legs (#579). |
sync-release-version.yml |
Rewrites the download block in site/index.html (inline release data — no latest-release.json since the static-page rewrite) from gh api repos/$REPO/releases/latest via site/design-scratch/scripts/sync-release.mjs (assets matched by SHAPE: extension + arch suffix), commits to develop as github-actions[bot] (a default-token commit does NOT trigger another workflow — the push path filter cannot fire on it). The working release path: publish.yml site-redeploy dispatches this workflow, waits via correlation-token run lookup + gh run watch --exit-status + explicit conclusion check, then dispatches deploy-site.yml --ref develop explicitly. Trigger: workflow_dispatch ONLY (correlation input). release: removed — it fired only for hand-published prerelease drafts and that run was incomplete (its GITHUB_TOKEN commit cannot start deploy-site.yml). Manual recovery = TWO dispatches: sync-release-version, then deploy-site. Locked by site-deploy-workflow-contract.test.ts E11 + sync-release-version.yml has no release-event trigger describe. See change: fix-deploy-site-ship-shell, fix-ci-pipeline-followups. |
