Releasing torchregress¶
This guide describes how to publish a new version of torchregress to PyPI.
Publishing is fully automated in GitHub Actions after you push an annotated release tag. Local scripts handle version bumps, validation, and tagging.
Overview¶
- Run
./scripts/release/prepare_release.shlocally. - Push
mainand the new tagvX.Y.Z. - GitHub Actions builds the package, checks its contents and metadata, installs the wheel with core dependencies only on Linux and macOS for Python 3.12–3.14, and then publishes to PyPI via Trusted Publishing.
See also scripts/release/README.md for command-level reference.
One-time setup¶
1. Configure PyPI Trusted Publishing¶
In the torchregress project settings on PyPI:
https://pypi.org/manage/project/torchregress/settings/publishing/
Add a GitHub trusted publisher with:
| Field | Value |
|---|---|
| Owner | astroai |
| Repository | torchregress |
| Workflow name | release.yml |
| Environment name | pypi |
No long-lived PyPI API token is required in GitHub secrets when Trusted Publishing is configured.
Before the first upload the project does not exist on PyPI yet: add the same values as a
pending publisher under Your account → Publishing. Do the same on TestPyPI
(https://test.pypi.org) for release-candidate dry runs.
2. Create the GitHub pypi and testpypi environments¶
In the GitHub repository:
Settings → Environments → New environment → pypi (and again for testpypi)
Tags vX.Y.ZaN, vX.Y.ZbN, and vX.Y.ZrcN publish to TestPyPI through the testpypi environment; tags vX.Y.Z
publish to PyPI through pypi. A TestPyPI trusted publisher with the same owner,
repository and workflow, and environment testpypi, is needed for the dry run.
Recommended protection rules:
- Required reviewers before deployment (optional but recommended for production releases)
- Deployment branches and tags: allow tags matching
v*(the release job runs on tag pushes, not onmain)
The workflow job in .github/workflows/release.yml uses
environment: pypi and permissions.id-token: write, which are required for OIDC-based
publishing with GitHub Actions OIDC (pypa/gh-action-pypi-publish).
3. Turn on GitHub Pages for the docs¶
Settings → Pages → Source: GitHub Actions. The Docs workflow
(.github/workflows/docs.yml) then publishes https://astroai.github.io/torchregress/
on every push to main. The README, pyproject.toml and the PyPI page link there.
First release (0.3.0): dry run on TestPyPI first¶
- Finish the one-time setup above, including the TestPyPI pending publisher.
- Move the
[Unreleased]notes inCHANGELOG.mdunder## [0.3.0] - <date>. - Prepare a release candidate and push it:
./scripts/release/prepare_release.sh --version 0.3.0b1
git push origin main && git push origin v0.3.0b1
- Watch Actions → Release:
build, the sixinstall-smokelegs, thenpublish-testpypi. - Install from TestPyPI in a clean environment (dependencies come from PyPI):
python -m venv /tmp/tr && . /tmp/tr/bin/activate
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ torchregress==0.3.0b1
torchregress-health
- Run the local CUDA tests on the candidate (
pixi run -e cuda test-cudaon a GPU machine). - Release:
./scripts/release/prepare_release.sh --version 0.3.0, pushmainandv0.3.0.
Release checklist¶
1. Prepare the release locally¶
From a clean working tree on main:
Other forms:
./scripts/release/prepare_release.sh minor
./scripts/release/prepare_release.sh major
./scripts/release/prepare_release.sh --version 1.0.0
./scripts/release/prepare_release.sh --dry-run patch
prepare_release.sh will:
- Bump
versioninpyproject.toml - Run
scripts/ci_local.sh(CI parity checks) - Build and validate artifacts with
scripts/release/build_package.sh - Verify tag/version alignment
- Commit
Release vX.Y.Z - Create annotated tag
vX.Y.Z
2. Push main and the tag¶
Pushing the tag triggers the release workflow.
3. Verify the release¶
- Open Actions → Release and confirm the workflow succeeded.
- Download the uploaded
distartifact if you want to inspect the built files. - Confirm the new version on PyPI: https://pypi.org/project/torchregress/
Version source of truth¶
- Canonical version:
versioninpyproject.toml - Runtime version:
torchregress.__version__from installed package metadata - Release tags must match exactly: tag
v1.2.3↔version = "1.2.3"
scripts/release/verify_version.py enforces this in CI.
Troubleshooting¶
Trusted Publishing failed¶
Common causes:
- PyPI trusted publisher workflow/environment mismatch
- Missing
id-token: writepermission on the publish job - Tag/version mismatch between git tag and
pyproject.toml
For clearer OIDC errors during setup, the release workflow uses
pypa/gh-action-pypi-publish with id-token: write.
Tag pushed but version not bumped on main¶
The tag must point to a commit whose pyproject.toml version matches the tag. Use
prepare_release.sh so the commit and tag are created together.
Local build validation¶
build_package.sh checks the archives with scripts/release/check_dist.py
(no build or tooling output, py.typed and LICENSE present, matching versions).
To repeat the CI install check by hand:
python -m venv /tmp/tr && /tmp/tr/bin/pip install dist/*.whl
cd /tmp && /tmp/tr/bin/python <repo>/scripts/release/smoke_install.py
Manual version bump only¶
pixi run python scripts/release/bump_version.py patch
pixi run python scripts/release/verify_version.py --tag vX.Y.Z
What is intentionally not automated here¶
- CHANGELOG generation
- GitHub Release notes
- TestPyPI dry-run publishing
These can be added later if needed.