Release for Pypi¶
The package is built and uploaded to PyPI by the CI GitHub workflow
(.github/workflows/ci.yml) when a version tag is pushed. The upload
uses PyPI trusted publishing: PyPI trusts the OpenID Connect token issued
by GitHub to the publish job, so no API token or password is stored
anywhere.
Release from GitHub Actions¶
Update the version number in the
pibooth/__init__.pyfile. It is the only place where the version is declared:setup.pyimports it, and thedownload_urlis built from it, so the git tag must match it exactly.Merge the pull request carrying the new version into
master. Thebuildandpackagejobs of the workflow run on the pull request: they run the tests, build the source distribution and the wheel, check them withtwineand install the wheel in a clean environment.Tag the merge commit with exactly the version set in step 1 and push the tag:
$ git checkout master $ git pull $ git tag <version> $ git push origin <version>
The workflow runs again on the tag. Once the
buildandpackagejobs are green, thepublishjob checks that the packaged version is the tag name and waits for a manual approval.Approve the deployment: open the workflow run in the Actions tab of the repository, click on Review deployments, tick the
pypienvironment and Approve and deploy. The job then uploadsdist/*to PyPI.Warning
This step is irreversible: a version number can never be reused on PyPI. If the run fails after the upload, or if something is wrong with the release, bump the version and start again.
Write the release notes on GitHub (Releases → Draft a new release, pick the pushed tag).
Note
The publish job relies on two settings of the project, to redo
if the workflow file or the environment is renamed: on PyPI, a
GitHub trusted publisher for pibooth/pibooth, workflow
ci.yml, environment pypi; on GitHub, the pypi
environment with required reviewers.
Manual release (fallback)¶
If the workflow can not be used, the package can still be built and uploaded from a development machine. It requires a PyPI API token.
Create a virtual environment and install the packaging tools in it:
$ python3 -m venv /tmp/release-venv $ /tmp/release-venv/bin/pip install build twine
Note
Installing them system-wide with
sudo pip installfails on recent distributions, which mark the system Python as externally managed (PEP 668).Update the version number in the
pibooth/__init__.pyfile, as in the automated procedure.Clean previous packages (avoid upload of an older package):
$ rm -rf build/ dist/ pibooth.egg-info/
Generate the package:
$ /tmp/release-venv/bin/python -m build .
Warning
Do not use
python setup.py bdist_wheel. Direct invocation ofsetup.pyis deprecated and now fails with recent versions ofsetuptools.Check the package integrity. This also validates that the reStructuredText
long_descriptionrenders correctly, which PyPI rejects otherwise:$ /tmp/release-venv/bin/twine check --strict dist/*
Check that the built package actually installs and starts, in a clean environment. This is what catches a broken dependency pin before the users do:
$ python3 -m venv /tmp/install-check $ /tmp/install-check/bin/pip install dist/pibooth-*.whl $ SDL_VIDEODRIVER=dummy /tmp/install-check/bin/pibooth --reset /tmp/cfg-check
Upload the package on PyPI:
$ /tmp/release-venv/bin/twine upload dist/*
PyPI no longer accepts account passwords: authentication requires an API token, used as the password with
__token__as the username.twineprompts for it, or reads it from~/.pypircor theTWINE_USERNAME/TWINE_PASSWORDenvironment variables.Warning
This step is irreversible: a version number can never be reused on PyPI.
Tag the release and push the tag, using exactly the version set in step 2:
$ git tag <version> $ git push origin <version>
Note
Pushing the tag still triggers the
publishjob, which waits for the approval of thepypienvironment. The package being already on PyPI, reject the deployment. Without a required reviewer the job runs and fails on the duplicate upload, which is harmless.