Codeband is published to PyPI as codeband
under the Band PyPI org. Releases are cut by
pushing a vX.Y.Z tag; GitHub Actions builds the sdist and wheel and uploads
them to PyPI via Trusted Publishing (OIDC, no API tokens stored).
Done once by a maintainer with admin access to the Band PyPI org.
- Sign in to https://pypi.org as a member of the Band org.
- Go to Your account → Publishing → Add a pending publisher (use a
pending publisher because the
codebandproject does not exist on PyPI yet — the first successful publish creates it under the org). - Fill in:
- PyPI Project Name:
codeband - Owner:
thenvoi - Repository name:
codeband - Workflow name:
publish.yml - Environment name:
release
- PyPI Project Name:
After the first release, the project will appear under https://pypi.org/manage/project/codeband/. Future trusted-publisher edits live under the project's Publishing tab.
Done once on the thenvoi/codeband repo.
- Settings → Environments → New environment → name it
release. - (Optional, recommended) Restrict the environment to protected tags matching
v*so only maintainers can trigger a publish.
- Bump the version in two places — the publish workflow fails the build if
they drift:
pyproject.toml→[project] versionsrc/codeband/__init__.py→__version__
- Update
CHANGELOG.md: rename theUnreleasedsection to the new version and add a freshUnreleasedheading on top. - Commit and push to
main. - Tag and push:
git tag -a v0.1.0 -m "v0.1.0" git push origin v0.1.0 - Watch the Publish to PyPI workflow under Actions. It verifies the tag against both version files, builds, and uploads. Total runtime ~2 minutes.
- Verify in a clean venv:
pip install --upgrade codeband cb --version
pip install --upgrade build twine
python -m build
twine check dist/*The repo uses a src/ layout with setuptools.packages.find, so python -m build produces both an sdist and a wheel under dist/. Prompt files are
bundled via [tool.setuptools.package-data].
- Tag/version drift — the build job's verify step fails before any upload.
Fix: delete the bad tag (
git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z), align the versions, re-tag. - OIDC rejected by PyPI — confirm the Trusted Publisher entry matches
exactly: owner
thenvoi, repocodeband, workflowpublish.yml, environmentrelease. Re-run the failed job from the Actions tab. - Bad release shipped — you can
yanka release on PyPI (hides from defaultpip install, keeps it for pinned installs). You cannot delete a version once published. Ship the next patch version with the fix. - Re-publishing the same version — not allowed by PyPI. Bump and re-tag.
If Trusted Publishing is ever unavailable, a maintainer with Band org upload
permissions can publish from a local machine:
python -m build
twine upload dist/* # uses ~/.pypirc or TWINE_USERNAME/TWINE_PASSWORDPrefer the tag-driven workflow — it leaves an auditable trail in GitHub Actions and avoids any local credential handling.