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.
This commit is contained in:
parent
0c7f4dfbd9
commit
db3c9f084b
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
|
|
|
|||
Loading…
Reference in New Issue