Versioning and Releases
This page documents the versioning strategy and the steps required to cut a release of OpenBook.
Versioning Strategy
OpenBook follows Semantic Versioning
(SemVer). Given a version number MAJOR.MINOR.PATCH:
PATCH is incremented for backward-compatible bug fixes.
MINOR is incremented for backward-compatible new features.
MAJOR is incremented for breaking changes to the public API.
There are currently no plans to introduce breaking changes. Users can safely update to any patch or minor release without modifying their code.
Release Checklist
Ensure main is green.
All CI checks must pass before tagging.
Create release issue (recommended).
Create a new issue for the release and describe any remaining work to be done before a new version is released. You do not need to repeat the individual release steps, only what else needs to be done.
Align release planning on the GitHub Project board.
Check the planning board on GitHub to make sure that there are no open issues left for the release. If needed, move issues to the next development cycle.
Create new branch.
From within the release issue, create a new release preparation branch. Check out the branch, as the next steps must all be performed within that branch.
Complete remaining work.
If there is any remaining work to be done (e.g., updating documentation), push the changes onto the release preparation branch.
Update the changelog.
Add a dated entry to Changelog summarising user-visible changes. See Changelog Format below for the expected format.
Bump the version number in
pyproject.tomlusing Poetry:# choose one of: patch, minor, major poetry version minor
Commit the version bump:
git add pyproject.toml docs/administrators/changelog.rst git commit -m "Bump version: vX.Y.Z"
Open and merge pull request.
Now open a pull request to merge the release preparation branch into main. At this stage, Copilot will review the branch, code quality and security will be scanned, documentation will be built, and unit tests will run. Usually, you will need to push a few more commits to the release branch (which will automatically appear in the PR and retrigger quality checks).
Once all is green, merge the pull request into main.
Tag the commit in order to trigger the release workflow.
Checkout the main branch and create a signed annotated tag for the merge commit, then push the tag to GitHub:
git checkout main git pull git tag -s vX.Y.Z -m "Release vX.Y.Z" git push origin --tagsThe
.github/workflows/release.ymlworkflow will automatically:
Verify the tag is a signed annotated tag with a valid signature
Verify the tag version matches
pyproject.tomlRun the full test suite and build the documentation again (for safety)
Build a versioned source archive artifact (
.tar.gz)Generate a CycloneDX SBOM (
sbom.cyclonedx.json)Create a GitHub release with release notes extracted from the changelog
Create a release branch for hotfixes (if the release is not a pre-release)
Monitor the workflow run in the Actions tab.
Update website content.
Ensure release-related website pages are updated as required.
Changelog Format
The changelog is located in docs/administrators/changelog.rst and uses
reStructuredText (RST) formatting. Each version entry must follow this structure,
allowing the release workflow to extract the changelog entries for the GitHub
release page.
X.Y.Z (Month Year)
^^^^^^^^^^^^^^^^^^
- Change 1
- Change 2
- Change 3
Guidelines
Use the exact version number (e.g.,
2.1.0) without thevprefix.Add the release date in parentheses (e.g.,
(April 2026)).Add an underline using
^characters of the same length.List changes as bullet points with clear, user-facing descriptions.
Start descriptions with the affected component.
Group related changes together logically.
Pre-releases
For pre-release versions (alpha, beta, release candidate), use the extended version format in the tag and changelog:
git tag v2.1.0-pre1
git tag v2.1.0-rc1
Update the changelog accordingly:
0.0.1-pre1 (April 2026)
^^^^^^^^^^^^^^^^^^^^^^^
- Preview of upcoming features...
The release workflow will automatically detect pre-releases and mark them as such in GitHub.
Tag Signing
Setup
Release tags must be signed. If tag signing is not configured locally, set it up once before creating your next release:
# Use your existing GPG key ID
git config --global user.signingkey <YOUR_GPG_KEY_ID>
git config --global tag.gpgSign true
To list available secret keys and find your key ID:
gpg --list-secret-keys --keyid-format=long
Only signed annotated tags (git tag -s) are accepted by the release workflow.
Signing commits is also recommended as a general repository security practice, but commit signing is currently not enforced by the release workflow.
Troubleshooting
If the release workflow rejects a signed tag with a reason such as bad_email,
inspect the tag metadata first:
git cat-file -p <tag>
Look for the tagger line, for example:
tagger Name <email@example.com> ...
When you create a signed tag with git tag -s, Git embeds the tagger identity from your local Git configuration. That email address must:
Be present in your GitHub account
Be verified in GitHub
Match exactly, including casing
A common failure mode is that GitHub has multiple verified email addresses, but
Git is using the wrong one via user.email. This matters because Git uses
that email for the tagger identity, while GPG signs with a key that is usually
associated with specific UID email addresses. If the tagger email and the
verified GitHub identity do not align, GitHub tag verification can fail.
To fix this, delete the incorrect tag locally and remotely, correct your Git identity, then recreate and push the signed tag:
git tag -d <tag>
git push origin :refs/tags/<tag>
git config user.email <correct-verified-email>
git tag -s <tag>
git push origin <tag>
Read the Docs
Documentation is rebuilt automatically on every push to main and on every
tag that matches the v* pattern. No manual trigger is needed after pushing
a release tag. See Repository Setup for details of the Read
the Docs project settings and automation rules.