How to cancel GitHub workflows when pushing new commits on a branch

 
 
  • Gérald Barré

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:

YAML
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:

YAML
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!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub