Release¶
A release promotes develop to main and tags the merged commit on main. The
version change and the release notes land on develop first, so the two branches
never diverge. The release tag must identify the reviewed version commit on
main. Existing tags are immutable.
Prepare the release pull request¶
- Start from an up-to-date
developand create a release branch. - Sync the locked environment and run validation:
uv sync --locked --group dev --group docs
uv run --no-sync ruff check .
uv run --no-sync ruff format --check .
uv run --no-sync ty check
uv run --no-sync pytest
uv run --no-sync zensical build --clean --strict
uv run --no-sync tox run -e build
- Preview the version change, selecting
major,minor, orpatch:
- Apply the version change without creating a tag or commit:
- Add
docs/release-notes/<version>.mddescribing user-visible changes and migration requirements. Updateuv.lockif the project metadata change requires it and verify that the locked environment remains current. Do not edit generated changelog files manually. Validate the version and nonempty release notes locally:
- Commit the version files and release notes, open a pull request against
develop, and wait for all required checks. Merge it by squashing or rebasing.
Promote develop to main¶
Open a pull request from develop to main, wait for the required checks, and
merge it with a merge commit. The merge commit is the only method main accepts:
squashing or rebasing would rewrite the promoted commits and leave develop
diverged from main. Neither branch accepts a direct push, so this pull request
is the only way a release reaches main.
Preview the release workflow¶
Run the CI-CD workflow manually with release_tag set to the prospective
version. Select the release branch to validate it before merging, or main
after the promotion. The run validates the version and release notes, runs the
checks, and uploads distributions. Manual runs never publish to PyPI, create a
GitHub release, or deploy documentation, including runs selected on a tag.
For example, after pushing the release branch:
An empty release_tag runs the ordinary validation checks for supported Python
versions. Python 3.15 CI coverage is temporarily disabled.
Tag the reviewed commit¶
Fetch the promoted main, verify its version and release notes, and create the
annotated tag using the version number without a v prefix, for example:
Use the actual release version. Push only that tag. Do not tag a release branch
commit before merging: squash or rebase merging into develop can change the
final commit. Never move or delete a published tag. Fix a release with a new
version.
Verify publication¶
The tag workflow runs validation, builds distributions, and publishes to PyPI
through the pypi environment using trusted publishing. The repository owner
must configure the PyPI trusted publisher and any environment approval policy
before the first automated publication.
Use .github/workflows/ci-cd.yml as the trusted publisher workflow filename.
Update an existing publisher registration if the workflow filename changes.
The publisher must match repository owner matthiaskoenig, repository
porous_media, workflow ci-cd.yml, and environment pypi. In particular,
replace an older registration for main.yml; GitHub settings alone cannot
update the PyPI registration.
If PyPI publication succeeds but the GitHub release step fails, rerun the failed release job using its original build artifact. Publication skips files already present on PyPI so the job can finish creating the GitHub release. Do not move the tag, rebuild different files under the same version, or delete published files to retry. A manual workflow run is a preview and does not publish.
Check the GitHub Actions release run, the GitHub release notes, and PyPI. Test the published package in a fresh environment outside the checkout:
uv venv /tmp/porous-media-release-check --python 3.14
uv pip install --python /tmp/porous-media-release-check/bin/python porous_media==0.3.1
/tmp/porous-media-release-check/bin/python -c "import porous_media; print(porous_media.__version__)"
Replace the example version and temporary path as needed. Run the documented quickstart with that interpreter to confirm the wheel includes its resources.
Citation metadata¶
After Zenodo archives a release, update CITATION.cff and the README citation
from its published record. Use the released version, publication date, and
version-specific DOI. Keep the concept DOI 10.5281/zenodo.8335487 in badges
and concept identifiers. Do not invent a DOI or update a citation before the
corresponding archive exists.