How GitHub expands a matrix
Every key except include and exclude is a list; GitHub combines them into a Cartesian product, with the first key varying slowest. exclude entries then remove every combination whose listed keys all match—partial entries remove many jobs at once. Finally each include entry is merged into every remaining original combination it would not overwrite; values that an earlier include added can be overwritten, original matrix values cannot. An entry that fits no original combination becomes a new job.
Reading the provenance trace
Each job lists the product values it started from, the includes that added or overwrote values, or the include that created it. Excluded combinations keep the number of the exclude entry that removed them, so it is clear when an include re-adds something that was excluded or when an exclude matches nothing because of a typo or a type mismatch such as 16 versus "16".
Variable preview and dynamic matrices
Expressions that use only matrix.* and literals are evaluated with GitHub’s rules—loose equality, value-returning &&/||, and functions such as contains, format and fromJSON—so job names, runs-on and step inputs show the values each job receives, and references to keys some jobs lack are flagged. For matrices built with ${{ fromJSON(needs.plan.outputs.matrix) }}, paste a sample JSON value to preview it.
Validation boundary
This is a preview, not GitHub Actions. Expressions that use github, needs, env, vars or other contexts are shown unevaluated, job display names follow GitHub’s default pattern approximately, and concurrency, runner availability and reusable-workflow matrices are not simulated. Confirm the generated job list in a test run.
Frequently asked questions
Does include run before or after exclude?
After. Exclude removes combinations from the product first; include then extends the remaining original combinations or adds new ones, so include can bring back a combination that exclude removed.
Why did my include create a new job instead of adding a value?
An include entry is merged only into original combinations it would not overwrite. If every combination has a different value for one of its matrix keys, GitHub creates a separate job from the entry.
How many jobs can a matrix create?
GitHub allows at most 256 jobs per matrix in a workflow run.
Is my workflow uploaded?
No. The YAML is parsed and expanded in your browser.
Authoritative references
GitHub’s documentation on running variations of jobs in a workflow and evaluating expressions defines the semantics modeled here.
Browse PKI & DevOps tools · Audit reusable-workflow permissions and secrets