Skip to content

Latest commit

 

History

History
112 lines (73 loc) · 4.64 KB

File metadata and controls

112 lines (73 loc) · 4.64 KB

Releasing

Releases are built from a clean, version-aligned tag and published only after artifact validation. The current release tag is v1.3.3.

1. Prepare metadata

Before tagging:

  1. update src/python_extensions/_version.py;
  2. update CHANGELOG.md and docs/RELEASE_NOTES.md;
  3. synchronize README, support/security, citation, compatibility, and maintainer metadata that actually depend on the release version;
  4. add new benchmark/certification evidence only when its provenance changes—do not rewrite historical evidence to match a newer version;
  5. verify pyproject.toml, CITATION.cff, and LICENSE agree on the current license;
  6. run full runtime diagnostics and relevant stress/differential qualification.

Local gates:

python tools/check_repo.py
python -m compileall -q src tests tools benchmarks/scripts
python -m pytest
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -X dev -W error -m pytest

2. Validate release metadata

Install release tooling without installing the local project first:

python tools/install_dependencies.py \
  --include-build-system \
  --include-runtime \
  --upgrade build test
python tools/check_metadata.py

Installing the local project before clean-tree preflight can create build/ or *.egg-info output and correctly make the repository dirty.

3. Build reproducibly

Use the release commit timestamp as SOURCE_DATE_EPOCH input to the project build helper:

EPOCH=$(git show -s --format=%ct HEAD)
python tools/build_release.py --out-dir dist --epoch "$EPOCH"

PowerShell:

$epoch = git show -s --format=%ct HEAD
python tools/build_release.py --out-dir dist --epoch $epoch

The local helper emits an sdist, host-native wheel, and checksum manifest. On Linux, a raw linux_x86_64 wheel is an internal build product and is not publishable to PyPI.

The tagged GitHub workflow rebuilds from the canonical sdist in manylinux, verifies reproducibility, checks metadata, installs/smokes the exact wheel, reproduces the exact sdist, and stages only publishable distributions.

4. Validate artifacts

Twine validates Python distributions, not the checksum file:

python -m twine check dist/*.whl dist/*.tar.gz

For a release candidate, verify final checksums and test the exact artifacts that will be attached/published rather than rebuilding a different copy for smoke tests.

5. Tag

The stable tag must exactly match the package version:

git tag -s v1.3.3 -m "cpython-extensions 1.3.3"
git push origin v1.3.3

If signing is not configured, use an annotated tag (git tag -a).

Do not move or overwrite a pushed stable tag. If a stable tag is wrong, fix the source, increment the package version, and create a new tag.

Preview tags

Preview labels (alpha, beta, rc, preview, test, optionally numbered) can exercise the build/GitHub-prerelease path without entering PyPI publication.

git tag -a v1.3.3-rc1 -m "cpython-extensions 1.3.3 release candidate"
git push origin v1.3.3-rc1

6. GitHub Release behavior

Stable tags create normal releases; preview tags create prereleases. The workflow attaches the already-validated wheel, sdist, and SHA256SUMS.txt.

Release creation is idempotent for matching assets. A stable asset whose bytes differ from newly certified output is a hard failure rather than something to overwrite silently.

7. PyPI Trusted Publishing

Stable tags can enter the protected pypi environment after artifact/GitHub Release validation. Publishing uses GitHub OIDC (id-token: write) and should not require a stored PyPI API token.

Configure the PyPI Trusted Publisher for Karvp/cpython-extensions and ensure required environment reviewers/protection rules are satisfiable by the release process.

Only *.whl and *.tar.gz are staged to the PyPI publishing directory. The checksum manifest remains a GitHub Release integrity artifact.

8. Failure recovery

  • Tag/version mismatch before build: do not rerun the bad stable tag; fix source metadata, increment the version, and create a new stable tag.
  • Preview release failure: repair/recreate the preview as allowed by the workflow and rerun validation.
  • Stable GitHub Release already exists: never replace a differing stable asset; investigate and publish a new version if bytes must change.
  • PyPI upload failure: first determine whether PyPI accepted any file. Published files are immutable; if any artifact for the version was accepted, do not attempt to replace it.

Keep workflow permissions explicit and scoped: artifact readers need actions: read, GitHub Release creation needs contents: write, and PyPI OIDC needs id-token: write only in the publishing job.