diff --git a/.github/actions/setup-turbo/action.yml b/.github/actions/setup-turbo/action.yml index 2caf55ea47..2e96679040 100644 --- a/.github/actions/setup-turbo/action.yml +++ b/.github/actions/setup-turbo/action.yml @@ -4,7 +4,15 @@ description: Bun + deps with cache, optional Turbo remote cache server inputs: bun-version: description: Bun version - default: '1.3.12' + # Floor 1.4.1. Earlier Bun ran N-API addon finalizers and cleanup hooks + # inside process.exit() and could hand a still-queued threadsafe-function + # call a null env; rolldown (Vite 8) is such an addon. The docs client + # build stalled on roughly one CI run in fifteen after its last build + # output and before `vite preview` started, and the evidence places that + # stall at the build's explicit exit; the docs Playwright webServer then + # timed out with zero tests run. The pin is hashed into every Turbo task + # (`globalDependencies`), so a bump reruns the cached tasks under it. + default: '1.4.2' start-turbo-cache: description: Start the Turborepo GH artifacts cache server default: 'true' diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index a43eff686d..49cf3fd6fa 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -62,15 +62,16 @@ jobs: - name: Setup Bun uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: - # Deliberately newer than the 1.3.12 the build jobs pin: before 1.4, - # `bun audit --prod` run from a workspace root reported workspace + # The test toolchain's pin (`.github/actions/setup-turbo`); the audit + # itself needs 1.4 or newer: before 1.4, `bun audit --prod` run from + # a workspace root reported workspace # members' devDependencies as production (oven-sh/bun#26675, fixed # in 1.4 by oven-sh/bun#38333). That made the gate below fail on # @faker-js/faker 5.5.3, reachable only through the dev-only # @stoplight/prism-http mock server (postman-collection pins it and # no upstream release lifts the pin). 1.4.0 keeps reporting real # production findings (verified against the fast-uri/mysql2 lock). - bun-version: '1.4.0' + bun-version: '1.4.2' - name: Run bun audit (report) # Full advisory list for visibility; does not fail the build itself. diff --git a/services/docs/playwright.config.ts b/services/docs/playwright.config.ts index 845d8fde6c..338322a0aa 100644 --- a/services/docs/playwright.config.ts +++ b/services/docs/playwright.config.ts @@ -23,7 +23,8 @@ export default createPlaywrightConfig({ // `scripts/build-client.ts` (vite's JS API + an explicit exit), not the // `vite build` CLI: the CLI process occasionally never exits after a // successful build, and the `&&` chain then starves silently until this - // webServer timeout with zero tests run. + // webServer timeout with zero tests run. The explicit exit is only safe + // on Bun ≥ 1.4.1 — see build-client.ts for why. command: `bun --bun scripts/build-search-index.ts && ` + `bun --bun scripts/build-client.ts && ` + diff --git a/services/docs/scripts/build-client.ts b/services/docs/scripts/build-client.ts index 4c25675153..4665ff7f6f 100644 --- a/services/docs/scripts/build-client.ts +++ b/services/docs/scripts/build-client.ts @@ -1,12 +1,15 @@ // The Playwright webServer chains client build → preview with `&&`, so the // chain advances only when the build PROCESS exits. `bun --bun vite build` -// occasionally never exits after a successful build — a dangling handle in -// the rolldown/PWA-plugin pipeline keeps the event loop alive — and the -// silent hang starves the chain until the webServer timeout with zero tests -// run. Building through the JS API and exiting explicitly makes process -// exit a certainty instead of an event-loop accident: `build()` resolves -// only after every plugin's `closeBundle`, so the PWA artifacts are already -// on disk when the exit fires. +// occasionally never exits after a successful build, and the silent hang +// starves the chain until the webServer timeout with zero tests run. +// Building through the JS API and exiting explicitly removes the implicit +// exit from the chain: `build()` resolves only after every plugin's +// `closeBundle`, so the PWA artifacts are already on disk when the exit +// fires. The exit itself needs Bun ≥ 1.4.1 — earlier Bun ran rolldown's +// N-API finalizers and cleanup hooks inside `process.exit()`, and the +// evidence places CI's remaining stalls there (pinned in +// `.github/actions/setup-turbo/action.yml`). The line logged after `build()` +// resolves puts any future stall on one side of the exit or the other. import { build } from 'vite'; @@ -16,4 +19,5 @@ try { console.error(error); process.exit(1); } +console.info('[build-client] build resolved, exiting 0'); process.exit(0); diff --git a/turbo.json b/turbo.json index 5527fbebe2..6ab8beea9c 100644 --- a/turbo.json +++ b/turbo.json @@ -109,6 +109,7 @@ } }, "globalDependencies": [ + ".github/actions/setup-turbo/action.yml", ".oxlintrc.json", ".oxfmtrc.json", "tsconfig.base.json"