From b3ad22765003d9617a50b8db99987484cac4da9c Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:03:19 -0700 Subject: [PATCH] ci: use Bun 1.4.3 across all workflows (#28384) * ci: share Bun 1.4.3 across current toolchain workflows * ci: use shared Bun pin for server migration tests too --- .github/workflows/node-server-tests.yml | 4 ++-- .github/workflows/pr.yml | 2 +- .github/workflows/preflight-benchmark.yml | 8 ++++---- .../preflight-critical-path-benchmark.yml | 2 +- config/.bun-version | 2 +- .../scripts/node-server-change-scope.test.mjs | 3 +-- config/scripts/node-server-test-paths.mjs | 2 +- config/scripts/pr-preflight-gates.test.mjs | 20 +++++++++++++++++-- config/scripts/run-node-server-tests.mjs | 2 +- src/main/orcad/orcad-node-slot-fixture.ts | 12 ++++++----- ...le-state-cross-runtime.integration.test.ts | 6 +++--- 11 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.github/workflows/node-server-tests.yml b/.github/workflows/node-server-tests.yml index 917d4dcd263..92f03a8ecee 100644 --- a/.github/workflows/node-server-tests.yml +++ b/.github/workflows/node-server-tests.yml @@ -165,12 +165,12 @@ jobs: cache-pnpm-store: ${{ runner.os != 'Windows' }} cache-pnpm-store-lookup-only: 'true' # Design D7 upgrade and rollback: the last Bun orcad, built from a main commit that shipped - # it, beside this checkout's Node slot; the live-terminal hand-over skips once PROTOCOL_VERSION + # it, using the current Bun pin beside this checkout's Node slot; hand-over skips once PROTOCOL_VERSION # moves past the Bun daemon's. Install its pinned dependencies independently of this checkout. - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 if: runner.os == 'Linux' with: - bun-version: 1.4.2 + bun-version-file: config/.bun-version - name: Build the last Bun orcad for the cross-runtime tests id: bun-orcad background: true diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ffcd77278fd..905fa583fe3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -206,7 +206,7 @@ jobs: - name: Set up Bun for preflight checks uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Check process-host imports if: '!cancelled()' diff --git a/.github/workflows/preflight-benchmark.yml b/.github/workflows/preflight-benchmark.yml index 20432b878c6..44b3617b3eb 100644 --- a/.github/workflows/preflight-benchmark.yml +++ b/.github/workflows/preflight-benchmark.yml @@ -27,7 +27,7 @@ jobs: node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Compare native and Bun typechecking run: node config/scripts/benchmark-preflight-compilers.mjs - uses: actions/upload-artifact@v7 @@ -49,7 +49,7 @@ jobs: node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Compare anti-slop patch and script runtimes run: node config/scripts/benchmark-preflight-static-analysis.mjs - uses: actions/upload-artifact@v7 @@ -72,7 +72,7 @@ jobs: node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Compare compatibility-import scan and runtimes run: node config/scripts/benchmark-preflight-compat-boundary.mjs - uses: actions/upload-artifact@v7 @@ -94,7 +94,7 @@ jobs: node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Compare localization extraction runtimes and complete catalogs run: node config/scripts/benchmark-preflight-localization-extraction.mjs - uses: actions/upload-artifact@v7 diff --git a/.github/workflows/preflight-critical-path-benchmark.yml b/.github/workflows/preflight-critical-path-benchmark.yml index 971cf05c8f7..cfabf00e3cc 100644 --- a/.github/workflows/preflight-critical-path-benchmark.yml +++ b/.github/workflows/preflight-critical-path-benchmark.yml @@ -31,7 +31,7 @@ jobs: node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: - bun-version: 1.4.3 + bun-version-file: config/.bun-version - name: Compare checks and verify their results run: node config/scripts/benchmark-ci-preflight-critical-path.mjs ${{ matrix.comparison }} - uses: actions/upload-artifact@v7 diff --git a/config/.bun-version b/config/.bun-version index 9df886c42a1..428b770e3e2 100644 --- a/config/.bun-version +++ b/config/.bun-version @@ -1 +1 @@ -1.4.2 +1.4.3 diff --git a/config/scripts/node-server-change-scope.test.mjs b/config/scripts/node-server-change-scope.test.mjs index e9517a13973..be9703cf080 100644 --- a/config/scripts/node-server-change-scope.test.mjs +++ b/config/scripts/node-server-change-scope.test.mjs @@ -595,8 +595,7 @@ it('runs the Bun and Node cross-runtime tests on Linux against pinned inputs', ( const steps = workflow.jobs.persistence.steps const setupBun = steps.find((step) => String(step.uses).startsWith('oven-sh/setup-bun@')) expect(setupBun.uses).toMatch(/^oven-sh\/setup-bun@[0-9a-f]{40}$/) - // Mirrors LAST_BUN_ORCAD_VERSION in src/main/orcad/orcad-node-slot-fixture.ts. - expect(setupBun.with['bun-version']).toBe('1.4.2') + expect(setupBun.with['bun-version-file']).toBe('config/.bun-version') const build = steps.find((step) => String(step.run).includes('build-orcad-bun.mjs')) expect(build.env.BUN_ORCAD_COMMIT).toMatch(/^[0-9a-f]{40}$/) expect(setupBun.if).toBe("runner.os == 'Linux'") diff --git a/config/scripts/node-server-test-paths.mjs b/config/scripts/node-server-test-paths.mjs index c9fb5c9a503..0f54418bc8b 100644 --- a/config/scripts/node-server-test-paths.mjs +++ b/config/scripts/node-server-test-paths.mjs @@ -1,7 +1,7 @@ /** Mirrors ORCA_REQUIRED_TEST_INPUTS_ENV in src/main/orcad/orcad-node-slot-fixture.ts. */ export const REQUIRED_TEST_INPUTS_ENV = 'ORCA_REQUIRED_TEST_INPUTS' -// Need Bun 1.4.2 and the last Bun orcad slot beside the built Node slot (design D7). +// Need the pinned Bun and the last Bun orcad slot beside the built Node slot (design D7). export const CROSS_RUNTIME_TEST_PATHS = [ 'src/main/orcad/orcad-cross-runtime-daemon-adoption.integration.test.ts', 'src/main/persistence/profile-state/profile-state-cross-runtime.integration.test.ts' diff --git a/config/scripts/pr-preflight-gates.test.mjs b/config/scripts/pr-preflight-gates.test.mjs index 367ed18294f..023971708ae 100644 --- a/config/scripts/pr-preflight-gates.test.mjs +++ b/config/scripts/pr-preflight-gates.test.mjs @@ -1,4 +1,4 @@ -import { readFileSync } from 'node:fs' +import { readFileSync, readdirSync } from 'node:fs' import { runInNewContext } from 'node:vm' import { expect, it } from 'vitest' import { parse } from 'yaml' @@ -29,7 +29,7 @@ it('shares one setup and overlaps the compiler only after type-aware checks fini expect(compiler.background).toBe(true) expect(compiler.run).toContain('pnpm run typecheck:ci') const bunSetup = steps.find((step) => step.name === 'Set up Bun for preflight checks') - expect(bunSetup.with['bun-version']).toBe('1.4.3') + expect(bunSetup.with['bun-version-file']).toBe('config/.bun-version') expect(bunSetup.if).toBeUndefined() expect(plan.background).toBe(true) expect(plan.run.trim().split('\n')).toEqual([ @@ -50,6 +50,22 @@ it('shares one setup and overlaps the compiler only after type-aware checks fini ) }) +it('uses the shared Bun pin for every current-toolchain workflow', () => { + expect(readFileSync('config/.bun-version', 'utf8').trim()).toBe('1.4.3') + for (const file of readdirSync('.github/workflows').filter((name) => /\.ya?ml$/.test(name))) { + const current = parse(readFileSync(`.github/workflows/${file}`, 'utf8')) + for (const job of Object.values(current.jobs)) { + for (const step of job.steps ?? []) { + if (!String(step.uses).startsWith('oven-sh/setup-bun@')) { + continue + } + expect(step.with['bun-version-file'], file).toBe('config/.bun-version') + expect(step.with['bun-version'], file).toBeUndefined() + } + } + } +}) + it('keeps the Bun anti-slop scan aligned with the local audit', () => { const audit = steps.find((step) => step.name === 'Reject low-evidence patterns') const manifest = JSON.parse(readFileSync('package.json', 'utf8')) diff --git a/config/scripts/run-node-server-tests.mjs b/config/scripts/run-node-server-tests.mjs index e51c0c273a9..4ed52684ad2 100644 --- a/config/scripts/run-node-server-tests.mjs +++ b/config/scripts/run-node-server-tests.mjs @@ -26,7 +26,7 @@ import { const root = resolve(import.meta.dirname, '../..') const target = currentTarget() const artifact = process.argv.includes('--artifact') -// Lanes that provide Bun 1.4.2 and the last Bun orcad slot (design D7 upgrade and rollback). +// Lanes that provide the pinned Bun and the last Bun orcad slot (design D7 upgrade and rollback). const crossRuntime = process.argv.includes('--cross-runtime') const testArgs = process.argv .slice(2) diff --git a/src/main/orcad/orcad-node-slot-fixture.ts b/src/main/orcad/orcad-node-slot-fixture.ts index f1e3891ef3d..ef211377b7d 100644 --- a/src/main/orcad/orcad-node-slot-fixture.ts +++ b/src/main/orcad/orcad-node-slot-fixture.ts @@ -1,5 +1,5 @@ // Test fixture: a packaged Node slot whose runtime is the real pinned Node, laid out as shipped. -import { copyFileSync, existsSync, linkSync, mkdirSync, readdirSync } from 'node:fs' +import { copyFileSync, existsSync, linkSync, mkdirSync, readFileSync, readdirSync } from 'node:fs' import { copyFile, link, mkdir, writeFile } from 'node:fs/promises' import { createRequire } from 'node:module' import type * as NodePty from 'node-pty' @@ -41,15 +41,17 @@ export function locatePinnedNodeForTests(): string | null { ) } -/** The Bun the last Bun orcad shipped on; only the design D7 cross-runtime gates still run it. */ -export const LAST_BUN_ORCAD_VERSION = '1.4.2' +const crossRuntimeBunVersion = readFileSync( + new URL('../../../config/.bun-version', import.meta.url), + 'utf8' +).trim() -/** Bun 1.4.2 (BUN_EXECUTABLE, else `bun` on PATH), the last runtime orcad shipped on, if any. */ +/** The shared Bun pin (BUN_EXECUTABLE, else `bun` on PATH), if available. */ export function locateBunForTests(): string | null { const candidate = process.env.BUN_EXECUTABLE ?? 'bun' try { const result = runProcessSync({ program: candidate, args: ['--version'], timeoutMs: 10_000 }) - return result.code === 0 && result.stdout.trim() === LAST_BUN_ORCAD_VERSION ? candidate : null + return result.code === 0 && result.stdout.trim() === crossRuntimeBunVersion ? candidate : null } catch { return null } diff --git a/src/main/persistence/profile-state/profile-state-cross-runtime.integration.test.ts b/src/main/persistence/profile-state/profile-state-cross-runtime.integration.test.ts index c6e8326dfa2..50b09f12504 100644 --- a/src/main/persistence/profile-state/profile-state-cross-runtime.integration.test.ts +++ b/src/main/persistence/profile-state/profile-state-cross-runtime.integration.test.ts @@ -1,5 +1,5 @@ /** - * Design D4 Phase 1 gate: a profile database Bun 1.4.2 wrote, WAL included after an unclean + * Design D4 Phase 1 gate: a profile database the pinned Bun wrote, WAL included after an unclean * exit, opens and backs up under the pinned Node, and the reverse — the rollback direction. * Today's source reaches Bun's own SQLite through its node:sqlite; the Bun adapter is gone. */ @@ -96,11 +96,11 @@ async function run( } const skip = skipForMissingInputs('cross-runtime', [ - ...(bun ? [] : ['Bun 1.4.2 (BUN_EXECUTABLE or bun on PATH)']), + ...(bun ? [] : ['the pinned Bun (BUN_EXECUTABLE or bun on PATH)']), ...(node ? [] : ['the pinned Node (ORCA_PINNED_NODE or out/runtimes)']) ]) -describe.skipIf(skip)('profile database across Bun 1.4.2 and the pinned Node', () => { +describe.skipIf(skip)('profile database across the pinned Bun and the pinned Node', () => { it.each([ ['Bun', 'Node'], ['Node', 'Bun']