Skip to content

Commit 1aff323

Browse files
committed
Tune CI wall-clock and hygiene
1 parent 51cfd6c commit 1aff323

2 files changed

Lines changed: 126 additions & 60 deletions

File tree

.github/workflows/ci.yml

Lines changed: 111 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,58 @@ on:
77
- main
88

99
concurrency:
10-
group: ci-${{ github.event_name == 'push' && format('{0}-{1}', github.ref, github.sha) || github.ref }}
11-
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
10+
group: ci-${{ github.ref }}
11+
cancel-in-progress: true
1212

1313
jobs:
14+
changes:
15+
name: Changed paths
16+
runs-on: blacksmith-4vcpu-ubuntu-2404
17+
timeout-minutes: 10
18+
outputs:
19+
desktop_smoke: ${{ github.event_name != 'pull_request' || steps.filter.outputs.desktop_smoke == 'true' }}
20+
selfhost_docker_smoke: ${{ github.event_name != 'pull_request' || steps.filter.outputs.selfhost_docker_smoke == 'true' }}
21+
steps:
22+
- uses: actions/checkout@v4
23+
24+
- name: Filter changed paths
25+
id: filter
26+
if: github.event_name == 'pull_request'
27+
uses: dorny/paths-filter@v3
28+
with:
29+
filters: |
30+
desktop_smoke:
31+
- ".github/workflows/**"
32+
- "bun.lock"
33+
- "package.json"
34+
- "turbo.json"
35+
- "apps/desktop/**"
36+
- "apps/local/**"
37+
- "apps/cli/**"
38+
- "packages/app/**"
39+
- "packages/core/**"
40+
- "packages/hosts/mcp/**"
41+
- "packages/kernel/runtime-quickjs/**"
42+
- "packages/plugins/**"
43+
- "packages/react/**"
44+
selfhost_docker_smoke:
45+
- ".github/workflows/**"
46+
- ".dockerignore"
47+
- "bun.lock"
48+
- "package.json"
49+
- "turbo.json"
50+
- "apps/host-selfhost/**"
51+
- "packages/app/**"
52+
- "packages/core/**"
53+
- "packages/hosts/mcp/**"
54+
- "packages/kernel/runtime-quickjs/**"
55+
- "packages/plugins/**"
56+
- "packages/react/**"
57+
1458
format:
1559
name: Format
1660
runs-on: blacksmith-4vcpu-ubuntu-2404
61+
timeout-minutes: 10
1762
steps:
1863
- uses: actions/checkout@v4
1964

@@ -22,27 +67,21 @@ jobs:
2267
bun-version: 1.3.11
2368

2469
- name: Cache Bun package cache
25-
uses: actions/cache@v4
70+
uses: useblacksmith/cache@v5
2671
with:
2772
path: ~/.bun/install/cache
2873
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
2974
restore-keys: |
3075
${{ runner.os }}-bun-1.3.11-
3176
32-
# No prebuilt better-sqlite3 binary matches this runner, so `bun install`
33-
# builds it from source via node-gyp, whose undici needs Node 22.10+
34-
# (webidl.markAsUncloneable). Pin the same runtime the test/e2e jobs use.
35-
- uses: actions/setup-node@v4
36-
with:
37-
node-version: 22
38-
39-
- run: bun install --frozen-lockfile
77+
- run: bun install --frozen-lockfile --ignore-scripts
4078

4179
- run: bun run format:check
4280

4381
lint:
4482
name: Lint
4583
runs-on: blacksmith-4vcpu-ubuntu-2404
84+
timeout-minutes: 10
4685
steps:
4786
- uses: actions/checkout@v4
4887

@@ -51,27 +90,21 @@ jobs:
5190
bun-version: 1.3.11
5291

5392
- name: Cache Bun package cache
54-
uses: actions/cache@v4
93+
uses: useblacksmith/cache@v5
5594
with:
5695
path: ~/.bun/install/cache
5796
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
5897
restore-keys: |
5998
${{ runner.os }}-bun-1.3.11-
6099
61-
# No prebuilt better-sqlite3 binary matches this runner, so `bun install`
62-
# builds it from source via node-gyp, whose undici needs Node 22.10+
63-
# (webidl.markAsUncloneable). Pin the same runtime the test/e2e jobs use.
64-
- uses: actions/setup-node@v4
65-
with:
66-
node-version: 22
67-
68-
- run: bun install --frozen-lockfile
100+
- run: bun install --frozen-lockfile --ignore-scripts
69101

70102
- run: bun run lint
71103

72104
typecheck:
73105
name: Typecheck
74106
runs-on: blacksmith-4vcpu-ubuntu-2404
107+
timeout-minutes: 15
75108
steps:
76109
- uses: actions/checkout@v4
77110

@@ -80,7 +113,7 @@ jobs:
80113
bun-version: 1.3.11
81114

82115
- name: Cache Bun package cache
83-
uses: actions/cache@v4
116+
uses: useblacksmith/cache@v5
84117
with:
85118
path: ~/.bun/install/cache
86119
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
@@ -89,10 +122,19 @@ jobs:
89122
90123
# No prebuilt better-sqlite3 binary matches this runner, so `bun install`
91124
# builds it from source via node-gyp, whose undici needs Node 22.10+
92-
# (webidl.markAsUncloneable). Pin the same runtime the test/e2e jobs use.
125+
# (webidl.markAsUncloneable). Pin the same Node 24 runtime used by release.
93126
- uses: actions/setup-node@v4
94127
with:
95-
node-version: 22
128+
node-version: 24
129+
130+
- name: Cache Turbo task cache
131+
uses: useblacksmith/cache@v5
132+
with:
133+
path: .turbo
134+
key: ${{ runner.os }}-turbo-typecheck-${{ hashFiles('bun.lock', 'turbo.json') }}
135+
restore-keys: |
136+
${{ runner.os }}-turbo-typecheck-
137+
${{ runner.os }}-turbo-
96138
97139
- run: bun install --frozen-lockfile
98140

@@ -101,8 +143,10 @@ jobs:
101143
test:
102144
name: Test
103145
runs-on: blacksmith-4vcpu-ubuntu-2404
146+
timeout-minutes: 15
147+
# Tuned for Blacksmith's 4 vCPU runners.
104148
env:
105-
TURBO_TEST_CONCURRENCY: 3
149+
TURBO_TEST_CONCURRENCY: 4
106150
steps:
107151
- uses: actions/checkout@v4
108152

@@ -111,7 +155,7 @@ jobs:
111155
bun-version: 1.3.11
112156

113157
- name: Cache Bun package cache
114-
uses: actions/cache@v4
158+
uses: useblacksmith/cache@v5
115159
with:
116160
path: ~/.bun/install/cache
117161
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
@@ -120,10 +164,19 @@ jobs:
120164
121165
# apps/cloud's test script invokes `node` directly; undici 8.x (pulled
122166
# in by @cloudflare/vitest-pool-workers) calls webidl.markAsUncloneable
123-
# which only exists in Node 22.10+. Pin a known-good runtime.
167+
# which only exists in Node 22.10+. Pin the Node 24 CI runtime.
124168
- uses: actions/setup-node@v4
125169
with:
126-
node-version: 22
170+
node-version: 24
171+
172+
- name: Cache Turbo task cache
173+
uses: useblacksmith/cache@v5
174+
with:
175+
path: .turbo
176+
key: ${{ runner.os }}-turbo-test-${{ hashFiles('bun.lock', 'turbo.json') }}
177+
restore-keys: |
178+
${{ runner.os }}-turbo-test-
179+
${{ runner.os }}-turbo-
127180
128181
- run: bun install --frozen-lockfile
129182

@@ -135,24 +188,18 @@ jobs:
135188
fail-fast: false
136189
matrix:
137190
include:
138-
# Cloud is SHARDED: each shard boots its own fresh dev stack. The
139-
# cloud dev server degrades after a few minutes of sustained suite
140-
# load on 2-core runners (the SSE/OTel memory growth being
141-
# instrumented on main) — requests start failing partway through and
142-
# everything after dies with connection errors. Short shards on
143-
# fresh boots stay under that threshold; re-merge into fewer jobs
144-
# once the degradation is fixed.
145-
- { target: cloud, shard: 1/8, shard-name: 1of8 }
146-
- { target: cloud, shard: 2/8, shard-name: 2of8 }
147-
- { target: cloud, shard: 3/8, shard-name: 3of8 }
148-
- { target: cloud, shard: 4/8, shard-name: 4of8 }
149-
- { target: cloud, shard: 5/8, shard-name: 5of8 }
150-
- { target: cloud, shard: 6/8, shard-name: 6of8 }
151-
- { target: cloud, shard: 7/8, shard-name: 7of8 }
152-
- { target: cloud, shard: 8/8, shard-name: 8of8 }
191+
# Each cloud shard boots its own fresh dev stack. On 4 vCPU runners,
192+
# four fatter shards keep the longest shard below selfhost while saving
193+
# four runner boots and four warm cache restores.
194+
- { target: cloud, shard: 1/4, shard-name: 1of4 }
195+
- { target: cloud, shard: 2/4, shard-name: 2of4 }
196+
- { target: cloud, shard: 3/4, shard-name: 3of4 }
197+
- { target: cloud, shard: 4/4, shard-name: 4of4 }
153198
- target: selfhost
154199
runs-on: blacksmith-4vcpu-ubuntu-2404
155200
timeout-minutes: 30
201+
env:
202+
E2E_MCP_FAST_IDLE_TEARDOWN: "true"
156203
steps:
157204
- uses: actions/checkout@v4
158205

@@ -161,26 +208,28 @@ jobs:
161208
bun-version: 1.3.11
162209

163210
- name: Cache Bun package cache
164-
uses: actions/cache@v4
211+
uses: useblacksmith/cache@v5
165212
with:
166213
path: ~/.bun/install/cache
167214
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
168215
restore-keys: |
169216
${{ runner.os }}-bun-1.3.11-
170217
171218
# The dev stacks spawn Node sidecars (vite/workerd tooling); pin the
172-
# same known-good runtime the unit-test job uses.
219+
# same Node 24 runtime the release and publish workflows use.
173220
- uses: actions/setup-node@v4
174221
with:
175-
node-version: 22
222+
node-version: 24
176223

177224
- run: bun install --frozen-lockfile
178225

179226
- name: Cache Playwright browsers
180-
uses: actions/cache@v4
227+
uses: useblacksmith/cache@v5
181228
with:
182229
path: ~/.cache/ms-playwright
183230
key: ${{ runner.os }}-playwright-1.60.0
231+
restore-keys: |
232+
${{ runner.os }}-playwright-
184233
185234
# Install from e2e so bunx resolves ITS pinned playwright (the version
186235
# the tests run against) rather than floating to the latest.
@@ -190,7 +239,7 @@ jobs:
190239

191240
# The globalsetup boots the target's own dev server (ports are claimed
192241
# per checkout, so this is hermetic) and tears it down after the run.
193-
# --retry=2: browser scenarios time out sporadically on 2-core runners
242+
# --retry=2: browser scenarios can still hit isolated waitFor timeouts
194243
# (single-test waitFor timeouts, not systemic failures); a retry on the
195244
# same booted stack clears them.
196245
- name: Run ${{ matrix.target }} scenarios
@@ -222,26 +271,28 @@ jobs:
222271
bun-version: 1.3.11
223272

224273
- name: Cache Bun package cache
225-
uses: actions/cache@v4
274+
uses: useblacksmith/cache@v5
226275
with:
227276
path: ~/.bun/install/cache
228277
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
229278
restore-keys: |
230279
${{ runner.os }}-bun-1.3.11-
231280
232281
# The local scenarios boot a real `executor web` (which spawns a Node
233-
# sidecar) and some drive a browser, so pin Node 22 and install Chromium.
282+
# sidecar) and some drive a browser, so pin Node 24 and install Chromium.
234283
- uses: actions/setup-node@v4
235284
with:
236-
node-version: 22
285+
node-version: 24
237286

238287
- run: bun install --frozen-lockfile
239288

240289
- name: Cache Playwright browsers
241-
uses: actions/cache@v4
290+
uses: useblacksmith/cache@v5
242291
with:
243292
path: ~/.cache/ms-playwright
244293
key: ${{ runner.os }}-playwright-1.60.0
294+
restore-keys: |
295+
${{ runner.os }}-playwright-
245296
246297
# `chromium` and the new `chromium-headless-shell` ship as separate
247298
# downloads; the browser-driven scenarios launch the headless shell.
@@ -265,7 +316,10 @@ jobs:
265316

266317
desktop-smoke:
267318
name: Desktop smoke build
319+
needs: changes
320+
if: needs.changes.outputs.desktop_smoke == 'true'
268321
runs-on: blacksmith-4vcpu-ubuntu-2404
322+
timeout-minutes: 20
269323
steps:
270324
- uses: actions/checkout@v4
271325

@@ -274,7 +328,7 @@ jobs:
274328
bun-version: 1.3.11
275329

276330
- name: Cache Bun package cache
277-
uses: actions/cache@v4
331+
uses: useblacksmith/cache@v5
278332
with:
279333
path: ~/.bun/install/cache
280334
key: ${{ runner.os }}-bun-1.3.11-${{ hashFiles('bun.lock') }}
@@ -283,10 +337,10 @@ jobs:
283337
284338
# No prebuilt better-sqlite3 binary matches this runner, so `bun install`
285339
# builds it from source via node-gyp, whose undici needs Node 22.10+
286-
# (webidl.markAsUncloneable). Pin the same runtime the test/e2e jobs use.
340+
# (webidl.markAsUncloneable). Pin the same Node 24 CI runtime.
287341
- uses: actions/setup-node@v4
288342
with:
289-
node-version: 22
343+
node-version: 24
290344

291345
- run: bun install --frozen-lockfile
292346

@@ -305,7 +359,10 @@ jobs:
305359

306360
selfhost-docker-smoke:
307361
name: Self-host Docker image
362+
needs: changes
363+
if: needs.changes.outputs.selfhost_docker_smoke == 'true'
308364
runs-on: blacksmith-4vcpu-ubuntu-2404
365+
timeout-minutes: 20
309366
steps:
310367
- uses: actions/checkout@v4
311368

0 commit comments

Comments
 (0)