How to Queue Release Jobs So They Never Overlap in GitHub Actions
One shared concurrency group across every release trigger queues publishes so two never run at once.
Releases often fire from both tag pushes and manual dispatch. Put them all in the same group with cancel-in-progress: false so a second release waits behind the first instead of racing it.
Steps
- Trigger the release from all relevant events.
- Use one static
concurrency.groupshared by every trigger. - Set
cancel-in-progress: falseso an in-progress publish finishes.
Workflow
.github/workflows/release.yml
on:
push:
tags: ['v*']
workflow_dispatch:
concurrency:
group: release-publish
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm publishGotchas
- Only one release can be pending; a third trigger cancels the earlier pending one, so avoid bursting releases.
- A registry that rejects duplicate versions still needs distinct version numbers per release.
Related guides
How to Serialize Production Deploys in GitHub ActionsSerialize production deploys in GitHub Actions with a single static concurrency group so two release runs can…
How to Queue Deploys Without Canceling in GitHub ActionsPrevent concurrent deploys to an environment in GitHub Actions by using a concurrency group with cancel-in-pr…