File a cycle's changelogs as a pull request - #2103
Merged
Merged
Conversation
The build already produced everything changelogs/ needs, and it was still copied in by hand: nine package indexes, nine lock files, nine requirements, and nine _History.md written one wppm.diff call at a time. A changelogs job now does it. It takes the metadata artifacts the legs produced, files the three kinds that belong in changelogs/, writes the histories from the checkout -- a history compares against the previous release, which only the repository has -- and opens one pull request for the cycle. changelog_files.py decides what goes where; wppm.diff still decides what a history says. Whole-cycle publish runs only. Re-running one leg would otherwise reduce the branch to that leg's files, and it has nothing to add: the same lockfile builds the same package list, so a rebuilt leg cannot change a changelog. Opened with git and gh rather than a third-party action, to keep a repo that hash-pins its build inputs from taking a new action with write permissions for the sake of nine files. Checked against the real thing: the 27 metadata files of 2026-04 b1, run over a copy of changelogs/, file 27 and write 9 histories against the right baselines -- 3.15.0.5b1 against 3.15.0.4 -- adding 36 files and modifying none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3
changelog_files.py imported wppm and CI answered ModuleNotFoundError. Running a script puts the script's own directory on sys.path -- here .github/scripts -- and not the checkout root, so the import fell through to whatever else was reachable. On a developer machine that is the installed wppm and everything looks fine; a runner installs none, so the step died. The workflow job would have died the same way, not just the tests. The path is now derived from __file__ and inserted first, so the wppm imported is the one being released. The tests missed it for the same reason CI caught it, so they now run the script by absolute path from an unrelated directory, with a decoy wppm on PYTHONPATH. The insert puts the checkout ahead of that decoy; without it the decoy wins and the test fails, on any machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3
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.
Move 3 of the publishing clean-up, after #2098 (one dispatch per cycle, build publishes itself). The build already produces everything
changelogs/needs; this stops it being copied in by hand — nine package indexes, nine lock files, nine requirements, and nine_History.mdwritten onewppm.diffcall at a time.How it works
A
changelogsjob takes the metadata artifacts the legs produced, files the three kinds that belong inchangelogs/, writes the histories, and opens one pull request for the cycle.The histories are written from the checkout rather than shipped by the build, because a history compares against the previous release and only the repository has that.
changelog_files.pydecides what goes where;wppm.diffstill decides what a history says.hashes_<winpyver>.mdstays out: it describes one build's binaries rather than the release, andchangelogs/has never held one.Whole-cycle runs only
if: inputs.publish && inputs.python_versionf == 'all'. Re-running a single leg would otherwise reduce the branch to that leg's files — and it has nothing to add anyway, since the same lockfile builds the same package list, so a rebuilt leg cannot change a changelog.No new action
Opened with
gitandghrather than a create-pull-request action. A repo that hash-pins its build inputs shouldn't take on a third-party action withcontents: writeandpull-requests: writefor the sake of filing nine files.Checked against the real thing
Not a mock: the 27 metadata files of the
2026-04b1draft, run over a copy of the realchangelogs/.The
slimhistory lists real deltas (aiohappyeyeballs 2.6.1 → 2.7.1, newclarabel/lmfit/scipy); thedotone correctly reports no differences, bare Python being unchanged.Testing
16 new tests, 223 in the full suite. The selection is pinned against the leg output names verbatim, and mutation-checked: widening the filter to any
.md/.toml/.txtfails the two tests that say hashes stay behind, and loosening the whole-cycle gate fails the test that says a single-leg re-run must not file changelogs.One thing that only runs for real on a dispatch: the push and
gh pr create. The job is gated so it cannot fire on apublish: offor single-version run.🤖 Generated with Claude Code
https://claude.ai/code/session_01MBk5k7WdpPvx4SUFyEk3U3