Aseem
Aseem

Reputation: 6787

if condition in concurrency in GHA

Is it possible to add IF condition in concurrency in github action?

I want to do following but only when branch name is not master

concurrency: 
  group: ${{ github.ref }}
  cancel-in-progress: true

Trigger on my yaml file is as follows:

name: Build
on:
  push:

This triggers on push on any branch (master or feature)

Upvotes: 6

Views: 1997

Answers (2)

nemanja
nemanja

Reputation: 704

After trying to achieve this for countless hours, the only thing that worked for me and for our organization was not to tweak cancel-in-progress, but rather to make sure every job on master has a unique group identifier.

As I've explained in this comment, even when you set cancel-in-progress to false that only means that there will be one job pending at all times. Push three commits in a row and the middle one will be cancelled with Canceling since a higher priority waiting request for 'refs/heads/master' exists. Hence, your master branch will look busted even though the test didn't even run. I hope GitHub implements a native support for this.

In meantime, this should work for anyone:

# we tend to reserve push only for a master branch to avoid duplicated runs in PRS
on:
  push:
    branches:
      - master
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
  cancel-in-progress: true

The second part of the group string is an expression known as a fake ternary.

If we imagine that we have two workflows named "Foo" and "Bar" and we push two commits in a row, this is what we'd get for group:

  1. on master:
  • comit A
    • Foo-4135785169
    • Bar-4135785170
  • commit B
    • Foo-4135785171
    • Bar-4135785172
  1. in a PR:
  • commit A:
    • Foo-refs/pull/14/merge
    • Bar-refs/pull/14/merge
  • commit B:
    • Foo-refs/pull/14/merge
    • Bar-refs/pull/14/merge

(obviously, IDs will be different for your scenario)


tl;dr

master

  • Since every single group identifier on master is always unique (due to the github.run_id), a cancel-in-progress: true doesn't really affect it.

PRs

  • Workflow name in combination with a branch ref (or you can even use a branch name) ensures that the same workflow gets cancelled only within that one branch.
  • Two developers can push at the same time in their own PRs and the same workflow will run for both of them.
  • One developer pushing multiple times in their own PR will always have only the latest commit running in CI. All previous ones will be cancelled.

Upvotes: 5

Jamie Birch
Jamie Birch

Reputation: 6112

You could keep the concurrency group name as-is and simply cancel in-progress tasks only if their branch name is something other than master:

concurrency: 
  group: ${{ github.ref }}
  cancel-in-progress: ${{ github.ref_name != 'master' }}

To learn more about:

Upvotes: -1

Related Questions