Skip to content

Add Python 3.14 to the CI matrix - #131

Merged
wdolinar merged 1 commit into
masterfrom
feature/python-3.14-matrix
Aug 20, 2026
Merged

Add Python 3.14 to the CI matrix#131
wdolinar merged 1 commit into
masterfrom
feature/python-3.14-matrix

Conversation

@gagelarsen

Copy link
Copy Markdown
Member

First consumer of the per-platform Python fan-out from xmsconan #96, released as 2.21.0. xmscore is the pattern repo; the other seven follow once this is green.

The change

build.toml only:

[ci]
python_versions       = ["3.10", "3.13", "3.14"]   # Windows
mac_python_versions   = ["3.13", "3.14"]
linux_python_versions = ["3.13", "3.14"]

[coverage]
python_version = "3.13"

Workflows regenerated with xmsconan_ci at 2.21.0. Everything else in the diff is generated output.

Three lists rather than one because the constraints differ per platform: 3.10 exists for the desktop products' Windows wheel and nothing else needs it, and every Linux entry requires a published conan-gcc13-py<version> container — which exists for 3.13 and 3.14 only, with no 3.10/3.11/3.12 image on either registry.

Verified before opting Linux in

ghcr.io/aquaveo/conan-gcc13-py3.14 is public and anonymously pullable, which matters because the generated container: block carries no credentials: stanza. And it really is 3.14, checked by running it rather than reading its metadata:

$ docker run --rm ghcr.io/aquaveo/conan-gcc13-py3.14 python --version
Python 3.14.7

manylinux_2_28 base, gcc-toolset-13, built alongside the 3.13 image.

Two consequences worth knowing before merge

Release asset and wheel-artifact names change on mac and Linux. They now carry -py<version>linux-GCC13-Release-py3.13.tar.gz rather than linux-GCC13-Release.tar.gz. Unavoidable: those platforms now produce two ABIs each and the old names would have one leg overwrite the other. Windows already worked this way. If anything fetches those assets by exact name, it needs updating.

A tagged release publishes seven wheels instead of four — 3.10/3.13/3.14 on Windows, 3.13/3.14 on macOS and Linux. Distinct cp3XY tags, so they coexist under one devpi release rather than colliding. Wheel upload stays gated on refs/tags/ plus build_type == 'Release', so ordinary pushes and PRs still publish nothing.

CI time and Conan storage roughly double. If that's not wanted yet, dropping the two *_python_versions lines makes 3.14 Windows-only and is a one-line follow-up to widen later.

Why coverage is pinned

Coverage resolves to the highest linux_python_versions entry, so leaving it default would have moved the coverage gate 3.13 → 3.14 as a side effect of a matrix change. Pinning to 3.13 keeps Coverage.yaml's only diff the xmsconan version bump, so a 3.14 problem surfaces in the build legs alone rather than in two places at once. Worth removing once 3.14 is proven across the suite.

The actual risk

This is the first time anything in the suite compiles against 3.14. The Conan option permits it and pybind11 is at 3.0.1, which supports 3.14, but no build has happened. Python 3.14 removed C-API entry points, and xmscore has hand-written pybind glue — python/misc/PyUtils.cpp, the Listener / PublicProgressListener shims. If any of it touches a removed API, this CI run is where we find out, which is the point of doing xmscore first.

Note the linux job's status-check name changes (GCC-13 (Release, Linux)GCC-13 (Release, 3.13, Linux)) because the legs now differ by ABI and GitHub uses an explicit name: verbatim. master has no required_status_checks configured — only a one-approval review requirement — so nothing is blocked by the rename. Worth re-checking per repo as the rollout proceeds.

Windows gains 3.14 alongside 3.10 and 3.13. macOS and Linux gain it
alongside 3.13 through the per-platform lists xmsconan 2.21.0 introduced;
they need their own lists because 3.10 is Windows-only (the desktop products
consume that wheel) and because each Linux entry needs a published
conan-gcc13-py<version> container, which exists for 3.13 and 3.14 only.

Verified before opting Linux in: ghcr.io/aquaveo/conan-gcc13-py3.14 is
public and anonymously pullable -- the generated container: block has no
credentials: stanza -- and really is 3.14 (Python 3.14.7, manylinux_2_28
base, gcc-toolset-13).

[coverage].python_version is pinned to 3.13 rather than left to default.
Coverage follows the highest linux_python_versions entry, so without the pin
this change would also have moved the coverage gate 3.13 -> 3.14 as a side
effect. Keeping it on a proven ABI means a 3.14 problem shows up in the
build legs alone. Worth revisiting once 3.14 is proven across the suite.

Workflows regenerated with xmsconan 2.21.0, which also bumps the pin from
2.18.0. Regenerating renames the mac and linux release assets and wheel
artifacts to carry -py<version>, since those platforms now produce more than
one ABI each and the old names would collide between legs.

On a tagged release this publishes seven wheels instead of four: 3.10, 3.13
and 3.14 on Windows, and 3.13 plus 3.14 on both macOS and Linux.

This is the first build of anything in the suite against 3.14, so the pybind
layer compiling against the 3.14 C API is unproven until this CI run.
@gagelarsen

Copy link
Copy Markdown
Member Author

CI is green — all 15 legs, including every 3.14 leg on all three platforms:

success  Clang-Latest (Release, 3.14, Macos)        success  GCC-13 (Release, 3.14, Linux)
success  Clang-Latest (Debug, 3.14, Macos)          success  GCC-13 (Debug, 3.14, Linux)
success  Visual Studio 17 (Release, 3.14, Windows)  success  Visual Studio 17 (Debug, 3.14, Windows)

That answers the open risk in the description: the hand-written pybind glue compiles and its tests pass against the Python 3.14 C API, on MSVC, Clang and GCC. No C-API fallout.

About the warning annotations on the run

Every job emits a Node.js 20 deprecation warning. These are pre-existing and not from this change — master's latest run emits the identical warning; a 15-job matrix just produces 15 copies of it instead of 8. GitHub is force-running the affected actions on Node 24, so nothing is broken.

The pins are further behind than the warning suggests, though — actions/checkout@v4 against a current v7.0.1, a stray actions/setup-python@v2 in the flake job, and actions/upload-release-asset@v1 which has been archived since 2021 while sitting on the release-publishing path.

That belongs in xmsconan, not here — it owns the templates, so one fix covers all eight repos. Audited and filed as Aquaveo/xmsconan#102, deliberately kept out of this PR: it touches every job in every template, and a bad major bump would break CI in all eight repos at once.

@wdolinar
wdolinar merged commit 52649a0 into master Aug 20, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants