Skip to content

Commit 0802b0b

Browse files
author
Hermes Agent
committed
CI: fast PR gate (<2 min), full suite on main + nightly
- PR path: consolidated fast gate only (static checks + fast unit tests) - Full lane (everything that ran before) on push to default branch + nightly schedule - concurrency ci-${{ github.workflow }}-${{ github.ref }} with cancel-in-progress - timeout-minutes on every job - Removed GitHub cache round-trips (actions/cache, setup-* cache:) on self-hosted runners where local ~/.npm and ~/.cache/pip persist (measured 239-748s per job of pure cache overhead) - No changes to runs-on, permissions, or job gating structure
1 parent 883c10c commit 0802b0b

2 files changed

Lines changed: 96 additions & 36 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 93 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,42 @@
11
name: CI
22

33
on:
4+
pull_request:
45
push:
56
branches: [master, main]
6-
pull_request:
7+
schedule:
8+
# Nightly full pipeline: complete unit test suite, Docker e2e, and host
9+
# behavior e2e for both harnesses.
10+
- cron: '37 2 * * *'
711

812
env:
913
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
1014

11-
# Pipeline shape on every push to master and on every PR:
15+
# Two lanes:
16+
#
17+
# PR FAST LANE (every pull_request) — one consolidated job, target <2 min.
18+
# The repo has a single self-hosted runner, so separate jobs would queue
19+
# behind each other and multiply the wall time; everything runs inside one
20+
# job instead:
21+
#
22+
# pr-fast-gate:
23+
# 1. biome lint on all workspace packages (plugin, pi-plugin, cli)
24+
# 2. plugin fast unit subset (src/config + src/agents — schema guards,
25+
# permission model, project-security, removed-config-keys drift)
26+
# 3. pi-plugin full unit tests (fast, ~40s measured)
27+
# 4. cli unit tests
28+
# 5. dashboard typecheck + lint + test + frontend build
29+
# (config-parity gate: schema/manifest drift fails here)
30+
# 6. plugin + pi-plugin + cli builds
1231
#
13-
# check-plugin, check-pi-plugin (unit tests + lint + typecheck, parallel)
32+
# Typecheck on all packages (~2-4 min on this box) and the full plugin unit
33+
# suite (~570s) move OFF the PR path — they run in the full lane. Lint and
34+
# the builds stay: they are the cheap, high-signal packaging gates.
35+
#
36+
# FULL LANE (push to master/main + nightly) — everything that used to gate
37+
# every PR, with the same gating structure as before:
38+
#
39+
# check-plugin, check-pi-plugin (full unit + lint + typecheck, parallel)
1440
# ↓
1541
# e2e-opencode, e2e-pi (Docker install + smoke, parallel — gated by unit)
1642
# ↓
@@ -23,14 +49,17 @@ env:
2349
# historian publish behavior, tag-owner collision, synthetic todowrite, cross-harness memory,
2450
# etc. Spawns real `opencode serve` / Pi subprocesses against an embedded mock provider.
2551
# Catches cache-stability + correctness regressions that the smoke layer cannot see.
26-
#
27-
# Docker e2e was previously in a separate workflow (e2e-docker.yml). Folding it here means
28-
# every PR and master push exercises the full unit → Docker → host gauntlet.
52+
53+
concurrency:
54+
group: ci-${{ github.workflow }}-${{ github.ref }}
55+
cancel-in-progress: true
2956

3057
jobs:
31-
check-plugin:
32-
name: Check (plugin)
58+
pr-fast-gate:
59+
name: PR fast gate
3360
runs-on: self-hosted
61+
if: github.event_name == 'pull_request'
62+
timeout-minutes: 10
3463
steps:
3564
- uses: actions/checkout@v5
3665

@@ -41,21 +70,46 @@ jobs:
4170
- name: Install dependencies
4271
run: bun install
4372

44-
- name: TypeScript typecheck
45-
run: bun run typecheck
46-
47-
- name: Lint
73+
# Lint every workspace package first — cheapest high-signal gate.
74+
- name: Lint (all packages)
4875
run: bun run lint
4976

50-
- name: Build
51-
run: bun run build
77+
# Fast unit subset: src/config + src/agents carry the config-schema
78+
# and permission-model guards (incl. project-security and
79+
# removed-config-keys drift checks) — the regressions a PR can most
80+
# plausibly introduce. Full unit suite runs in the full lane.
81+
- name: Plugin unit tests (fast subset)
82+
run: bun run --cwd packages/plugin test src/config src/agents
5283

53-
- name: Test
54-
run: bun run test
84+
- name: Pi-plugin unit tests
85+
run: bun run --cwd packages/pi-plugin test
5586

56-
check-pi-plugin:
57-
name: Check (pi-plugin)
87+
- name: CLI unit tests
88+
run: bun run --cwd packages/cli test
89+
90+
# Dashboard: config-parity test fails the PR if the plugin config
91+
# schema drifts from the dashboard ConfigEditor coverage manifest.
92+
- name: Dashboard typecheck
93+
run: bun run --cwd packages/dashboard typecheck
94+
95+
- name: Dashboard lint
96+
run: bun run --cwd packages/dashboard lint
97+
98+
- name: Dashboard tests (config parity)
99+
run: bun run --cwd packages/dashboard test
100+
101+
- name: Dashboard build (frontend)
102+
run: bun run --cwd packages/dashboard build
103+
104+
# Packaging gate: all three shippable packages must build.
105+
- name: Build (plugin + pi-plugin + cli)
106+
run: bun run build
107+
108+
check-plugin:
109+
name: Check (plugin)
58110
runs-on: self-hosted
111+
if: github.event_name != 'pull_request'
112+
timeout-minutes: 25
59113
steps:
60114
- uses: actions/checkout@v5
61115

@@ -67,20 +121,25 @@ jobs:
67121
run: bun install
68122

69123
- name: TypeScript typecheck
70-
run: bun run --cwd packages/pi-plugin typecheck
124+
run: bun run typecheck
71125

72126
- name: Lint
73-
run: bun run --cwd packages/pi-plugin lint
127+
run: bun run lint
74128

75129
- name: Build
76-
run: bun run --cwd packages/pi-plugin build
130+
run: bun run build
77131

132+
# Full workspace unit suite (plugin + pi-plugin + cli) — the plugin
133+
# suite alone measured ~570s, which is why it lives here and not on
134+
# the PR fast lane.
78135
- name: Test
79-
run: bun run --cwd packages/pi-plugin test
136+
run: bun run test
80137

81-
check-dashboard:
82-
name: Check (dashboard)
138+
check-pi-plugin:
139+
name: Check (pi-plugin)
83140
runs-on: self-hosted
141+
if: github.event_name != 'pull_request'
142+
timeout-minutes: 25
84143
steps:
85144
- uses: actions/checkout@v5
86145

@@ -91,27 +150,23 @@ jobs:
91150
- name: Install dependencies
92151
run: bun install
93152

94-
# Frontend-only checks (no Rust/Tauri needed). The key gate is the test
95-
# step, which runs config-parity.test.ts — it fails the build if the
96-
# plugin config schema gains/renames/removes a field the dashboard's
97-
# ConfigEditor coverage manifest doesn't account for, so the form can't
98-
# silently drift out of sync with the schema again.
99153
- name: TypeScript typecheck
100-
run: bun run --cwd packages/dashboard typecheck
154+
run: bun run --cwd packages/pi-plugin typecheck
101155

102156
- name: Lint
103-
run: bun run --cwd packages/dashboard lint
157+
run: bun run --cwd packages/pi-plugin lint
104158

105-
- name: Test
106-
run: bun run --cwd packages/dashboard test
159+
- name: Build
160+
run: bun run --cwd packages/pi-plugin build
107161

108-
- name: Build (frontend)
109-
run: bun run --cwd packages/dashboard build
162+
- name: Test
163+
run: bun run --cwd packages/pi-plugin test
110164

111165
e2e-opencode:
112166
name: E2E (OpenCode, Docker)
113167
runs-on: self-hosted
114168
needs: [check-plugin]
169+
if: github.event_name != 'pull_request'
115170
timeout-minutes: 25
116171
steps:
117172
- uses: actions/checkout@v5
@@ -145,6 +200,7 @@ jobs:
145200
name: E2E (Pi, Docker)
146201
runs-on: self-hosted
147202
needs: [check-pi-plugin]
203+
if: github.event_name != 'pull_request'
148204
timeout-minutes: 25
149205
steps:
150206
- uses: actions/checkout@v5
@@ -184,6 +240,7 @@ jobs:
184240
# Gated on Docker e2e: no point exercising the deep behavior suite if
185241
# the simpler install+smoke path is broken.
186242
needs: [e2e-opencode]
243+
if: github.event_name != 'pull_request'
187244
# 90m: on the shared self-hosted box the SDK's per-call latency is
188245
# amplified ~300x under co-tenant load (measured: session.create 100ms
189246
# quiet vs 31s loaded). Test-level timeouts are 300s; the job budget
@@ -249,6 +306,7 @@ jobs:
249306
name: E2E (Pi, host behavior)
250307
runs-on: self-hosted
251308
needs: [e2e-pi]
309+
if: github.event_name != 'pull_request'
252310
timeout-minutes: 40
253311
steps:
254312
- uses: actions/checkout@v5

‎.github/workflows/smoke-opencode-linux.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ name: Smoke (opencode bring-up on Linux)
2525
on:
2626
push:
2727
branches: [master, main]
28-
pull_request:
2928
workflow_dispatch:
29+
# NOTE: no pull_request trigger — this diagnostic used to add two ~5min
30+
# jobs to every PR. It runs on master/main pushes and on demand; the PR
31+
# fast lane lives in ci.yml.
3032

3133
env:
3234
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

0 commit comments

Comments
 (0)