release: verify the published package before announcing it - #185
Merged
villelaitila merged 1 commit intoAug 24, 2026
Merged
Conversation
twine reports success when PyPI accepts the bytes. That says nothing about whether the distribution installs, imports, or contains the subpackages it claims to -- so a packaging misconfiguration shipped silently and was discovered by a user rather than by the release that caused it. The release of 1.13.0 published and announced without ever asking whether what it published worked. Phase 2 now installs sgraph==<version> from PyPI into a throwaway virtualenv, imports it, and compares the subpackages that shipped against those in src/sgraph. Only absence is a defect: a distribution containing more than the source tree lists is a question for a human, not grounds for aborting a release that has already happened. It runs between the upload and the GitHub release. It cannot prevent the upload -- nothing can, which is the whole reason the upload asks for confirmation -- but it can stop a broken artifact from being announced, and the tag is already public by then, so the earlier position buys nothing. --no-cache-dir is load-bearing rather than hygienic, and a test asserts it so it cannot be tidied away by someone who has not seen the failure. The distribution reaches PyPI seconds before this step runs, so a cached index page predates it and resolves the new version to "no such version" -- a false report of a failed upload. This bit during the 1.13.0 release: a clean-venv check reported "No solution found" until the index was re-fetched. For the same reason the install retries on a fixed schedule, since PyPI serves an upload before every index replica reflects it, and failing on the first attempt would report ordinary propagation lag as a broken release. --skip-verification exists for an unavailable network and says in its own help text that it removes the only check that what reached PyPI is usable. Validated against the live 1.13.0 release rather than only against mocks: the success path reports all eight subpackages present, a nonexistent version retries and raises ReleaseError, and the skip flag performs no network work. The existing ordering test pinned the exact call sequence and was updated rather than loosened -- that pin is what makes the position of this step a fact instead of an intention.
Softagram Impact Report for pull/185 (head commit: 0cd0279)TL;DR Arch. Impact: -10 | Changed code files: 3 | Directly impacted code files: 0⭐ Change Overview
⭐ Details of Dependency Changes (diagram)
🤖 AGENTS - machine-readable impact data (3 files changed, 0 impacted, +20/-0 deps)Change overviewHead Added dependencies (19)
Removed dependencies (0)None. Impacted files (0)None. Complete data
[] 📄 Full report
Impact Report explained. Give feedback on this report to support@softagram.com |
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.


twinereports success when PyPI accepts the bytes — which says nothing about whether the distribution installs or contains what it claims to. Phase 2 now checks.What it does. Installs
sgraph==<version>from PyPI into a throwaway virtualenv, imports it, and compares the shipped subpackages against those insrc/sgraph. Only absence is a defect. Runs between the upload and the GitHub release: it cannot prevent the upload, but it can stop a broken artifact from being announced.--no-cache-diris load-bearing, and a test asserts it. The distribution reaches PyPI seconds before this step runs, so a cached index page predates it and resolves the new version to "no such version" — a false report of a failed upload. This actually bit during the 1.13.0 release. The install also retries on a fixed schedule, since PyPI serves an upload before every index replica reflects it.--skip-verificationopts out for an unavailable network.Validated against the live 1.13.0 release, not only against mocks — success path reports all 8 subpackages, a nonexistent version retries then raises, the skip flag does no network work. 485 tests pass (474 + 11); flake8 on
scripts/release.py15 → 14.