Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions .github/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,16 @@ Requirements in the consumer repo:
jobs' `if:` on it, so a hand-made `chore/release-*` branch merged by a
collaborator never reaches the app-token steps.
- A `concurrency` group on every release workflow, always with
`cancel-in-progress: false` (the templates carry them): one candidate at a
time, one settle per version, one publish per release branch, one
`on-release` run per tag. Each of them ends in a push, a tag or an upload
that must never be cancelled half-way, and none of them is atomic with its
own guard, so a second run queues rather than overlaps.
`cancel-in-progress: false` (the templates carry them): one proposal at a
time, one cut at a time, one settle per version, one publish per release
branch, one `on-release` run per tag. Each of them ends in a push, a tag or
an upload that must never be cancelled half-way, and none of them is
atomic with its own guard, so a second run queues rather than overlaps.
The groups on the `pull_request`-triggered jobs (`cut`, `publish`) are
job-level, not workflow-level: every PR closing on that branch starts the
workflow, and GitHub keeps one pending run per group, so a workflow-wide
group would let an unrelated closure evict a queued release run. A
skipped job holds no slot in a job-level group.
- Every workflow the release depends on must be on the tagged commit, not
just on the default branch: `release-publish.yml` runs from the settle
PR's merge into the release branch, and `on-release.yml` from the tag's
Expand Down
19 changes: 13 additions & 6 deletions workflow-templates/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ on:
types: [closed]
branches: [$default-branch]

# One candidate at a time: two dispatches would race on the candidate branch,
# and a cut runs on its own merge and must never be cancelled half-way.
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: read

jobs:
propose:
if: github.event_name == 'workflow_dispatch'
# One proposal at a time: two dispatches would race on the candidate
# branch. Job-level, not workflow-level: every PR closing on the default
# branch also starts this workflow, and a workflow-wide group would let
# that noise evict a queued release run (one pending run per group).
# A skipped job holds no slot in a job-level group.
concurrency:
group: ${{ github.workflow }}-propose
cancel-in-progress: false
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
Expand Down Expand Up @@ -60,6 +62,11 @@ jobs:
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'chore/release-candidate-') &&
github.event.pull_request.user.login == 'mega-maxwell[bot]'
# One cut at a time, never cancelled: pull_request.closed does not refire.
# Job-level for the reason given on `propose`.
concurrency:
group: ${{ github.workflow }}-cut
cancel-in-progress: false
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
Expand Down
13 changes: 7 additions & 6 deletions workflow-templates/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ on:
types: [closed]
branches: ["release-v*"]

# One publish per release branch: the tag guard and the tag push are two
# steps, so a re-run must queue behind a run in flight, never overlap it.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.base.ref }}
cancel-in-progress: false

permissions:
contents: read

Expand All @@ -29,6 +23,13 @@ jobs:
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'chore/release-settle-') &&
github.event.pull_request.user.login == 'mega-maxwell[bot]'
# One publish per release branch: the tag guard and the tag push are two
# steps, so a re-run must queue behind a run in flight, never overlap it.
# Job-level: other PRs closing on the release branch also start this
# workflow, and must not evict a queued publish (one pending per group).
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.base.ref }}
cancel-in-progress: false
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
Expand Down
Loading