Skip to content

Commit 1d8a527

Browse files
committed
improvement(ci): attribute independent acceptance jobs and reclaim closed PR caches
1 parent e4627fb commit 1d8a527

7 files changed

Lines changed: 79 additions & 15 deletions

File tree

‎.github/CI.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ Database integration uses 4-vCPU Blacksmith runners with sticky dependency disks
2828

2929
GitHub runners install dependencies directly rather than transferring Bun and `node_modules` archives. In a same-source paired comparison, those restores took 26.2 seconds before an 82-millisecond install, while a clean install took 12.42 seconds. This is one paired observation; retain the policy only while repeated CI timings support it. Blacksmith keeps its sticky dependency disks. GitHub Turbo output caches remain enabled for jobs that request them, with a commit-specific key and a task/event/fork-scoped restore prefix, so a rerun can reuse an exact entry without creating another archive. Push jobs never restore pull-request entries.
3030

31+
Closing a pull request deletes only its GitHub merge-ref caches. The cleanup runs the base branch's workflow without checking out PR code; it never selects a branch-wide or default-branch cache. Blacksmith sticky disks retain their separate lifecycle.
32+
3133
Memory-heavy builds and browser jobs retain appropriately sized Blacksmith runners. Electron uses 4-vCPU Blacksmith: both shards passed within 14 seconds of the 8-vCPU control; the free GitHub rest shard was slower and its lease run stalled.
3234

3335
Every HTTP and browser group consumes the same production build in an isolated job/database. Electron also uses that build and skips its development-route warm-up. Local HTTP and Electron development runs retain their dev-server behavior. Build inputs exclude test-only files so a harness edit can reuse an unchanged production build.
3436

35-
Desktop inbox protocol, assistant actions UI, and organization search UI run as three parallel HTTP jobs with isolated databases, apps, and reports. They retain one acceptance task boundary, so changing any of their harnesses selects all three jobs. Desktop inbox needs no browser. The UI jobs and browser extension install Chromium while their app starts, waiting for both before executing assertions; browser-install failures still fail the job and preserve the install log. No acceptance assertions are removed by the split.
37+
Desktop inbox protocol, assistant actions UI, and organization search UI run as three parallel HTTP jobs with isolated databases, apps, and reports. Each harness owns its acceptance task, so an edit selects its own job. The inbox protocol task depends on server and realtime code; the browser tasks also depend on workspace UI. Desktop inbox needs no browser. The UI jobs and browser extension install Chromium while their app starts, waiting for both before executing assertions; browser-install failures still fail the job and preserve the install log. No acceptance assertions are removed by the split.
38+
39+
Live Electron acceptance tracks its live-app suite, fixtures, and Playwright configuration separately from shell-only smoke tests. Changing a shell-only smoke case runs the dedicated desktop workflow without starting the app's production build and live lease checks.
3640

3741
Browser extension acceptance runs native interaction and access-revalidation groups in parallel jobs with isolated databases, apps, browser profiles, and reports. Both retain the same task boundary, so an affected extension harness selects both groups. Native streaming and first-open capture checks retain real timers. Access checks install Playwright's clock before the app mounts: advancing production polling timers preserves real HTTP and database authorization checks without waiting through each polling interval. Capture timestamps originate in Chromium's isolated world, so the harness restores wall time after each advance. The local `browser-extension` group still runs the complete suite; live-provider runs require this complete mode and retain native timing throughout.
3842

‎.github/ci-suites.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
},
1919
{
2020
"group": "assistant-actions",
21-
"task": "ci:e2e-desktop-inbox"
21+
"task": "ci:e2e-assistant-actions"
2222
},
2323
{
2424
"group": "organization-search",
25-
"task": "ci:e2e-desktop-inbox"
25+
"task": "ci:e2e-organization-search"
2626
},
2727
{
2828
"group": "browser-extension-native",

‎.github/scripts/ci-plan.gql‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ query($base: String!, $head: String!) {
33
affectedTasks(base: $base, head: $head, tasks: [
44
"test", "build", "type-check", "ci:integration", "ci:desktop-live",
55
"ci:e2e-scim", "ci:e2e-cli", "ci:e2e-stop-after", "ci:e2e-desktop-inbox",
6+
"ci:e2e-assistant-actions", "ci:e2e-organization-search",
67
"ci:e2e-browser-extension", "ci:e2e-project-files", "ci:e2e-mobile", "ci:e2e-seo"
78
]) {
89
items {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: cache cleanup
2+
3+
on:
4+
pull_request_target:
5+
types: [closed]
6+
7+
permissions:
8+
contents: read
9+
10+
concurrency:
11+
group: cache-cleanup-${{ github.event.pull_request.number }}
12+
cancel-in-progress: false
13+
14+
jobs:
15+
cleanup:
16+
runs-on: ubuntu-24.04
17+
timeout-minutes: 5
18+
permissions:
19+
actions: write
20+
pull-requests: read
21+
steps:
22+
- name: Remove caches scoped to the closed pull request
23+
env:
24+
GH_TOKEN: ${{ github.token }}
25+
GH_REPO: ${{ github.repository }}
26+
PR_NUMBER: ${{ github.event.pull_request.number }}
27+
run: |
28+
if [ "$(gh pr view "$PR_NUMBER" --json state --jq .state)" = OPEN ]; then
29+
exit 0
30+
fi
31+
gh cache delete --all --ref "refs/pull/${PR_NUMBER}/merge" --succeed-on-no-caches

‎apps/sim/package.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
"ci:e2e-cli": "bash ../../.github/scripts/http-e2e.sh cli",
5252
"ci:e2e-stop-after": "bash ../../.github/scripts/http-e2e.sh stop-after",
5353
"ci:e2e-desktop-inbox": "bash ../../.github/scripts/http-e2e.sh desktop-inbox",
54+
"ci:e2e-assistant-actions": "bash ../../.github/scripts/http-e2e.sh assistant-actions",
55+
"ci:e2e-organization-search": "bash ../../.github/scripts/http-e2e.sh organization-search",
5456
"ci:e2e-project-files": "bash ../../.github/scripts/http-e2e.sh project-files",
5557
"ci:e2e-mobile": "bash ../../.github/scripts/http-e2e.sh mobile",
5658
"ci:e2e-seo": "bash ../../.github/scripts/http-e2e.sh seo",

‎apps/sim/turbo.json‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,18 @@
119119
"cache": false
120120
},
121121
"ci:e2e-desktop-inbox": {
122+
"dependsOn": ["ci:server", "@sim/realtime#ci:runtime"],
123+
"inputs": ["scripts/test-desktop-inbox-e2e.ts"],
124+
"cache": false
125+
},
126+
"ci:e2e-assistant-actions": {
122127
"dependsOn": ["ci:server", "ci:ui", "@sim/realtime#ci:runtime"],
123-
"inputs": [
124-
"scripts/test-desktop-inbox-e2e.ts",
125-
"scripts/test-assistant-actions-e2e.ts",
126-
"scripts/test-organization-search-e2e.ts"
127-
],
128+
"inputs": ["scripts/test-assistant-actions-e2e.ts"],
129+
"cache": false
130+
},
131+
"ci:e2e-organization-search": {
132+
"dependsOn": ["ci:server", "ci:ui", "@sim/realtime#ci:runtime"],
133+
"inputs": ["scripts/test-organization-search-e2e.ts"],
128134
"cache": false
129135
},
130136
"ci:e2e-project-files": {
@@ -145,7 +151,8 @@
145151
"ci:desktop-live": {
146152
"dependsOn": ["ci:server", "ci:ui", "@sim/desktop#ci:runtime", "@sim/realtime#ci:runtime"],
147153
"inputs": [
148-
"$TURBO_ROOT$/apps/desktop/e2e/**",
154+
"$TURBO_ROOT$/apps/desktop/e2e/desktop-tools-live-sim.spec.ts",
155+
"$TURBO_ROOT$/apps/desktop/e2e/fixtures/**",
149156
"$TURBO_ROOT$/apps/desktop/playwright.config.ts"
150157
],
151158
"cache": false

‎scripts/ci-changes.test.ts‎

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ describe('CI task attribution through real Turborepo', () => {
149149
'assistant-actions',
150150
'browser-extension-access',
151151
'browser-extension-native',
152-
'desktop-inbox',
153152
'mobile',
154153
'organization-search',
155154
'seo',
@@ -222,13 +221,13 @@ describe('CI task attribution through real Turborepo', () => {
222221
expect(plan.flags.integration).toBe(true)
223222
})
224223
it.each([
225-
'test-desktop-inbox-e2e.ts',
226-
'test-assistant-actions-e2e.ts',
227-
'test-organization-search-e2e.ts',
228-
])('selects every isolated organization acceptance job for %s', (file) => {
224+
['test-desktop-inbox-e2e.ts', 'desktop-inbox'],
225+
['test-assistant-actions-e2e.ts', 'assistant-actions'],
226+
['test-organization-search-e2e.ts', 'organization-search'],
227+
])('selects the owning organization acceptance job for %s', (file, group) => {
229228
const plan = classifyFiles([`apps/sim/scripts/${file}`])
230229
expect(plan.fallback).toBeUndefined()
231-
expect(groups(plan)).toEqual(['assistant-actions', 'desktop-inbox', 'organization-search'])
230+
expect(groups(plan)).toEqual([group])
232231
expect(plan.flags).toMatchObject({
233232
http: true,
234233
production: false,
@@ -349,6 +348,26 @@ describe('CI task attribution through real Turborepo', () => {
349348
})
350349
expect(plan.testPackages).toEqual(['@sim/desktop'])
351350
})
351+
it('keeps shell-only smoke edits out of the live Sim execution gate', () => {
352+
const plan = classifyFiles(['apps/desktop/e2e/browser-tools.spec.ts'])
353+
expect(plan.fallback).toBeUndefined()
354+
expect(groups(plan)).toEqual([])
355+
expect(plan.flags).toMatchObject({
356+
desktop_live: false,
357+
e2e_build: false,
358+
integration: false,
359+
build: false,
360+
})
361+
})
362+
it.each([
363+
'apps/desktop/e2e/desktop-tools-live-sim.spec.ts',
364+
'apps/desktop/e2e/fixtures/live-sim.ts',
365+
'apps/desktop/playwright.config.ts',
366+
])('keeps live execution coverage when its harness changes: %s', (file) => {
367+
const plan = classifyFiles([file])
368+
expect(plan.fallback).toBeUndefined()
369+
expect(plan.flags).toMatchObject({ desktop_live: true, e2e_build: true })
370+
})
352371
it('runs everything if the real task query cannot parse configuration', () => {
353372
const { repo, base } = fixture()
354373
write(repo, 'turbo.json', '{invalid')

0 commit comments

Comments
 (0)