How to Use a Static Concurrency Group for a Singleton Job in GitHub Actions
A constant group name (no context expressions) forces every run of a job into a single global lane.
For a job that touches a shared external resource (a migration runner, a terraform state), use a fixed group string. Every run repo-wide shares it, so at most one runs while the rest queue.
Steps
- Set
concurrency.groupto a literal string with no expressions. - Set
cancel-in-progress: falseso the running instance always finishes. - Scope it to the job if only that job must be a singleton.
Workflow
.github/workflows/migrate.yml
jobs:
migrate:
runs-on: ubuntu-latest
concurrency:
group: db-migrations
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
- run: ./run-migrations.shGotchas
- A static group is a repo-wide lock, so a hung run blocks every other invocation until it ends.
- Only one pending run is retained per group; extra queued runs are canceled while pending.
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 Limit a Single Job With Concurrency in GitHub ActionsApply concurrency to one job instead of the whole workflow in GitHub Actions, so only the deploy job serializ…