Matrix and concurrency¶
Matrix¶
Use a matrix when the decision requires multiple environments or versions. Do not add a matrix to look thorough; every leg costs runner minutes and adds a failure mode.
- A matrix produces the cartesian product.
includeis the part that confuses people: - An
includeentry augments original combinations where it does not overwrite original values. If it would overwrite one, it creates a new additional combination instead. - Original values are never overwritten. Later
includeentries can overwrite values added by earlier ones. excluderuns first and is a partial match: any subset of matching keys removes the combination.includecan add a combination back.- With no matrix keys, all
includeentries run. - Values can be arrays of objects, producing nested properties such as
matrix.node.version. - A dynamic matrix comes from
fromJSON(needs.<job>.outputs.<name>); the output must be a JSON array or object. fail-fastdefaults totrueand cancels other legs on the first failure. Set it tofalsewhen complete results are required, and usecontinue-on-errorper leg for experimental targets.- Limit: 256 jobs per workflow run.
- Reduce breadth by event: full matrix for releases and compatibility validation, a representative leg for ordinary changes.
Concurrency¶
- At most one run is in progress and one is pending per group. A new pending run replaces the
older pending run; it does not cancel the running one unless
cancel-in-progress: true. - Groups are repository-wide. Scope them with the workflow name, for example
${{ github.workflow }}-${{ github.ref }}, or a run can cancel runs from another workflow. - Group names are case-insensitive; ordering is FIFO by wait time and is not guaranteed.
cancel-in-progressaccepts an expression; protect release branches from cancellation.- Use a PR-specific group such as
${{ github.workflow }}-${{ github.head_ref || github.run_id }}so PR runs cancel each other without canceling branch runs. queue: maxallows up to 100 pending runs and cannot be combined withcancel-in-progress: true.- Deployments are not serialized by
environment:alone. Add aconcurrencygroup when a deployment must not overlap. - On cancellation, jobs with
always()still run. Expect a short grace period before the process is killed.