-
Notifications
You must be signed in to change notification settings - Fork 1
Releasing
How to cut a new openbadgeslib release: bump the version in the source, update the changelog, tag, and let CI publish to PyPI. This is for maintainers; see Contributing for the day-to-day development workflow.
The version is single-sourced from openbadgeslib/util.py (__version__).
pyproject.toml reads it dynamically ([tool.setuptools.dynamic]) and
docs/conf.py parses the same file, so you only ever edit one place. The
test_version_is_single_sourced test fails CI if a static version is
reintroduced.
Replace X.Y.Z with the new version throughout.
-
Bump the version in
openbadgeslib/util.py(__version__). That is the only place to edit.python -c "import openbadgeslib.util as u; print(u.__version__)" -
Add a
Changelog.txtentry. Entries are newest-first; follow the existing format (* vX.Y.Z - YYYY-MM-DDheader, then-dash-prefixed bullets, withSECURITY:markers on security-relevant lines):* vX.Y.Z - 2026-06-27 - Short description of each change.README.mdlinks toChangelog.txtrather than duplicating it, so there is nothing to mirror there. -
Run the checks locally before tagging — CI runs the same
flake8+pytestgate (see Contributing):pip install -e ".[dev]" flake8 openbadgeslib tests pytest --cov=openbadgeslib --cov-report=term-missing -
Commit the version bump and changelog:
git add openbadgeslib/util.py Changelog.txt git commit -m "Release vX.Y.Z" git push origin master -
Tag the release with an annotated tag and push it:
git tag -a vX.Y.Z -m "openbadgeslib vX.Y.Z" git push origin vX.Y.Z -
Create the GitHub Release. Draft a Release for the
vX.Y.Ztag (Releases → Draft a new release, orgh release create) and Publish it. Publishing — not merely tagging — is what triggers the upload to PyPI.gh release create vX.Y.Z --title "vX.Y.Z" --notes-file -
The workflow is .github/workflows/ci.yml. It has two jobs:
-
test runs on every
pushtomasterand every pull request, across the Python3.10,3.11,3.12, and3.13matrix (fail-fast: false). Each leg installs".[dev]", runsflake8 openbadgeslib tests, thenpytest --cov. -
publish runs when a GitHub Release is published or the workflow is
triggered manually (
workflow_dispatch), andneeds: test, so it runs only if the whole test matrix passed. It builds the sdist and wheel withpython -m buildand uploads them to PyPI viapypa/gh-action-pypi-publish.
publish:
needs: test
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'This means: tagging alone does nothing; a Release whose tests fail will not
publish; and you can publish the current master on demand from
Actions → CI → Run workflow (or gh workflow run ci.yml).
The publish job authenticates with secrets.PYPI_API_TOKEN:
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}This must exist as a repository (or environment) secret named PYPI_API_TOKEN, holding a PyPI API token scoped to the openbadgeslib project. If it is missing or expired the upload step fails even when every test passes. Rotate it in PyPI and update the GitHub secret when needed — the token never lives in the repo.
- Confirm the publish job is green in the Actions tab.
- Confirm the new version appears on PyPI and installs cleanly:
pip install openbadgeslib==X.Y.Z. - Confirm
python -c "import openbadgeslib.util as u; print(u.__version__)"reportsX.Y.Zfrom the published wheel.
openbadgeslib · LGPLv3 (library) / BSD (CLI) · Issues
Getting Started
Concepts
Reference
Guides
Project