repomatic.matrix_axes module¶
Test matrix constants for CI workflows.
Defines the GitHub-hosted runner images and Python versions used to build
test matrices. Separating these from
repomatic.metadata.core makes the CI matrix configuration self-contained
and easier to update when runner images or Python releases change.
- repomatic.matrix_axes.TEST_RUNNERS_FULL = ('ubuntu-26.04-arm', 'ubuntu-26.04', 'macos-26', 'macos-26-intel', 'windows-11-arm', 'windows-2025')¶
GitHub-hosted runners for the full test matrix.
Two variants per platform (one per architecture). See available images.
Note
Preview images are adopted on measurement, not on GitHub’s label
GitHub still marks the Ubuntu 26.04 pair preview, which gates their eligibility to sit behind the
-latestaliases. This project never uses those aliases (a floating alias re-points with no commit to review, whichcheck_runner_images()rejects outright), so that distinction does not reach it. An image is treated as stable here once it has been validated against this suite, not once a vendor relabels it. Measured over consecutive runs before the swap,ubuntu-26.04-armbeatubuntu-24.04-armby 16% on Python 3.10 and 28% on 3.14, tied on 3.15, and failed nothing.The residual risk is capacity rather than correctness: GitHub warns a preview image’s capacity “will be balanced only throughout the next weeks”, so queue time may be worse than the runtimes above suggest. Release binaries are built on GA images for that reason, see
NUITKA_BUILD_TARGETS.Note
Architecture speed is not uniform across platforms
When reducing to one runner per OS, choose by measured speed, not architecture (see Test matrix). Tendencies from
repomatic’s own full test suite: ARM Linux runs two to three times as fast as the lean x86ubuntu-slimthat precededubuntu-26.04on this axis; Apple-siliconmacos-26beatsmacos-26-intelby ~2x; the two Windows images tie on compute (windows-2025is the PR pick). Per-job wall-clock folds in setup and upload, so isolate the test steps before blaming the image. These figures drift as images are re-provisioned, so re-confirm against your own job timings.
- repomatic.matrix_axes.TEST_RUNNERS_PR = ('ubuntu-26.04-arm', 'macos-26', 'windows-2025')¶
Reduced runner set for pull request test matrices.
One runner per platform: ARM Linux (
ubuntu-26.04-arm) and Apple-silicon macOS (macos-26) are the fastest of their platform on the test workload, plus x86 Windows (windows-2025, where the two Windows images tie on compute). x86 Linux stays covered by the full matrix (TEST_RUNNERS_FULL).Note
Why ARM Linux for the PR slot
The suite runs
pytest --numprocesses=auto, so it scales with cores and favors ARM, by two to three times over the x86 image, for quicker PR feedback. See Test matrix for the measurements.
- repomatic.matrix_axes.TEST_PYTHON_FULL = ('3.10', '3.14', '3.15')¶
Python versions tested across every runner in the full matrix.
Spans the supported range: the floor (
3.10), the latest stable release (3.14), and the in-development version (3.15, flaggedcontinue-on-errorviaUNSTABLE_PYTHON_VERSIONS). Intermediate releases (3.11, 3.12, 3.13) are skipped to reduce CI load. Released build flavors (free-threaded) are not full-spread; they get a single-runner smoke test instead, seeSINGLE_RUNNER_PYTHON_VERSIONS.
- repomatic.matrix_axes.TEST_PYTHON_PR = ('3.10', '3.14')¶
Reduced Python version set for pull request test matrices.
Just the floor and the latest stable release, for fast PR feedback. The in-development version and released build flavors (free-threaded) are left to the full matrix.
- repomatic.matrix_axes.UNSTABLE_PYTHON_VERSIONS: Final[frozenset[str]] = frozenset({'3.15'})¶
Python versions still in development.
Jobs using these versions run with
continue-on-errorin CI. Contrast withSINGLE_RUNNER_PYTHON_VERSIONS, which are released and run stable.
- repomatic.matrix_axes.PRERELEASE_LABEL_SUFFIX: Final[str] = '-dev'¶
Suffix marking an unreleased Python in a CI job name.
Appended to each
UNSTABLE_PYTHON_VERSIONSmember to form thepython-labelmatrix key, so acontinue-on-errorcell states why it may fail:⁉️ ubuntu-26.04 / py3.15-devrather than a barepy3.15indistinguishable from a released one. Being a plain suffix append, it composes with the free-threaded flavor the way both tools below spell it:3.15treads3.15t-dev.The spelling is borrowed, not invented. pyenv ships version definitions named
3.15-devand3.15t-devthat build from the CPython branch tip, and actions/setup-python documents anx.y-devsyntax resolving to “the latest patch version of Python, alpha, beta and rc (release candidate) releases included”. Anyone reading a GitHub Actions job name has met it in one of the two.Warning
A label, never a uv request
uv does not implement the syntax.
uv python find 3.15parses as a version request (“No interpreter found for Python 3.15”), while uv python find 3.15-dev falls through to the executable-name branch (“No interpreter found for executable name3.15-dev”). The workflow handspython-versionstraight touv venv --python, so the axis value stays the bare version and this suffix reaches the jobname:alone. Writing it into a[tool.repomatic.test-matrix]directive matches no cell.
- repomatic.matrix_axes.SINGLE_RUNNER_PYTHON_VERSIONS: Final[dict[str, str]] = {'3.14t': 'ubuntu-26.04-arm'}¶
Released Python build flavors smoke-tested on a single runner, mapped to it.
A free-threaded build (the
tsuffix, made officially supported in 3.14 by PEP 779) runs the same released interpreter as its base version, just without the GIL. The base version already gets the full cross-platform spread (TEST_PYTHON_FULL), so the library logic is covered everywhere; the flavor only needs one runner to catch a free-threading-specific break. These run stable (expected to pass), unlike the unreleasedUNSTABLE_PYTHON_VERSIONS. The runner isubuntu-26.04-arm, the default single-runner pick: the fastest measured on compute-bound parallel work and the cheapest tier, and free-threading targets server workloads where Linux/ARM is the norm (see Test matrix).
- repomatic.matrix_axes.python_version_sort_key(version)[source]¶
Sort key ordering
python-versionaxis values by release.Compares on the numeric release components, then places a build flavor (the free-threaded
tsuffix ofSINGLE_RUNNER_PYTHON_VERSIONS) directly after its base version rather than after every later release:3.14sorts before3.14t, which sorts before3.15. Non-numeric components are dropped, so an axis value likepypy3.10falls back to the digits it carries.