How to cancel GitHub workflows when pushing new commits on a branch
When you push multiple commits to a branch, you may want to cancel in-progress workflows and run only the latest workflow. This can be useful to reduce costs if you use paid runners. On free runners, GitHub limits the number of concurrent jobs. So, it can also release resources for other workflows.
To automatically cancel in-progress runs, you can use the concurrency
feature. This gives a name to a group of workflows. Then, you can configure the group to cancel in-progress runs when a new workflow is triggered.
Here's an example:
name: sample
on:
push:
branches:
- '*'
pull_request:
branches:
- '*'
# https://docs.github.com/en/actions/learn-github-actions/expressions
# https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
concurrency:
# github.workflow: name of the workflow
# github.event.pull_request.number || github.ref: pull request number or branch name if not a pull request
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
# Cancel in-progress runs when a new workflow with the same group name is triggered
cancel-in-progress: true
If you want to only cancel in-progress runs for branches other than main
, you can use the following configuration:
concurrency:
# Use github.run_id on main branch
# Use github.event.pull_request.number on pull requests, so it's unique per pull request
# Use github.ref on other branches, so it's unique per branch
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
cancel-in-progress: true
Instead of hard-coding main
, you may use github.ref_protected
to avoid canceling jobs on protected branches.
Do you have a question or a suggestion about this post? Contact me!