From db3c9f084bacad34f620ba678924564e20f441f9 Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:15:42 +0800 Subject: [PATCH] fix(ci): keep cancellation ownership in the calling workflow Remove redundant ref-based concurrency from reusable provider and website workflows. Their old groups could cancel qualification from another CI tier even though the callers used separate groups. Disposable hosted jobs now inherit caller scheduling; direct manual dispatches remain independent. Validate every called CI workflow has no independent cancellation group. Validation: 100 focused scope/gate tests and actionlint 1.7.7. --- .github/workflows/real-binary-layout.yml | 4 ---- .github/workflows/real-browser.yml | 4 ---- .github/workflows/real-evm-interface.yml | 4 ---- .../workflows/real-javascript-recovery.yml | 4 ---- .github/workflows/real-recorded-crash.yml | 4 ---- .../workflows/real-web-network-captures.yml | 4 ---- .github/workflows/real-web-runtime.yml | 3 --- .github/workflows/real-web-source-map.yml | 3 --- .github/workflows/website-check.yml | 4 ---- docs/testing.md | 5 +++- .../filesystem/ciRequiredLanes.test.ts | 23 +++++++++++++++++++ 11 files changed, 27 insertions(+), 35 deletions(-) diff --git a/.github/workflows/real-binary-layout.yml b/.github/workflows/real-binary-layout.yml index e8c244de6c..8dd6f98667 100644 --- a/.github/workflows/real-binary-layout.yml +++ b/.github/workflows/real-binary-layout.yml @@ -12,10 +12,6 @@ on: permissions: contents: read -concurrency: - group: real-binary-layout-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" diff --git a/.github/workflows/real-browser.yml b/.github/workflows/real-browser.yml index 76ba2e4a63..11a8b7a539 100644 --- a/.github/workflows/real-browser.yml +++ b/.github/workflows/real-browser.yml @@ -4,10 +4,6 @@ on: workflow_call: workflow_dispatch: -concurrency: - group: real-browser-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - env: HUSKY: "0" diff --git a/.github/workflows/real-evm-interface.yml b/.github/workflows/real-evm-interface.yml index 9e4cddeb4f..b335f13911 100644 --- a/.github/workflows/real-evm-interface.yml +++ b/.github/workflows/real-evm-interface.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: real-evm-interface-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" diff --git a/.github/workflows/real-javascript-recovery.yml b/.github/workflows/real-javascript-recovery.yml index 4fee667d85..d94127d639 100644 --- a/.github/workflows/real-javascript-recovery.yml +++ b/.github/workflows/real-javascript-recovery.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: javascript-recovery-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - env: HUSKY: "0" NODE_OPTIONS: "--max-old-space-size=768" diff --git a/.github/workflows/real-recorded-crash.yml b/.github/workflows/real-recorded-crash.yml index d4410bb241..dc56034c8f 100644 --- a/.github/workflows/real-recorded-crash.yml +++ b/.github/workflows/real-recorded-crash.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: real-recorded-crash-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: NODE_OPTIONS: --max-old-space-size=768 HUSKY: "0" diff --git a/.github/workflows/real-web-network-captures.yml b/.github/workflows/real-web-network-captures.yml index b888674f78..df340520d4 100644 --- a/.github/workflows/real-web-network-captures.yml +++ b/.github/workflows/real-web-network-captures.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: real-web-network-captures-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - env: HUSKY: "0" NODE_OPTIONS: --max-old-space-size=768 diff --git a/.github/workflows/real-web-runtime.yml b/.github/workflows/real-web-runtime.yml index c600e895cc..0ecdb92c65 100644 --- a/.github/workflows/real-web-runtime.yml +++ b/.github/workflows/real-web-runtime.yml @@ -4,9 +4,6 @@ on: workflow_dispatch: permissions: contents: read -concurrency: - group: real-web-runtime-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: HUSKY: "0" jobs: diff --git a/.github/workflows/real-web-source-map.yml b/.github/workflows/real-web-source-map.yml index 483b2f7125..b946621299 100644 --- a/.github/workflows/real-web-source-map.yml +++ b/.github/workflows/real-web-source-map.yml @@ -4,9 +4,6 @@ on: workflow_dispatch: permissions: contents: read -concurrency: - group: real-web-source-map-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: HUSKY: "0" jobs: diff --git a/.github/workflows/website-check.yml b/.github/workflows/website-check.yml index 8931ba418d..2a2c5406f5 100644 --- a/.github/workflows/website-check.yml +++ b/.github/workflows/website-check.yml @@ -7,10 +7,6 @@ on: permissions: contents: read -concurrency: - group: website-check-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: check: name: Website checks diff --git a/docs/testing.md b/docs/testing.md index b1d0031f6b..ca3210f474 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -776,7 +776,10 @@ should require this aggregate, `Static checks`, and `Portable tests`. Fast runs cancel superseded feedback for the same PR or main branch. Scheduled/manual qualification has a separate concurrency group: active work finishes and only the latest pending run is retained. Release qualification is grouped by its -exact source SHA and cannot be cancelled by newer main pushes. Publication +exact source SHA and cannot be cancelled by newer main pushes. Provider and +website lanes inherit their caller's scheduling; reusable +workflows have no independent cancellation group. Direct manual lane dispatches +run independently on disposable hosted runners. Publication requires that qualification to succeed and consumes its exact verified tarball, checking source SHA, workflow run, run attempt, package/Node version and SHA-256 before npm publication. Earlier attempts from the same workflow run are accepted diff --git a/tests/boundary/filesystem/ciRequiredLanes.test.ts b/tests/boundary/filesystem/ciRequiredLanes.test.ts index 6e30d8784b..0e9457e1ce 100644 --- a/tests/boundary/filesystem/ciRequiredLanes.test.ts +++ b/tests/boundary/filesystem/ciRequiredLanes.test.ts @@ -64,6 +64,29 @@ it("makes the required gate wait for every CI lane, including future additions", ); }); +it("leaves cancellation ownership with CI so child lanes cannot cancel another tier", async () => { + const { jobs } = await workflow(); + const children = Object.values(jobs).flatMap((job) => + typeof job.uses === "string" && job.uses.startsWith("./.github/workflows/") + ? [job.uses] + : [], + ); + expect(children.length).toBeGreaterThan(0); + for (const path of children) { + const child = z + .object({ concurrency: z.unknown().optional() }) + .parse( + parse( + await readFile(new URL(`../../../${path}`, import.meta.url), "utf8"), + ), + ); + expect( + child.concurrency, + `${path} must use caller scheduling`, + ).toBeUndefined(); + } +}); + it("keeps fast feedback separate from complete qualification and release proof", async () => { const ci = z .object({