# Matrix Builds — GitHub Actions

Source: https://www.skillbyai.com/en/github-actions/m-matrix

> Test across versions and platforms.

## Combinations, include, exclude

A `strategy.matrix` defines variables; GitHub creates one job per combination (the Cartesian product). `exclude` removes specific combinations and `include` adds extra ones or extra variables to existing ones. `fail-fast` (default true) cancels the other matrix jobs when one fails; set it to false when you want results for every combination. `max-parallel` limits concurrency. Large matrices multiply cost, so test the combinations that matter.

## One definition, many runs

Matrices fan out jobs; expressions read contexts; conditions decide what runs.

![Three ideas: matrices, expressions and contexts, conditions.](assets/figures/github-actions/section-4-map.svg) — Figure 4.1 — Matrices, expressions and conditions.

## Expanding a matrix with exclude and include, run

I ran this with Python 3. It is a simplified model of GitHub Actions behaviour for learning, not GitHub's implementation. Two operating systems times two Node versions give four combinations; excluding Windows with Node 20 leaves three, and include adds an experimental Ubuntu Node 24 job: four jobs in total.

```python
from itertools import product
matrix = {"os": ["ubuntu-latest", "windows-latest"], "node": [20, 22]}
exclude = [{"os": "windows-latest", "node": 20}]
include = [{"os": "ubuntu-latest", "node": 24, "experimental": True}]
jobs = [dict(zip(matrix, combo)) for combo in product(*matrix.values())]
jobs = [j for j in jobs if not any(all(j.get(k) == v for k, v in e.items()) for e in exclude)]
jobs += include
for j in jobs:
    print(j)
print(len(jobs), "jobs")
```

Output:

```
{'os': 'ubuntu-latest', 'node': 20}
{'os': 'ubuntu-latest', 'node': 22}
{'os': 'windows-latest', 'node': 22}
{'os': 'ubuntu-latest', 'node': 24, 'experimental': True}
4 jobs
```

## Mark experimental jobs

Combine include with continue-on-error: ${{ matrix.experimental == true }} so preview versions do not block merges.

**Quiz:** What does fail-fast: false change?

- [x] Other matrix jobs keep running when one fails
- [ ] The matrix runs sequentially
- [ ] Failures are ignored
- [ ] Only the first combination runs

*Answer:* Other matrix jobs keep running when one fails. See every result.
