Skip to content

add a release workflow - #54

Merged
ThomasWaldmann merged 1 commit into
mainfrom
release-workflow
Aug 18, 2026
Merged

add a release workflow#54
ThomasWaldmann merged 1 commit into
mainfrom
release-workflow

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Releasing borghash was fully manual so far: python -m build and twine upload on the maintainer machine, with a PyPI API token. This adds .github/workflows/release.yml, triggered by pushing a release tag, so that a release is just "update CHANGES, merge, tag, push".

The workflow has two jobs:

  • release: cythonizes and builds the sdist, twine checks it, checks that the sdist really is the one for the pushed tag (a missing or unfetched tag would silently give a setuptools-scm dev version), installs it into a clean venv and runs the test suite plus borghash-demo against that installation, then drafts the GitHub release with the sdist attached. It is a draft because the release notes want a human; a re-run replaces the assets instead of failing.
  • pypi: uploads that same sdist to PyPI via trusted publishing, so no API token is stored anywhere. It is a separate job so that the pypi environment gate applies to the irreversible step alone.

No wheels: borghash is a Cython extension, and only the sdist has ever been published. The sdist install check is the release gate here - ci.yml does not run on a tag push, and nothing else ever installs borghash from a sdist.

The sdist must be cythonized before python -m build runs: the .c files are not in git and Cython is not in build-system.requires, so the isolated build environment cannot cythonize. ci.yml already does it in that order.

Actions are pinned to commit SHAs.

README.rst gets a "Making a release" section describing the procedure.

One-time setup needed before the first release

  1. On pypi.org, add a trusted publisher to the borghash project: owner borgbackup, repository borghash, workflow release.yml, environment pypi.
  2. Create the pypi environment in the repository settings. Nothing in it is required, but configuring required reviewers makes the upload wait for an approval - the last chance to stop a release. "Prevent self-review" has to stay off for that to be approvable by the person who tagged.

Testing

Verified locally against a clean clone at tag 0.2.0, with the exact package set and Python version the workflow uses: build, twine check, install into a fresh venv without Cython, 66 tests pass, borghash-demo runs. The version guard was checked both ways (a dev-version sdist fails it). The release-drafting shell logic was exercised with gh stubbed: the create path, the --prerelease path for a b1 tag, and the upload --clobber re-run path.

Not provable without a real tag: the artifact hand-off between the two jobs and the PyPI upload itself.

Pushing a release tag now builds the sdist, checks that it is complete and
installable, drafts the GitHub release with it and uploads it to PyPI via
trusted publishing.
@ThomasWaldmann
ThomasWaldmann merged commit a0c5df3 into main Aug 18, 2026
3 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the release-workflow branch August 18, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant