Lesson 14 / 25

Concurrency Groups

Cancel superseded runs.

One run per group

A concurrency group allows only one active run per group key; with cancel-in-progress: true, a new run cancels the older one in the same group. Grouping by github.ref cancels outdated runs when someone pushes again to a branch, saving minutes and giving faster feedback. For deployments, use a group per environment without cancelling, so deploys queue instead of being interrupted halfway.

Runs cancelling older runs on the same ref, run

I ran this with Python 3. It is a simplified model of GitHub Actions behaviour for learning, not GitHub's implementation. Each push to feature-x cancels the previous run on that branch, while the run on main is in its own group and continues: runs 103 and 104 remain.

pushes = [("refs/heads/feature-x", "run 101"), ("refs/heads/feature-x", "run 102"),
          ("refs/heads/main", "run 103"), ("refs/heads/feature-x", "run 104")]
running = {}
for ref, run in pushes:                       # concurrency: group ci-<ref>, cancel-in-progress: true
    group = f"ci-{ref}"
    if group in running:
        print(f"{run}: cancels {running[group]} in group {group}")
    else:
        print(f"{run}: starts in group {group}")
    running[group] = run
print("still running:", sorted(running.values()))

Output:

run 101: starts in group ci-refs/heads/feature-x
run 102: cancels run 101 in group ci-refs/heads/feature-x
run 103: starts in group ci-refs/heads/main
run 104: cancels run 102 in group ci-refs/heads/feature-x
still running: ['run 103', 'run 104']

Do not cancel deployments

Use concurrency: { group: deploy-production, cancel-in-progress: false } so a deployment always finishes.

Quick check: What does cancel-in-progress: true do for a new run in the same group?

  • Deletes the group
  • Cancels the new run
  • Runs both in parallel
  • Cancels the older in-progress run
Answer

Cancels the older in-progress run — Newest run wins.