Packaging and Distribution#
PythTB is distributed on PyPI and conda-forge. This guide outlines how to maintain and publish new versions through both channels.
It covers:
Dependency management (pyproject.toml)
Versioning guidelines
Pre-release checks
Releasing on PyPI
Releasing on conda-forge through the feedstock
pyproject.toml#
The project’s pyproject.toml defines:
Build backend configuration
Package metadata (name, version, author, license, description)
Package dependencies (with optional groups)
It is required for modern Python packaging and ensures tools such as pip, PyPI, and conda-forge can build the package from source. See this guide for information on writing pyproject.toml.
Versioning#
PythTB follows Semantic Versioning. Versions are in the format X.Y.Z where:
Type |
Example |
Reason |
|---|---|---|
PATCH |
X.Y.Z → X.Y.Z+1 |
Bugfixes only |
MINOR |
X.Y.Z → X.Y+1.0 |
New features, no breaking changes |
MAJOR |
X.Y.Z → X+1.0.0 |
Breaking API changes |
Pre-release checklist#
Tests pass
pytest -n auto
Documentation builds cleanly (no warnings or errors)
sphinx-build docs/source docs/build/html
Version number updated in
pythtb/__init__.pyCHANGELOG.mdupdatedRelease notes added
Add release notes in
docs/source/release/and update toctree indocs/source/release.md
Once all of the changes are in place, we can proceed to release.
Releasing on PyPI#
Our releases are driven by GitHub Actions plus PyPI Trusted Publishing. No long-lived PyPI token exists in the repository (or on contributor machines); instead the workflow requests a short-lived token via OIDC and targets the protected pypi-prod environment. Because only release managers can push tags to the upstream repo and approve that environment, accidental or manual uploads are effectively prevented.
Commit the version bump, changelog, and release notes:
git commit -m "Release X.Y.Z"
Create an annotated tag that matches either the stable (
vX.Y.Z) or pre-release (vX.Y.ZrcN) pattern:git tag vX.Y.Z
Push the branch and tag:
git push git push --tags
Monitor the
Publish to PyPI (Trusted Publishing)workflow for stable tags orPublish to TestPyPIfor RC tags. GitHub will pause the job until an approver for thepypi-prodenvironment approves the deployment step. Once approved,pypa/gh-action-pypi-publishbuilds the sdist/wheel, runstwine check, and uploads them using Trusted Publishing.
Additional notes:
RC tags (
vX.Y.ZrcN) land on TestPyPI via.github/workflows/testpypi-publish.yml. Stable tags go straight to PyPI via.github/workflows/pypi-publish.yml.Both workflows can be re-run via Re-run failed jobs or
workflow_dispatchin GitHub’s UI; re-running reuses the same tag so nothing new needs to be pushed.Because we do not mint PyPI API tokens for local use, nobody can
twine uploadmanually unless the PyPI owners deliberately create and share a token for an emergency.
Manual fallback (only if automation cannot publish)#
In the rare case that PyPI is down or Trusted Publishing is temporarily unavailable, coordinate with the PyPI project owners to obtain a temporary API token and then follow the commands below. Clean up any locally stored credentials afterwards.
Build distribution artifacts#
pip install build
python -m build
This creates dist/ with:
dist/
pythtb-X.Y.Z.tar.gz
pythtb-X.Y.Z-py3-none-any.whl
Upload to PyPI#
First do a test upload to TestPyPI:
pip install twine
twine upload dist/* -r testpypi
Test the installation from TestPyPI:
pip install -i https://test.pypi.org/simple/ pythtb==X.Y.Z
Then upload to the real PyPI:
twine upload dist/*
Verify the release appears at https://pypi.org/project/pythtb/. Remove any temporary API tokens when finished.
Releasing on conda-forge#
PythTB is maintained on conda-forge via its feedstock repository (See conda-forge documentation for more details.)
The conda-forge bot usually:
Detects the new PyPI release
Opens a version-bump PR
Updates SHA + metadata
If the bot does not trigger, update manually.
Open feedstock
Navigate to the feedstock at conda-forge/pythtb-feedstock
Fork + clone
Create your own fork of the feedstock, clone it to your computer.
Create branch and make changes
Update version
Update SHA256 from PyPI
Reset
build:number to 0 when shipping a new versionIncrement
build:number when metadata changes without version bump
Create PR
Push changes and create a pull request to the original upstream feedstock.
Rerender
Comment on PR
@conda-forge-admin, please rerender
Or run locally:
conda install -c conda-forge conda-smithy
conda-smithy rerender
Post-release steps#
Add folder in docs/_static/versions/vX.Y.Z for the new version. Add the pythtb-X.Y.Z.tar.gz file there.
To get the .tar.gz file you can either download it from PyPI or create it locally by doing:
Make a release on GitHub
Go to the Releases page and click “Draft a new release”
Select the tag version
Copy the release notes from
docs/source/release/X.Y.Z-notes.mdinto the GitHub release descriptionPublish the release
Download the source code
.tar.gzfrom the GitHub release page.
Update the
docs/source/install.mdfile to include downloadable.tar.gz.
Update
docs/source/index.mdto highlight the new release.Update Zenodo record with new version.
Announce the new release on relevant channels.