GitHub Actions Tutorial — Include & Exclude

2 minute read

Include & Exclude

The full cartesian product of your matrix isn’t always what you want. include adds specific combinations, and exclude removes them.


Exclude — Remove Combinations

Remove specific combinations from the matrix:


strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node: [18, 20, 22]
    exclude:
      - os: windows-latest
        node: 18              # Don't test Node 18 on Windows
      - os: macos-latest
        node: 18              # Don't test Node 18 on macOS
runs-on: ${{ matrix.os }}

Result: 9 combinations − 2 excluded = 7 jobs.

You can exclude on any subset of matrix variables. If a combination matches all specified variables, it’s removed.


Include — Add Combinations

Add extra combinations or attach extra variables to specific matches:

Add New Combinations


strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [18, 20]
    include:
      - os: ubuntu-latest
        node: 22
        experimental: true    # extra variable for this combo only
runs-on: ${{ matrix.os }}
steps:
  - uses: actions/setup-node@v4
    with:
      node-version: ${{ matrix.node }}
  - run: echo "Experimental=${{ matrix.experimental }}"

Result: 4 standard jobs + 1 included = 5 jobs. Only the included combination has experimental=true; others have experimental=''.

Attach Variables to Existing Combinations


strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    include:
      - os: ubuntu-latest
        container: node:20-alpine    # attach to matching combo
      - os: windows-latest
        shell: pwsh                  # attach to matching combo
runs-on: ${{ matrix.os }}

When include matches an existing combination, it adds the extra variables without creating a new job.


Include-Only Matrix

You can define a matrix with only include — no base dimensions:


strategy:
  matrix:
    include:
      - os: ubuntu-latest
        node: 20
        deploy: true
      - os: ubuntu-latest
        node: 18
        deploy: false
      - os: macos-latest
        node: 20
        deploy: false
runs-on: ${{ matrix.os }}
steps:
  - uses: actions/setup-node@v4
    with:
      node-version: ${{ matrix.node }}
  - if: matrix.deploy
    run: echo "Deploying..."

This creates exactly 3 jobs — no cartesian product, just the listed combinations.


Combining Include and Exclude


strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    python: ['3.10', '3.11', '3.12']
    exclude:
      - os: macos-latest
        python: '3.10'
    include:
      - os: ubuntu-latest
        python: '3.13'
        experimental: true

Evaluation order:

  1. Generate cartesian product: 3 × 3 = 9
  2. Apply exclude: remove 1 → 8
  3. Apply include: add 1 → 9 jobs

Common Mistakes

Mistake Fix
exclude not removing a combo All specified variables must match exactly
include creates duplicate job If all base variables match an existing combo, it merges instead
Extra variable is empty string Variables from include default to '' for non-matching combos
Can’t exclude an included combo exclude runs before include — re-order your logic

Quick Reference

Feature Purpose Example
exclude Remove combinations exclude: [{os: windows, node: 18}]
include Add combinations include: [{os: ubuntu, node: 22}]
include + extra var Attach variable include: [{os: ubuntu, shell: bash}]
include-only No cartesian product Define each combo explicitly
Order exclude → include exclude first, then include

← Previous: Matrix Basics

Next: Fail-Fast & Parallel →

Updated: