Video Thumbnail for Lesson
4.6: Matrix Strategies, Conditionals, and Concurrency Controls

Matrix strategies, conditionals, and concurrency controls

Advanced scheduling features help you orchestrate complex automation without duplicating YAML.

  • Matrix jobs: fan out a single job definition across multiple inputs—useful for testing on different operating systems, language versions, or dependency sets.
  • Conditionals: (if: expressions) control whether a step or job should run for a particular matrix combination or based on data from previous steps.
  • Concurrency groups: instruct GitHub Actions to cancel superseded runs so you aren't burning time on outdated builds.
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  matrix-job:
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: true
      matrix:
        number: [1, 2]
        letter: [a, b, c]
        exclude:
          - number: 1
            letter: c
    timeout-minutes: 5

    steps:
      # Step 1 – always runs
      - name: Echo number and letter
        run: |
          echo "Number: ${{ matrix.number }}"
          echo "Letter: ${{ matrix.letter }}"

      # Step 2 – run for every combo EXCEPT number=2 ∧ letter=c
      - name: Run everywhere except 2c
        if: ${{ ! (matrix.number == 2 && matrix.letter == 'c') }}
        run: echo "✔ This step runs for ${{ matrix.number }}${{ matrix.letter }}"

  sleep-job:
    runs-on: ubuntu-24.04
    steps:
      - name: Sleep (to give time to be cancelled)
        run: sleep 100
        timeout-minutes: 2

If we trigger the workflow twice in quick succession and the first run will be automatically canceled when the second one starts because they share the same concurrency group.

Combine these techniques to create expressive pipelines that only do the work that's needed.