Skip to content

[AAASM-4453] ✅ (ci): Build all supported-Python wheels + drift guard - #240

Merged
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4453/wheel_version_matrix_guard
Jul 12, 2026
Merged

[AAASM-4453] ✅ (ci): Build all supported-Python wheels + drift guard#240
Chisanan232 merged 4 commits into
masterfrom
v0.0.1/AAASM-4453/wheel_version_matrix_guard

Conversation

@Chisanan232

@Chisanan232 Chisanan232 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Description

Systemic follow-up to AAASM-4446. That bug's immediate fix (PR #239) added cp313/cp314 to the release matrix; this PR makes the matrix provably track declared Python support so it can't silently drift again.

Two parts:

  1. Single source of truth. PR [AAASM-4446] 🔧 (ci): Build cp313 wheels in the release matrix #239 hardcoded 3.12 3.13 3.14 in six places. This introduces one PYTHON_INTERPRETERS env var in release-python.yml that every wheel job consumes (maturin --interpreter), and the macOS jobs translate it to setup-python's newline form in a small Expand step. Adding or dropping a supported version is now a one-line env edit.

  2. PR-time drift guard. A new .github/scripts/check-wheel-python-matrix.sh fails if:

    • the PYTHON_INTERPRETERS list != the Programming Language :: Python :: 3.x classifiers in pyproject.toml,
    • the requires-python floor != the lowest built version, or
    • any wheel job hardcodes a literal --interpreter <version> (bypassing the single source).

    It runs on every PR (not just release) via a dedicated wheel-python-matrix.yml workflow, triggered on pyproject.toml / release-python.yml / the guard's own files — mirroring the existing release-python-conversion-test.yml pattern rather than widening ci.yaml's path allow-list. The guard is covered by an 8-case fixture suite (test_check-wheel-python-matrix.sh).

This is the root-cause fix for the AAASM-4446 bug class: "claim support you don't build wheels for" now fails a check in review.

Type of Change

  • 🔧 Bug fix (process / CI hardening)

Breaking Changes

  • No

Related Issues

Stacking

Stacked on #239 ([AAASM-4446]). Base branch is master per convention, but this branch is cut on top of v0.0.1/AAASM-4446/release_cp313_wheels, so it includes #239's commit. Merge #239 first; after it merges the diff here reduces to the single-source refactor + drift guard.

Testing

  • Unit tests added (test_check-wheel-python-matrix.sh, 8 cases)
  • Manual testing performed

Validated locally: actionlint clean on both release-python.yml and wheel-python-matrix.yml; shellcheck clean on the guard + test; the guard passes against the real repo files and fails (rc=1) on a deliberate classifier/matrix desync and on a hardcoded --interpreter literal; the fixture suite reports 8 passed / 0 failed. The real multi-interpreter maturin build (macOS multi-setup-python + manylinux multi-interp) can only be exercised at an rc dispatch, not locally — that proof lands at the next rc.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated if needed
  • All tests passing

@Chisanan232

Copy link
Copy Markdown
Contributor Author

Claude Code — 4-point review

1. CI — ✅ All green, including the new drift-guard job Check wheel matrix matches declared Python support (runs shellcheck + the guard + the 8-case fixture suite — pass). Also Analyze (python), analyze/CodeQL, Run tag → PEP 440 fixture suite pass. The main pytest matrix is correctly absent (workflow-only change excluded by ci.yaml path-filter); the drift-guard SHOULD and DID run — as intended.

2. Scope vs ticket (AAASM-4453) — ✅ Matches. (a) Single source of truth: one PYTHON_INTERPRETERS='3.12 3.13 3.14' env var consumed by all four wheel jobs' --interpreter; macOS jobs translate it to setup-python's newline form in a small Expand step, so adding a version is a one-line edit. (b) PR-time drift guard: check-wheel-python-matrix.sh fails if the built list ≠ pyproject 3.x classifiers, if the requires-python floor ≠ lowest built version, or if any job hardcodes a literal --interpreter; wired via a dedicated wheel-python-matrix.yml triggered only on the contract's own paths (mirrors the existing release-python-conversion-test.yml pattern rather than widening ci.yaml). Verified against real files: requires-python=">=3.12,<4.0", classifiers 3.12/3.13/3.14, PYTHON_INTERPRETERS = same three, floor 3.12 == min built — guard passes. cp314 correctly included.

3. Side effects (CI/CD) — ✅ No regression. The single-source substitution preserves all four platform jobs (no platform dropped) and the sdist job; the two macOS Expand steps emit a correct heredoc to GITHUB_OUTPUT (space→newline). workflow_dispatch-only trigger and inputs intact; publish/OIDC path untouched (id-token:write still scoped to publish). The new wheel-python-matrix.yml is path-filtered to pyproject.toml / release-python.yml / the guard's own files, so it won't false-fail unrelated PRs. Same inherent caveat as #239: true multi-interp maturin build proof lands at the next rc dispatch.

4. Front-end — N/A. Workflow YAML + shell only; no front-end code, no Playwright.

Overall: APPROVE. Stacked on #239 — merge #239 first, then this. (Not merging / not changing Jira per review scope.)

— Claude Code

AAASM-4446 added cp312/cp313/cp314 by hardcoding "3.12 3.13 3.14" in four
places (each job's --interpreter) plus the two macOS setup-python lists, so
adding or dropping a supported version means editing six sites and any missed
site silently drifts.

Introduce a single PYTHON_INTERPRETERS env var and consume it everywhere: the
four maturin --interpreter args reference it directly, and the macOS jobs
translate it to setup-python's newline-separated form in a small Expand step.
Adding a version is now a one-line env edit; the drift guard added next pins
that env to pyproject's declared support.

Refs AAASM-4453
Fail-fast check that the release wheel matrix matches declared Python
support: the PYTHON_INTERPRETERS list in release-python.yml must equal the
"Programming Language :: Python :: 3.x" classifiers in pyproject.toml, the
requires-python floor must equal the lowest built version, and no wheel job
may hardcode a literal --interpreter list bypassing the single source.

This is the root-cause fix for AAASM-4446: the cp312-only-vs-declared-3.13
drift now fails a check instead of silently shipping a broken install.

Refs AAASM-4453
Exercises check-wheel-python-matrix.sh against synthetic pyproject/workflow
fixtures for the passing case, both drift directions, requires-python floor
drift, a hardcoded --interpreter literal, and unparseable-input fail-loud —
plus one run against the repo's real files proving the shipped config passes.
8 cases, mirrors the existing test_pep440_to_tag.sh style.

Refs AAASM-4453
New workflow that lints and runs check-wheel-python-matrix.sh plus its
fixture suite on any PR touching pyproject.toml or the release workflow (and
the guard's own files). Mirrors release-python-conversion-test.yml: a
dedicated sibling workflow so the guard runs at PR time — not release time —
without widening ci.yaml's path allow-list.

This closes the AAASM-4446 loop: the matrix can no longer silently drift from
requires-python + classifiers, because a divergent PR fails this check.

Refs AAASM-4453
@Chisanan232
Chisanan232 force-pushed the v0.0.1/AAASM-4453/wheel_version_matrix_guard branch from c19b071 to 65dde0d Compare July 12, 2026 11:27
@Chisanan232
Chisanan232 merged commit bf4e700 into master Jul 12, 2026
5 checks passed
@Chisanan232
Chisanan232 deleted the v0.0.1/AAASM-4453/wheel_version_matrix_guard branch July 12, 2026 11:29
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.

1 participant