PyPI releases are immutable. If a published artifact is wrong, fix the source and publish a new patch version; never move or recreate an existing release tag.
The checks below are release evidence, not proof of a live backend deployment. They apply when preparing a release and do not block research branches or ordinary commits.
-
pyproject.tomlcontainsversion = "X.Y.Z". -
src/spooled/_version.pyuses installed package metadata and its source-checkout fallback is exactlyX.Y.Z. -
uv.lockrecords the localspooledpackage asX.Y.Z; regenerate it after any package metadata or dependency-floor change. - The default REST user-agent is
spooled-python/X.Y.Zand derives from the canonical package version rather than an independent literal. - Sync worker, async worker, direct
SpooledWorkerOptions, and gRPC worker registration all default to the canonical package version. -
CHANGELOG.mdcontains## [X.Y.Z] - YYYY-MM-DD. - Release-specific version references in
README.md,docs/, and release-contract tests are synchronized or intentionally version-neutral. -
uv lock --check, lint, type checks, unit tests, build, andtwine check dist/*succeed. - Checked-in protobuf/gRPC stubs are regenerated from
proto/spooled.protowith the locked tools and produce no unexpected diff. - Declared
grpcioandprotobuffloors satisfy the runtime versions embedded in the generated stubs. - A clean install of the built wheel reports
spooled.__version__ == "X.Y.Z", sendsspooled-python/X.Y.Z, and imports the generated gRPC modules.
The release-contract tests derive their expected release from pyproject.toml; do not add a second hardcoded expected version to those assertions.
- The release commit is final; create
vX.Y.Zonce and do not move it. - The GitHub Release targets the same commit as
vX.Y.Z. - PyPI lists both wheel and sdist for
X.Y.Z. - PyPI Trusted Publisher provenance names this repository,
publish.yml,refs/tags/vX.Y.Z, and the expected commit. - Artifact SHA-256 values and upload time are recorded in the release evidence.
- A clean environment installs
spooled[all]==X.Y.Zfrom PyPI and repeats the version, user-agent, worker-registration, and gRPC import smoke checks.
.github/workflows/publish.yml is triggered only by a published GitHub Release. Its strict tag and release-metadata checks therefore do not run for normal pushes or pull requests. Normal development remains governed by .github/workflows/ci.yml.