diff --git a/.github/workflows/real-binary-layout.yml b/.github/workflows/real-binary-layout.yml index e8c244de6..8dd6f9866 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 76ba2e4a6..11a8b7a53 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 9e4cddeb4..b335f1391 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 4fee667d8..d94127d63 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 d4410bb24..dc56034c8 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 b888674f7..df340520d 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 c600e895c..0ecdb92c6 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 483b2f712..b94662129 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 8931ba418..2a2c5406f 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 b1d0031f6..ca3210f47 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 6e30d8784..0e9457e1c 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({