{{ summaryTitle }}
{{ summaryPrimary }}
{{ summarySecondary }}
{{ badge.label }}
OS Version Jobs Rules
GitHub Actions matrix generator inputs
Use the name your team expects to see in pull request checks.
Choose the toolchain that owns the matrix version axis.
Examples: 20, 22, 24 for Node.js or 3.11, 3.12, 3.13 for Python.
Comma-separated or one-per-line runner labels.
Keep install work deterministic, for example npm ci or python -m pip install -r requirements.txt.
Use the command that should decide whether each matrix job passes.
Setup-action cache is the default for package-manager workflows with lockfiles.
Enter a .yml or .yaml file name.
Examples: test, build, ci_matrix.
Comma-separated or one-per-line branch names.
Human-readable runtime label for job names.
Examples: actions/setup-node@v6, actions/setup-python@v6, actions/setup-go@v6.
Examples: node-version, python-version, go-version, java-version.
Use for inputs such as distribution=temurin or check-latest=true.
Examples: npm, pnpm, pip, poetry, gradle, maven, true.
Examples: package-lock.json or frontend/package-lock.json.
Accepts one path or a block of paths.
Example: frontend or packages/api.
Leave blank unless every matrix job should vary by another dimension.
Example: npm, pnpm, yarn.
Example: os=ubuntu-latest,node-version=25,experimental=true.
Example: os=windows-latest,node-version=20.
Use a positive number to cap concurrent matrix jobs.
jobs
Set a realistic ceiling for one matrix job.
min
Leave off when you want the full compatibility picture from every axis.
{{ fail_fast ? 'On' : 'Off' }}
Often paired with the default branch for CI coverage after merge.
{{ trigger_push ? 'On' : 'Off' }}
Turn on for branch protection and compatibility checks before merge.
{{ trigger_pull_request ? 'On' : 'Off' }}
Useful before adding a workflow to required checks.
{{ trigger_workflow_dispatch ? 'On' : 'Off' }}
Recommended for ordinary test workflows.
{{ permissions_contents_read ? 'On' : 'Off' }}
{{ workflowYaml }}
Runner OS {{ versionAxisLabel }} Extra axis Source Experimental Copy
{{ row.os }} {{ row.version }} {{ row.extraAxis }} {{ row.source }} {{ row.experimental ? 'yes' : 'no' }}
Check Status Detail Copy
{{ row.check }} {{ row.status }} {{ row.detail }}
Customize
Advanced
:

Introduction:

A continuous integration matrix is a compact way to ask the same build or test question across several supported environments. Instead of copying one job for Node.js 20, another for Node.js 22, and another for macOS, the workflow defines axes such as runtime version and runner operating system. GitHub Actions expands those axes into job runs, then exposes the chosen values through the matrix context for setup steps, cache keys, and commands.

The hard part is deciding what deserves to be in the grid. A larger matrix catches more compatibility drift, but it also consumes runner minutes, slows pull request feedback, and creates more failure messages for reviewers to triage. Good matrix design starts from a real support promise: a library may need every maintained runtime, a CLI may need each operating system it ships to, and an application may only need the production runtime plus one next-version smoke job.

Matrix axis
A named list of values, such as runner labels, runtime versions, package managers, databases, architectures, or shards.
Matrix combination
One job created from a specific value on every active axis.
Exception row
An include or exclude entry used when the regular grid has an unsupported pair, an experimental case, or another special rule.

Most workflows begin with two axes: runner label and runtime version. A third axis is useful only when it changes the evidence, for example package manager, database version, architecture, or shard number. It is easy to add a dimension that looks thorough but only multiplies duplicate failures. Moving runner labels such as ubuntu-latest also need attention because they follow GitHub-hosted runner image updates, which can change tools and system packages over time.

Matrix axes combine runner labels and runtime versions into GitHub Actions job combinations.

Exception rows should stay rare and easy to explain in code review. Exclude rows remove combinations that are unsupported, redundant, or intentionally out of scope. Include rows fit deliberate additions such as a prerelease runtime, an experimental package manager, or a one-off compatibility job that should not be confused with the stable grid.

A passing matrix still proves only the combinations it ran. The workflow depends on valid setup actions, available runner labels, real dependency files, appropriate cache paths, and commands that behave the same way in continuous integration as they do in a local checkout.

How to Use This Tool:

Build the ordinary CI workflow first, then add advanced settings only when the repository needs a named exception, a third axis, or a different trigger policy.

  1. Choose Runtime preset and check the filled Runtime label, Setup action, Version input name, Install command, and Test command. Switch to a custom setup only when the preset does not match the repository language or action version.
  2. Enter Runtime versions and Runner OS labels with one value per line or comma-separated values. Watch the summary job count before copying the workflow, especially after adding a third axis.
  3. Set Workflow name. Open Advanced when the repository needs a different Workflow file, Job id, Push branches, Working directory, or read-only contents permission block.
  4. Choose Dependency cache. Resolve warnings about Cache package/input, Dependency path, or Manual cache path before treating cache behavior as ready for branch protection.
  5. Use the extra axis fields only for a real compatibility dimension such as package manager, database, architecture, or shard. Values without an axis name block output until you either name the axis or clear the values.
  6. Add include and exclude rows as key=value lines for exceptions. Complete include rows are easier to audit because the Matrix Ledger records entered include rows as explicit additions.
  7. Set Fail-fast, Max parallel, Timeout, and the trigger switches. If push, pull request, and manual triggers are all off, Workflow YAML remains empty until one trigger is enabled.

Interpreting Results:

GitHub Actions matrix ready means the entered settings produced workflow text and review artifacts. Start with the headline job count because it shows how much CI work each workflow run can create before GitHub executes anything.

Workflow YAML is the content to copy or download. Matrix Ledger shows the local planning rows, including base rows and entered include rows. Workflow Checks is the safety readout: Blocked rows prevent YAML output, while Review rows flag choices that may be valid but still need a repository-specific decision.

  • An OK setup or cache check does not prove that the repository contains the named lockfile, package manager, runner label, or runtime version. Commit the workflow and run it manually before making the check required.
  • Matrix combinations should stay at or below 256 jobs. A larger count needs fewer axis values, narrower exceptions, or a split workflow.
  • Fail-fast policy marked Review means one required failure can cancel queued or in-progress matrix jobs, which may hide other compatibility failures.
  • Dependency cache marked Review means no cache is emitted or a manual cache path is missing. That affects speed and reproducibility checks, not the basic ability to write a workflow.

Technical Details:

A matrix strategy expands one job definition into job runs before any step executes. Each axis becomes a property in the matrix context, so a runtime version can feed a setup action, a runner label can drive runs-on, and the same value can appear in job names or cache keys.

GitHub documents a maximum of 256 matrix jobs per workflow run, for both GitHub-hosted and self-hosted runners. Parallelism is otherwise limited by runner availability unless max-parallel is set. Job timeouts use whole minutes, and this generator clamps entered timeout values to 1 through 360 minutes to match the common workflow syntax boundary.

Formula Core:

For the generated ledger, the local planning count is the base Cartesian product minus matching excludes plus entered include rows.

jobs = ( O × V × A ) E + I

O is the number of runner OS labels, V is the runtime version count, and A is the extra-axis count or 1 when no extra axis is used. E is the number of base combinations removed by exclude rows, and I is the number of include rows counted as added ledger rows. With 3 runner labels, 4 runtime versions, and no extra axis, the base grid is 12 jobs. Two matching excludes and one entered include row produce 11 local planning rows.

Rule Core:

GitHub Actions matrix workflow rules and planning boundaries
Part Rule Review point
strategy.matrix Runner labels, runtime versions, and an optional extra axis become YAML lists. Every added axis multiplies the base job count.
exclude A row removes base combinations whose keys all match the row values. Partial rows can remove more combinations than expected when they omit a version or runner label.
include Entered rows are emitted under strategy.matrix.include and counted locally as added ledger rows. Use complete exception rows because GitHub can merge incomplete include entries into existing combinations when they do not overwrite matrix values.
fail-fast The strategy writes either true or false. false keeps the full matrix running after a required job fails.
max-parallel 0 omits the setting. A value from 1 to 256 caps concurrent matrix jobs. A cap can protect limited runners, external services, and rate-limited test dependencies.
timeout-minutes The job timeout is clamped to a whole number from 1 to 360 minutes. A very low timeout can fail slow-but-valid combinations before they reveal useful evidence.

Workflow Assembly:

The generated YAML uses pull request, push, and manual triggers according to the selected switches. Push branches are emitted only when the push trigger is enabled and branch names are present. Read-only contents permission is included when that switch is on, and a working-directory default is emitted only when a non-root directory is entered.

Setup-action caching and manual caching solve different problems. Setup-action cache inputs are concise when the language setup action supports the package manager. Manual cache steps expose the cache path directly and build a key from the runner OS, runtime version, and dependency-path hash expression. Generic lockfile globs are a fallback in either path, not a substitute for checking the real repository layout.

Generated output surfaces and their boundaries
Output What it contains Boundary
Workflow YAML Triggers, permissions, defaults, one matrix job, checkout, setup, optional cache, install, and test steps. It is not pushed to a repository or validated by GitHub until you commit and run it.
Matrix Ledger Runner OS, runtime version, optional extra axis, source, and experimental flag for each planned row. A planned row is intended coverage, not a completed GitHub Actions job.
Workflow Checks OK, Review, or Blocked status for path, count, setup, cache, triggers, fail-fast, timeout, warnings, and errors. OK means the local generation rules passed, not that the workflow is accepted by GitHub.
JSON The same parameters, matrix rows, checks, warnings, errors, and generated YAML in structured form. Use it for review or recordkeeping, not as a GitHub API response.

Accuracy and Privacy Notes:

The generated workflow is assembled from visible settings and local review rules. It does not inspect repository files, check current runner images, confirm that setup-action versions exist, or ask GitHub to validate the YAML.

  • Run the committed workflow manually before making it a branch protection requirement.
  • Confirm setup-action versions, supported cache inputs, and dependency file paths against the current action documentation for the repository.
  • Workflow content is not sent to GitHub by the generator. Copy and download actions use the current browser output.

Worked Examples:

Default Node.js CI

The Node.js preset with versions 20, 22, and 24 across ubuntu-latest and macos-latest creates 6 jobs. Workflow path shows .github/workflows/ci.yml, Workflow YAML sets the selected Node version from the matrix, and Matrix Ledger lists six base rows.

Python with one unsupported runner

A Python matrix using 3.11, 3.12, and 3.13 on ubuntu-latest and windows-latest starts with six jobs. Adding os=windows-latest,python-version=3.13 to Matrix exclude rows removes that unsupported combination, so Matrix Ledger should show five rows and the YAML should include an exclude entry.

Oversized compatibility grid

Six runner labels, eight runtime versions, and six shard values expand to 288 jobs before exceptions. Workflow Checks marks Matrix combinations as Review because the count is over GitHub's 256-job limit. Reduce an axis, add matching exclude rows, or split the coverage across more than one workflow.

Experimental include row

A stable Node.js matrix can add os=ubuntu-latest,node-version=25,experimental=true under Matrix include rows. The added Matrix Ledger row is marked yes for experimental, and Workflow YAML includes continue-on-error: ${{ matrix.experimental == true }} so that experimental failure does not fail the workflow run by itself.

No YAML after trigger changes

If Push trigger, Pull request trigger, and Manual trigger are all off, the error list says Enable at least one trigger. and Workflow YAML stays empty. Turn on Manual trigger for a safe first run, then verify that Blocking errors returns to OK.

FAQ:

Does the generator run the workflow in GitHub?

No. It creates Workflow YAML, Matrix Ledger, Workflow Checks, and JSON from the entered values. Commit the YAML and run it in GitHub Actions to confirm repository-specific behavior.

Why is the YAML output empty?

A blocking error is present. Common causes are empty Runtime versions, empty Runner OS labels, missing install or test commands, no enabled trigger, or extra-axis values without an axis name.

Should include rows contain every matrix key?

Yes when you want predictable review. Complete include rows make the added Matrix Ledger entry clear and avoid GitHub's merge-style include behavior changing how the row expands.

Why are version numbers quoted in the YAML?

Runtime versions are emitted as strings so values such as 3.10, 20, or lts/* stay version labels instead of being treated as ordinary YAML numbers.

What does the cache warning mean?

A cache warning means the generated cache step may be incomplete or broad. Check Cache package/input, Dependency path, and Manual cache path against the repository before relying on faster CI runs.

Does the generator send workflow content to GitHub?

No. It does not call the GitHub API or push files to a repository. The workflow text remains in the browser until you copy, download, commit, and run it yourself.

Glossary:

Matrix axis
A named list of values that GitHub combines with other axes, such as os or a runtime version key.
Matrix combination
One planned job created from a specific set of axis values.
Runner label
The runs-on value that selects the GitHub-hosted or self-hosted runner environment.
Setup action
An action that prepares a language runtime before install and test commands run.
Include row
An additional matrix entry emitted under strategy.matrix.include.
Exclude row
A key-value rule that removes matching base matrix combinations.
Fail-fast
A matrix policy that can cancel queued or in-progress jobs after a required matrix job fails.
Workflow trigger
An event such as push, pull_request, or workflow_dispatch that starts a workflow run.