Skip to content

Read the CI Python versions from the recipes' conda_build_config.yaml - #264

Merged
antonwolfy merged 5 commits into
masterfrom
python-versions-from-recipe
Oct 29, 2026
Merged

antonwolfy merged 5 commits into
masterfrom
python-versions-from-recipe

Conversation

@antonwolfy

@antonwolfy antonwolfy commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #263; the diff shows only this PR's change. GitHub retargets it as the PRs below it are merged.

Summary

The Python versions that the conda workflows build and test now come from the python: list in each recipe's conda_build_config.yaml, in the spec format conda-forge pinning uses:

python:
    - 3.11.* *_cpython
    - 3.12.* *_cpython
    - 3.13.* *_cp313
    - 3.14.* *_cp314
    - 3.14.* *_cp314t
    - 3.15.* *_cp315
    - 3.15.* *_cp315t

This replaces the static matrix in conda-build-test.yml, the hard-coded 3.14/3.15 rows, and the python-versions input added in #263. conda-recipe/ lists 3.10-3.15 with 3.14t and 3.15t; conda-recipe-cf/ lists the feedstock's versions (3.11-3.15, 3.14t) plus 3.15t. To change the set, you now edit the recipe.

How it works

  • A new variants job runs a new composite action, .github/actions/conda-python-matrix, which reads the python: list from the caller's recipe and outputs the matrix for the build and test jobs. Its script, conda_python_matrix.py, uses only the standard library and doesn't install conda or render the recipe. It fails on bare versions (3.12) and on selectors, so every job gets an explicit ABI; that matters because a bare --python 3.14 has been observed to pick the free-threaded build. It also fails on an ABI that doesn't match the version (3.13.* *_cp314t) and on a second entry for the same build, whose artifact names would collide. Quoted entries are accepted, and comment lines are skipped. You can run it locally: python .github/actions/conda-python-matrix/conda_python_matrix.py conda-recipe-cf/conda_build_config.yaml.
  • The build job passes each entry to conda build --python "<spec>". With the full list in the config, conda-build then builds only that one variant: rendering conda-recipe-cf gives 7 variants without --python and exactly one (python 3.14.10 *_cp314t) with --python "3.14.* *_cp314t".
  • The build and test jobs get explicit names built from the matrix, so the check names don't change: Build (3.12) for a version with one build and Build (3.14, 3.14.* *_cp314t, 3.14t) for a version with GIL and free-threaded builds. The master ruleset requires the six 3.14 Test checks by these exact names. I compared the generated names with the 46 conda checks reported on Build the conda-forge workflow like the conda-forge feedstock #263, and they are identical. One cosmetic difference: when a failed build skips the whole Test job, GitHub never expands its matrix, so that check shows as Test (${{ matrix.label }}) instead of Test.
  • Artifact names are unchanged. They use python_tag, which is now always set (3.12, 3.14, 3.14t, ...).

The exact specs keep the Intel workflow's Python builds the same: Intel-channel Python packages also have _cpython build strings, so 3.12.* *_cpython still resolves to the Intel channel's python 3.12.8 (he267403_8_cpython on linux-64, h3c23a9a_8_cpython on win-64), as the bare 3.12 did. 3.13 and 3.15 come from conda-forge (*_cp313, *_cp315t), as before.

Side effect: a plain conda build conda-recipe (or conda-recipe-cf) now builds every listed Python version. Pass --python "3.12.* *_cpython" to build one; conda-recipe/AGENTS.md says so.

Prepared for the shared workflow

The action's directory refers to nothing outside itself, so it can move to a shared repository together with conda-build-test.yml. After that move, the uses: line in the variants job must change from ./.github/actions/conda-python-matrix (which resolves against the caller's checkout) to $/.github/actions/conda-python-matrix. GitHub's self-repository syntax resolves against the repository of the workflow file itself and needs no checkout. It isn't $/ already because actionlint 1.7.12, used by pre-commit, rejects that syntax (rhysd/actionlint#711). .github/AGENTS.md records this.

Changes

  • conda-recipe/conda_build_config.yaml, conda-recipe-cf/conda_build_config.yaml: add the python: lists
  • .github/actions/conda-python-matrix/: new composite action (action.yml, conda_python_matrix.py)
  • conda-build-test.yml: new variants job; build and test use its matrix and explicit names; the python-versions input and the static matrices are removed
  • conda-package-cf.yml: stop passing python-versions
  • AGENTS.md files: the policy "keep the Python matrix in workflow files" becomes "the conda workflows read it from the recipe" (build_pip.yml and the clang workflows keep their own matrices); document the spec rules, the check-name constraint, and the action

Test plan

  • pre-commit (including black, flake8, isort, pylint and actionlint) and zizmor --min-severity medium .github/ report no findings
  • The script, run on both configs, produces the expected entries; their names match all 46 conda check names on Build the conda-forge workflow like the conda-forge feedstock #263
  • The script rejects a selector on an entry or on the key, a bare version, a missing list, a duplicate python: key, an ABI that doesn't match the version, and a second entry for the same build; it accepts quoted entries and skips comment lines, also at column 0 inside the list
  • conda render with the in-recipe list selects a single variant per --python spec, for conda-recipe-cf (conda-forge) and conda-recipe (Intel channel; linux-64 and win-64 for 3.12, 3.13 and 3.15t)
  • On the previous revision of this PR, the Intel workflow was green with the same check names as Build the conda-forge workflow like the conda-forge feedstock #263
  • CI on this revision is green and has the same Build and Test check names as Build the conda-forge workflow like the conda-forge feedstock #263, plus one Variants job per platform

List the Python versions as full specs in the python: key of
conda-recipe/conda_build_config.yaml and
conda-recipe-cf/conda_build_config.yaml, the way conda-forge pinning
lists them, instead of in the matrix of conda-build-test.yml and the
python-versions input.

A new variants job in conda-build-test.yml outputs the build/test
matrix from that list with a new composite action,
.github/actions/conda-python-matrix. Its script reads the list without
rendering the recipe, using only the standard library, and rejects bare
versions and selectors, so every job gets an explicit ABI, as the 3.14
and 3.15 rows had before. The build job passes each entry to
conda build --python, which selects that single variant from the list.
The action refers to nothing outside its directory, so it can move to a
shared repository together with conda-build-test.yml.

The build and test jobs get explicit names, so the check names stay
those of the former static matrix: "Build (3.12)" for a version with
one build, "Build (3.14, 3.14.* *_cp314t, 3.14t)" for a version with
GIL and free-threaded builds. The master ruleset requires the 3.14
Test checks by these names.

Update the AGENTS.md files: the Python versions now come from the
recipes, a plain "conda build <recipe>" builds all of them, and the
action's uses: line must switch to the $/ self-repository syntax when it
moves, which actionlint does not support yet.
@vlad-perevezentsev

vlad-perevezentsev commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Side effect check: with the python: list in conda-recipe/conda_build_config.yaml, a conda build conda-recipe without --python now builds all 8 variants. Do any internal Intel-channel build pipelines build this recipe without --python? If so, they need updating before this lands.

FYI, harmless: the build-string hash is now per Python version (py310hc2b3a8e, py311hc4e632d, ...) instead of one shared hash (h51e2b0f), because the python spec now takes part in the variant hash.

Comment thread .github/actions/conda-python-matrix/conda_python_matrix.py
Comment thread .github/actions/conda-python-matrix/conda_python_matrix.py Outdated
Comment thread conda-recipe/AGENTS.md Outdated
Comment thread .github/AGENTS.md Outdated
A comment at column 0 inside the python: list ended the list, so the
entries after it were dropped from the matrix without an error, while
conda-build, which reads the file as YAML, still saw them. Skip comment
lines instead.

Reject an entry whose ABI doesn't match its version (3.13.* *_cp314t
was accepted and tagged 3.13t), and a second entry for a build already
listed, such as a duplicate line or 3.12.* *_cpython next to
3.12.* *_cp312: both failed only later, when the artifact names
collided.

Since the build job runs conda build from the base environment, no job
reads the python field of the matrix any more, so drop it.
The python: lists in the recipes' conda_build_config.yaml are now the
only place the conda workflows take their Python versions from; listing
them again in AGENTS.md brings back the drift that moving them there
removed. Say where they come from instead.

Document the new checks of the variants job, and drop the policy line
about repeating experimental in include rows: no workflow uses
experimental any more.
@antonwolfy

Copy link
Copy Markdown
Collaborator Author

Do any internal Intel-channel build pipelines build this recipe without --python?

No, I checked the internal pipeline's logs. Every conda build job (dev and prod, Linux and Windows, 3.10 to 3.14t, packages and wheels) passes --python: a bare version below 3.14 (--python "3.12"), and 3.14.* *_cp314 or 3.14.* *_cp314t for 3.14. --python replaces the recipe's python: list, so each job still builds one variant. Rendering conda-recipe from this PR with each of those values gives one package each, with the same build strings those jobs produced from master yesterday (py312hc05a690, py314h7914234, py314hcd6fef5). Nothing needs updating before this lands.

On the hash: agreed, it's harmless. The internal builds keep their hashes, because they pass either a bare version or the same spec as before.

@vlad-perevezentsev
vlad-perevezentsev self-requested a review October 29, 2026 13:43

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more comments from my side
LGTM
Thank you @antonwolfy

Base automatically changed from align-cf-workflow-with-feedstock to master October 29, 2026 15:56
jharlow-intel added a commit that referenced this pull request Oct 29, 2026
conda-forge no longer builds Python 3.10. The list now has the same entries as
the one #264 adds, so whichever of the two lands second keeps one of them.
@antonwolfy
antonwolfy merged commit 1b7a50c into master Oct 29, 2026
172 of 175 checks passed
@antonwolfy
antonwolfy deleted the python-versions-from-recipe branch October 29, 2026 17:42
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