7

Based on the documentation (there's also a SO answer), I wrote this:

on:
  push
concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers.
  group: ci-${{ github.ref }}
  cancel-in-progress: true
jobs:
  ...

This creates a separate group for each branch, and cancels builds if there's a later push/force push to a branch. Sadly, this also cancels master builds, which I don't want. On master all commits should complete running, so it's easy to see when something broke.

I'm essentially looking for a way to say:

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true
  if: github.ref != 'refs/heads/master'
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
  • 1
    [_"A concurrency group can be any string or expression"_](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#concurrency) - so maybe on master the group is the commit hash, i.e. nothing gets grouped, whereas off master it's the branch? – jonrsharpe Jul 17 '21 at 08:42
  • ‍♂️, yes! Thank you! Maybe it's too early in the morning. – TWiStErRob Jul 17 '21 at 08:45
  • That's fun, @jonrsharpe, there's no ternary here... anyway I found workarounds to get an "if" in there, let me try them. – TWiStErRob Jul 17 '21 at 08:52

2 Answers2

15

You can specify cancel-in-progress based on the default branch:

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
thisismydesign
  • 21,553
  • 9
  • 123
  • 126
9

There's no ternary operator in GitHub Actions expression syntax, but I found some workarounds: http://rickluna.com/wp/tag/fake-ternary/ is an awesome post about this.

The commit hash of the head branch is available in the github context object as github.sha.

In my case truthyness in fake ternary is not an issue, it actually always has to have a value, so I can do:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.ref == 'refs/heads/master' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
  • For getting a real ternary vote here: https://github.com/actions/runner/issues/409 – TWiStErRob Jul 17 '21 at 15:56
  • A note about the `${{ x && || }}` construct: This only works if `` isn't the empty string. If ` == ''` then `''` is considered as `false`, which then evaluates the right hand side of the `||`. Just lost ten minutes over this, hope it helps! – Nicolas Mattia Jan 14 '22 at 17:40