From a00c34dcb155e5993bda8ad0f51bf3b13e289760 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sun, 11 Oct 2026 18:43:22 +0800 Subject: [PATCH] ci: reuse portable Turbo outputs across verification runs --- .../actions/portable-build-cache/action.yml | 40 +++++++++++++++++++ .github/workflows/ci.yml | 4 ++ .github/workflows/real-binary-layout.yml | 1 + .github/workflows/real-browser.yml | 3 +- .github/workflows/real-evm-interface.yml | 1 + .../workflows/real-javascript-recovery.yml | 3 +- .github/workflows/real-recorded-crash.yml | 1 + .../workflows/real-web-network-captures.yml | 1 + .github/workflows/real-web-runtime.yml | 3 +- .github/workflows/real-web-source-map.yml | 3 +- docs/testing.md | 7 ++++ 11 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 .github/actions/portable-build-cache/action.yml diff --git a/.github/actions/portable-build-cache/action.yml b/.github/actions/portable-build-cache/action.yml new file mode 100644 index 000000000..0fb8903c1 --- /dev/null +++ b/.github/actions/portable-build-cache/action.yml @@ -0,0 +1,40 @@ +name: Portable build cache +description: Reuse Turbo build outputs without serializing verification jobs. +inputs: + save: + description: Save newly built outputs after the job succeeds. + default: "false" +runs: + using: composite + steps: + - name: Resolve portable build task hashes + id: plan + shell: bash + env: + BUILD_CACHE_PREFIX: rea-portable-build-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc') }} + run: | + npm run --silent test:prepare -- --dry=json | + node --input-type=module -e ' + import { createHash } from "node:crypto"; + import { readFileSync } from "node:fs"; + const { tasks } = JSON.parse(readFileSync(0, "utf8")); + const hashes = tasks.map(({ taskId, hash }) => { + if (typeof hash !== "string") + throw new Error(`Build task ${taskId} must have an eager Turbo hash`); + return `${taskId}:${hash}`; + }).sort(); + const hash = createHash("sha256").update(hashes.join("\n")).digest("hex"); + console.log(`key=${process.env.BUILD_CACHE_PREFIX}-${hash}`); + ' >> "$GITHUB_OUTPUT" + - name: Restore portable build outputs + if: inputs.save != 'true' + uses: actions/cache/restore@v4 + with: + path: .turbo/cache/ + key: ${{ steps.plan.outputs.key }} + - name: Restore and save portable build outputs + if: inputs.save == 'true' + uses: actions/cache@v4 + with: + path: .turbo/cache/ + key: ${{ steps.plan.outputs.key }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccb36d5b2..bc2e7e28f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -145,6 +145,10 @@ jobs: node-version-file: .nvmrc cache: npm - run: npm ci + - name: Reuse portable build outputs across runs + uses: ./.github/actions/portable-build-cache + with: + save: "true" - run: npm run test:prepare - name: Find successful default-branch timing history id: history diff --git a/.github/workflows/real-binary-layout.yml b/.github/workflows/real-binary-layout.yml index 687f7a4b5..e8c244de6 100644 --- a/.github/workflows/real-binary-layout.yml +++ b/.github/workflows/real-binary-layout.yml @@ -32,6 +32,7 @@ jobs: node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Acquire exact upstream libraries in an isolated runner environment shell: bash run: | diff --git a/.github/workflows/real-browser.yml b/.github/workflows/real-browser.yml index 0f380c0d2..76ba2e4a6 100644 --- a/.github/workflows/real-browser.yml +++ b/.github/workflows/real-browser.yml @@ -22,9 +22,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - run: npm run verify:browser env: REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome diff --git a/.github/workflows/real-evm-interface.yml b/.github/workflows/real-evm-interface.yml index 6ea22c20c..9e4cddeb4 100644 --- a/.github/workflows/real-evm-interface.yml +++ b/.github/workflows/real-evm-interface.yml @@ -26,6 +26,7 @@ jobs: node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Acquire unchanged fixture compiler in isolated runner storage shell: bash run: | diff --git a/.github/workflows/real-javascript-recovery.yml b/.github/workflows/real-javascript-recovery.yml index 52488eb53..4fee667d8 100644 --- a/.github/workflows/real-javascript-recovery.yml +++ b/.github/workflows/real-javascript-recovery.yml @@ -24,9 +24,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Fetch pinned Wakaru release into the job workspace shell: bash run: | diff --git a/.github/workflows/real-recorded-crash.yml b/.github/workflows/real-recorded-crash.yml index ef6696c46..d4410bb24 100644 --- a/.github/workflows/real-recorded-crash.yml +++ b/.github/workflows/real-recorded-crash.yml @@ -29,6 +29,7 @@ jobs: node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Install GDB on the disposable CI runner shell: bash run: | diff --git a/.github/workflows/real-web-network-captures.yml b/.github/workflows/real-web-network-captures.yml index 004677d8f..b888674f7 100644 --- a/.github/workflows/real-web-network-captures.yml +++ b/.github/workflows/real-web-network-captures.yml @@ -28,6 +28,7 @@ jobs: - name: Use pinned package manager run: npm install --global npm@11.16.0 - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Acquire fixed upstream native profile in runner temporary storage shell: bash run: | diff --git a/.github/workflows/real-web-runtime.yml b/.github/workflows/real-web-runtime.yml index 8a307d524..c600e895c 100644 --- a/.github/workflows/real-web-runtime.yml +++ b/.github/workflows/real-web-runtime.yml @@ -17,9 +17,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - run: npm run verify:browser:runtime env: REA_BROWSER_EXECUTABLE: /usr/bin/google-chrome diff --git a/.github/workflows/real-web-source-map.yml b/.github/workflows/real-web-source-map.yml index dff978024..483b2f712 100644 --- a/.github/workflows/real-web-source-map.yml +++ b/.github/workflows/real-web-source-map.yml @@ -17,9 +17,10 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version-file: .nvmrc cache: npm - run: npm ci + - uses: ./.github/actions/portable-build-cache - name: Install the pinned compiler into an isolated fixture directory run: npm install --prefix "$RUNNER_TEMP/rea-web-source-map-compiler" --no-audit --no-fund --package-lock=false esbuild@0.25.10 - run: npm run verify:browser:source-maps diff --git a/docs/testing.md b/docs/testing.md index 0ffec9040..3fa490e4f 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1015,6 +1015,13 @@ summary. Static checks, documentation, build, package verification, and real-system lanes remain separate jobs so one kind of evidence cannot stand in for another. +The build job saves portable Turbo outputs across runs. Eight Linux real-system +lanes restore this cache without waiting for the build job. The shared action +derives its key from `test:prepare --dry=json` task hashes, runner OS and +architecture, and `.npmrc`; test-only changes can reuse compiled outputs. Every +build and verification command still runs, so Turbo checks task inputs and +rebuilds misses. There is no prefix fallback to accumulate older build outputs. + Native package jobs reuse the same workflow's Turbo cache for portable compiled JavaScript, skills, and catalogs. They retain the normal build and prepack commands, which restore matching outputs or rebuild on a cache miss. Native