release: close remaining tag and artifact coherence gaps - #559
Conversation
`_verify_sdist` selected PKG-INFO with `member.name.endswith("/PKG-INFO")`.
setuptools ships the `.egg-info` directory inside the sdist, so a real archive
has two:
chainweaver-0.14.1/PKG-INFO
chainweaver-0.14.1/chainweaver.egg-info/PKG-INFO
The selector collected both and raised "expected one PKG-INFO, found 2".
Reproduced by exporting this branch, running `python -m build`, and running the
script against the result — it exits 1. The step sits after `python -m build`
and before `Upload dist artifacts`, so on the next `v*` tag the build job would
have died and publish never run: a release outage introduced by the change
meant to protect releases.
Now matches only the archive's top-level PKG-INFO via PurePosixPath parts.
The tests did not catch this because the fixture wrote a single PKG-INFO — a
shape `python -m build` never produces. The fixture now adds the nested
egg-info member, so all five existing cases exercise the real thing, plus one
new case asserting the nested file is ignored rather than counted.
Verified by mutation: with the realistic fixture and the old selector, three
tests fail (including two that previously passed against the unrealistic
shape); with the fix, six pass. End to end, `verify_dist.py 0.14.1` against a
genuine wheel + sdist prints "verified ChainWeaver 0.14.1 wheel + sdist
metadata" and exits 0.
Also moves `Sequence` to `collections.abc` (ruff UP035, pre-existing on this
branch and would have failed lint).
Co-Authored-By: Claude <noreply@anthropic.com>
|
Found a release-breaking bug in this branch and fixed it on the branch — The bug
Reproduced rather than reasoned about — exported this branch, ran Why it mattered. In The fix, and the reason the tests missed itSelection now matches only the archive's top-level The more interesting half: the five existing tests passed because Verified by mutation: with the realistic fixture and the old selector, 3 tests fail — including two that previously passed against the unrealistic shape. With the fix, 6 pass. End to end against a genuine wheel + sdist:
One structural gap I did not closeNo CI job builds a distribution, so The fix would be a small job in Two minors from the review, also unaddressed: The PR is still a draft and its previous CI run (2026-08-22) predates three commits of main, so it needs a fresh run before merge. Generated by Claude Code |
scripts/verify_dist.py gates the release in publish.yml, between `python -m build` and the artifact upload. Nothing in CI built a distribution, so the script met a real one for the first time *during a release*. That is not hypothetical: it is exactly how it shipped rejecting every real sdist. setuptools puts a second PKG-INFO inside `<pkg>.egg-info/`, the selector matched both, and the unit tests passed because their fixture wrote only one — a shape `python -m build` never produces. A verifier whose first real run is the thing it guards is not a gate. The new job builds wheel + sdist and runs the verifier against the result, so the release path is exercised on ordinary PRs instead of at tag time. Version is read as a literal from chainweaver/__init__.py, since pyproject sets `dynamic = ["version"]`. Deliberately not imported — the job installs only `build`, so a missing runtime dependency would turn a version lookup into a spurious release-gate failure. Deliberately not derived from the built filename either, which would make verify_dist's own filename check vacuous. Verified by running the job's exact sequence locally against a pristine export: `python -m build`, then the sed version read (0.14.1), then `python scripts/verify_dist.py 0.14.1` -> "verified ChainWeaver 0.14.1 wheel + sdist metadata", exit 0. With the pre-fix selector the same sequence exits 1, so the job would have caught the bug it now guards against. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
Hardens the remaining release-coherence boundaries tracked by #519 without changing package/runtime behavior.
What changed
scripts/verify_dist.pyto inspect the exact wheel and sdist built for publication before they are uploaded;METADATAand sdistPKG-INFOName/Versionagainst the intended release;chainweaver/py.typed;py.typed, and unexpected dist artifacts;Why
The repository already has strong source-level coherence checks in
scripts/release.pyand post-publish verification, and v0.14.1 successfully published to PyPI. The remaining high-value gaps in #519 were proving the built artifacts themselves match the intended version and making the publish job explicitly prove it is operating on the commit named by the release tag.This does not claim #519 is closed until CI passes and the issue's full acceptance criteria are re-audited.
Validation
Expected on this PR:
Closes #519 only after the acceptance-criteria audit confirms no remaining gap.