Skip to content

Test that the cycle workflow and its config script agree - #2099

Merged
stonebig merged 1 commit into
winpython:masterfrom
stonebig:test-cycle-config-agreement
Sep 6, 2026
Merged

stonebig merged 1 commit into
winpython:masterfrom
stonebig:test-cycle-config-agreement

Conversation

@stonebig

@stonebig stonebig commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #2098, which made one dispatch build a whole cycle and publish its own output. This adds the test that keeps the two halves of that honest.

Why

build_winpython_cycle.yml reads the build shape out of .github/scripts/cycle_config.py as matrix.leg.<key> and needs.config.outputs.<key>. Actions resolves an expression naming a key nothing emits to the empty string, without a word about it — so a renamed key does not fail at the line that reads it. It fails later, in PowerShell, an hour into a Windows runner, with an empty path. That is slow to find and slow to retry.

What it checks

tests/test_cycle_config.py, 35 tests, in three groups:

  • Per cycle file, parametrized over cycles/*.toml, so a new cycle is covered the moment its TOML lands: it yields at least one leg, every lockfile a leg names exists, artifact names are unique (two legs sharing one would race to upload), ver2 appears in the tarball URL, and a free-threaded Python builds only *f flavors — 3.14 and 3.14F share a ver2, so the WINPYARCHDET filter is all that separates them, and if it stopped applying a free-threaded run would rebuild the ordinary flavors under the same file names.
  • Release tags: the derivations, the explicit release_tag override, and nine names git would refuse as a ref.
  • Workflow against script: every matrix.leg.* and archive format the workflow reads is emitted; declared job outputs come from the script and every output read is declared; no matrix.flavor survives from the old shape; both publish gates exist, so a run with publish off cannot build gigabytes and upload none of it; and TAG is never taken from a dispatch input, keeping the cycle file the single source. Plus a drift check: every Python in a cycle file must appear in the workflow's choice list, or a cycle can offer a Python that all builds but nobody can re-run alone when one flavor fails.

No new dependencies

The workflow is read as text rather than parsed as YAML, so the pinned test dependencies stay pytest and packaging and nothing needs re-locking.

Testing

35 passed; full suite 163 passed. Three mutations confirm the tests can go red, each caught by the intended test and nothing else: renaming matrix.leg.src in the workflow, replacing the !inputs.publish gate with always(), and typo'ing the lockfile name in the script.

test_wppm.yml triggered on wppm/, winpython/, tests/ and pyproject.toml, so a commit touching cycle_config.py, build_winpython_cycle.yml or cycles/ ran none of this — the commit where the answer is worth having. Those three paths are added to both the push and pull_request triggers.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3

Actions resolves an expression naming a key nothing emits to the empty
string, without a word about it. So a renamed matrix.leg key does not
fail at the line that reads it: it fails later, in PowerShell, an hour
into a Windows runner, with an empty path.

tests/test_cycle_config.py reads the workflow as text and runs
cycle_config.py for real over whatever cycle files are committed, so a
new cycle is covered the moment its TOML lands. It checks that the two
sides name the same keys, that every leg points at a lockfile that is
there, that artifact names cannot collide, that ver2 matches the tarball
it downloads, that a free-threaded Python builds only free-threaded
flavors -- 3.14 and 3.14F share a ver2, so nothing else separates them
-- and the release tag rules, including the names git would refuse as a
ref. Nothing new to install: the workflow is text rather than parsed
YAML, and the pinned test dependencies stay pytest and packaging.

test_wppm.yml ran none of it, having no trigger on the paths these tests
guard, which is the commit where the answer is worth having. It does
now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3
@stonebig
stonebig merged commit 3c269a8 into winpython:master Sep 6, 2026
2 checks passed
@stonebig
stonebig deleted the test-cycle-config-agreement branch September 6, 2026 13:45
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