0–5 min: release inventory
Read pyproject, version source, build backend, package data rules, entry points, README, license, and current release docs.
Success checkThe current release path and metadata are visible.
Python release checklist · Updated 2026-06-27
A practical release checklist for Python libraries and CLIs so uv migration, build metadata, wheel/sdist publishing, changelog, credentials, and rollback do not break at release time.
Python toolchain migration is not complete until publishing still works. A project can run perfectly with uv locally and still fail at release time because metadata, build backends, package data, wheels, sdists, credentials, TestPyPI, dependency constraints, or changelog rules were never tested.
This checklist covers the release-specific layer after the Python Toolchain Migration Checklist. uv can manage projects and build workflows, mise can pin uv and release tools, but publishing requires its own gate: package metadata, build backend behavior, wheel and sdist inspection, TestPyPI dry run, token handling, provenance notes, rollback plan, and post-release monitoring.
RepoDaily verdict
Do not replace a Python project release path just because local uv sync works. A publish-ready migration must prove clean build artifacts, correct metadata, reproducible wheels and sdists, safe credentials, TestPyPI or dry-run validation, changelog/version alignment, and a rollback or yanked-release plan.
| Release area | What to check | Pass signal | Stop signal |
|---|---|---|---|
| Project metadata | name, version, description, license, authors, classifiers, URLs, Python requires | Metadata renders correctly and matches README/changelog | Wrong package name, stale license, unsupported Python range |
| Build backend | setuptools, hatchling, flit, poetry-core, maturin, or uv build path | Clean isolated build produces expected artifacts | Build depends on local files, hidden env, or old Poetry-only behavior |
| Wheel artifact | Wheel filename, tags, imports, package data, console scripts | Fresh venv install imports and runs CLI | Missing files, wrong tags, import failures, broken entry points |
| sdist artifact | Source contents, pyproject, tests/docs policy, generated files | sdist can rebuild wheel in isolation | sdist excludes required package data or includes secrets |
| Dependencies | Runtime deps, optional extras, upper/lower bounds, environment markers | Install works on supported Python versions and platforms | Unpinned internal deps, broken extras, incompatible markers |
| Credentials | PyPI/TestPyPI token, secret storage, CI environment, maintainer access | Token scoped and stored in CI/secret manager | Token in local shell history, repo, logs, or shared chat |
| Dry run | TestPyPI or internal index publish/install cycle | Install from published test artifact succeeds | Only local build was tested |
| Rollback | Yank/delete policy, version bump rule, hotfix owner, incident notes | Team knows when to yank, patch, or publish fix | No plan for bad release |
Score the release path before changing official publishing instructions.
| Readiness area | 0 points | 1 point | 2 points | Reviewer question |
|---|---|---|---|---|
| Metadata | Incomplete or stale | Mostly correct | Reviewed and matches docs | Will PyPI show the right story? |
| Artifacts | No artifact inspection | Wheel only checked | Wheel and sdist inspected and installed | Can a clean environment use this package? |
| CI release path | Manual laptop release | Partial CI automation | Owned CI release job with scoped secrets | Who can publish and how is it audited? |
| Dependency policy | Unknown bounds | Some version rules | Bounds/extras/markers tested | What versions and platforms are supported? |
| Dry run | None | Local build only | TestPyPI or internal index install tested | Did we test the published artifact? |
| Rollback | No plan | Informal owner | Yank/patch/notify playbook documented | What happens after a bad release? |
Use this plan before migrating a package release path to uv or CI automation.
Read pyproject, version source, build backend, package data rules, entry points, README, license, and current release docs.
Success checkThe current release path and metadata are visible.
Build wheel and sdist in a clean environment and list artifact names and contents.
Success checkBoth artifacts exist and contents look intentional.
Create a fresh environment, install from wheel or sdist, import the package, and run CLI/help or minimal function tests.
Success checkThe installed artifact works without source checkout assumptions.
Validate upload credentials and publish/install through TestPyPI or staging where possible.
Success checkThe published artifact can be installed from an index.
Decide migrate, keep old path, patch metadata, test longer, or assign release owner and rollback plan.
Success checkThe next release step has owner, evidence, and rollback path.
| Scenario | Release pattern | Extra guardrail |
|---|---|---|
| Pure Python library | Build wheel and sdist, inspect metadata, install both artifacts, run import smoke test | Check Python version range and dependency markers |
| Python CLI tool | Verify console script entry points and fresh venv command execution | Run help/version command from installed wheel |
| Package with data files | Inspect wheel/sdist contents for package data and exclusions | Confirm no private data or generated junk is included |
| Native extension or Rust-backed package | Build platform-specific artifacts and test tags | Use platform matrix or release tooling owner review |
| Internal package index | Publish to internal dry-run or staging index first | Validate credentials, index URL, and dependency resolution |
| Poetry-to-uv migration | Keep existing release path until build/publish parity is proven | Compare metadata and artifact contents before switching |
| Emergency hotfix | Patch version, minimal diff, clean artifact, install smoke test, publish, monitor | Do not reuse a broken version number |
A package can import locally because source paths are on disk. Test installed artifacts from wheel and sdist.
Package metadata, README, changelog, license, and Python support can disagree unless reviewed together.
Wheel-only testing can hide missing source files. A good sdist should rebuild the wheel in isolation.
Publishing tokens should be scoped and stored in CI or a secret manager, never committed or pasted into chat.
Once a version is published, reusing it is usually unsafe. Define patch/yank behavior before release.
Loose or wrong dependency bounds can break downstream users after install, not during local tests.
Use a clean environment or CI job so hidden local files and editable installs cannot mask packaging problems.
List wheel and sdist contents and check metadata before uploading to any index.
Run smoke tests against the built/published artifact, not the source checkout.
Use a dry-run index when feasible to validate upload and install behavior.
Use mise to pin uv, Python, twine, or other release tools when releases must be reproducible.
Every release PR should record version, changelog, artifacts tested, credentials path, publisher, and rollback owner.
Short answers for Python maintainers publishing packages after toolchain migration.
No. uv can support build and project workflows, but release policy still needs artifact inspection, credentials, dry run, changelog, and rollback rules.
Yes for published packages. Wheel and sdist failures differ, and downstream users may depend on either path.
Use it to validate upload/install behavior and metadata rendering before publishing a real public release.
Do not rely on overwriting. Use a new version, yank when appropriate, publish a fix, and document the incident.
Feedback
Anonymous feedback helps RepoDaily improve what is actually useful.