Cycle build publishes itself - #2098
Merged
Merged
Conversation
The cycle workflow built one Python version per dispatch and stopped at upload-artifact, so a cycle cost five dispatches, five artifact downloads and a release upload done by hand. cycle_config.py now hangs the version, tarball and paths off each matrix leg rather than the job, so a leg names its own Python and "all" builds the whole cycle in one go. It also derives the release tag from the cycle name and release level -- 2026_04 at b1 publishes as 2026-04b1 -- which a release_tag key overrides, and refuses a tag git would not take as a ref while that still costs five seconds rather than an hour of build. One job opens the draft release, so the legs cannot race to create it, and each leg uploads its own files with --clobber: re-running a missing flavor lands on the release the others are already on. No date in the tag, for that reason and because the download URLs outlive the run. With publish off the output stays artifacts as before; with it on the artifact keeps only the metadata the changelog commit needs, so a 670 MB slim.7z is no longer re-zipped to no purpose. fail-fast goes off with it: a cycle is nine legs now, and one bad flavor should not bin the eight that built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3
This was referenced Sep 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits: the workflow change below, and
2026-04 b1 updatecarrying the 2026-04 b1 lockfile refresh (including the new 3.15 slim pair, which is what takes the cycle to nine buildable legs).The cycle workflow built one Python version per dispatch and stopped at
upload-artifact, so a cycle cost five dispatches, five artifact downloads (~2 GB) and a release upload done by hand. This makes one dispatch build the whole cycle and hands the build its own publishing.One dispatch per cycle
cycle_config.pyhangs the version, tarball and paths off each matrix leg rather than the job, so a leg names its own Python and the matrix can be (Python × flavor) instead of flavor alone.python_versionfgainsall, which takes every Python the cycle has lockfiles for and quietly skips the ones whose lockfiles are not committed yet. A single version still dispatches exactly as before, through the same code path.The build publishes its own output
A new
publishinput (default on) makes one job open a draft release, so the legs cannot race to create it, and each leg then uploads its own files with--clobber. Re-running a missing flavor lands on the release the others are already on. Withpublishoff, everything stays artifacts as it does today.The tag comes from the cycle file:
<cycle name with dashes><release_level>, so2026_04atb1publishes as2026-04b1, and a respin is arelease_levelbump rather than a tag to invent. Arelease_tagkey overrides it. There is deliberately no date in the tag — a date would fix it to a run rather than a release, so re-running one flavor tomorrow would open a second release, and the download URLs the site publishes outlive the run. A tag git would refuse as a ref is rejected in the 5-second config job rather than an hour into a build.Smaller things that came with it
publishon, the artifact keeps only the metadata the changelog commit needs, so a 670 MBslim.7zis no longer re-zipped byupload-artifactfor nothing.fail-fastgoes off: a cycle is nine legs, and one bad flavor should not bin the eight that built.permissions: {}at the top with least privilege per job,persist-credentials: falseon the build checkout, and the dispatch inputs passed throughenv:rather than interpolated into the shell.Testing
Not yet run on Actions — it needs a dispatch. Checked statically against what the script emits: every
matrix.leg.*andneeds.config.outputs.*the workflow reads exists on every leg in all six dispatch choices, no stalematrix.flavorreferences, the artifact steps are mutually exclusive, anddotwheelhousekeeps its exact value.cycles/2026_04.tomlyields 9 legs andcycles/2026_03.tomlthe 10 that cycle shipped. The tag derivation was checked over four cases and five malformed tags, and the upload shell logic ran against a mockpublish_output, including a slash-bearing tag and the guard that fails a leg producing no binary.Worth a trial dispatch on a fork with
publishoff, then one with it on, before this drives a real cycle.The per-cycle copies (
github_workflows_build-*.yml) are left in place: only2026_03has a matching TOML today, and this path has not had a green run yet. They can go once it has.🤖 Generated with Claude Code
https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3