This document describes how to publish a new version of greybeard to PyPI.
greybeard uses PyPI's Trusted Publishing for secure, token-free releases.
-
Create the package on PyPI (first release only):
# Build locally uv pip install build python -m build # Upload manually with twine (one time only) uv pip install twine twine upload dist/*
-
Configure Trusted Publisher on PyPI:
- Go to https://pypi.org/manage/project/greybeard/settings/publishing/
- Add a new publisher:
- PyPI Project Name:
greybeard - Owner:
btotharye(your GitHub username) - Repository name:
greybeard - Workflow name:
publish.yml - Environment name:
pypi
- PyPI Project Name:
- Save
After this one-time setup, all future releases are automatic via GitHub Actions.
The easiest way to create a release:
./release.sh 0.2.0This script will:
- ✅ Create a release branch (
release-0.2.0) - ✅ Update
pyproject.tomlwith the new version - ✅ Create/initialize
CHANGELOG.md(if it doesn't exist) - ✅ Commit the version bump
- ✅ Push the release branch
- ✅ Open your browser to create a PR
After the PR is merged:
git checkout main
git pull origin main
git tag -a v0.2.0 -m "Release v0.2.0"
git push origin v0.2.0Then create the GitHub Release, and the workflow will automatically publish to PyPI!
If you prefer manual control, follow these steps:
git checkout main
git pull origin main
git checkout -b release-0.2.0Edit pyproject.toml:
[project]
version = "0.2.0" # Update thisIf you're maintaining a CHANGELOG.md, add release notes:
## [0.2.0] - 2026-03-01
### Added
- New feature X
### Fixed
- Bug Y
### Changed
- Improved Zgit add pyproject.toml CHANGELOG.md # if you have one
git commit -m "chore: bump version to 0.2.0"
git push origin release-0.2.0- Go to your repository and create a PR from
release-0.2.0tomain - Wait for CI to pass
- Get approval (if required)
- Merge the PR
After the PR is merged:
git checkout main
git pull origin main
git tag v0.2.0
git push origin v0.2.0- Go to https://github.com/btotharye/greybeard/releases/new
- Tag: Select
v0.2.0(the tag you just pushed) - *8Release title**:
v0.2.0orgreybeard v0.2.0 - Description: Summarize changes from CHANGELOG or write release notes
- Click Publish release
The GitHub Action will automatically:
- ✅ Build the distribution files (
sdistandwheel) - ✅ Publish to PyPI using trusted publishing
- ✅ Show the new version at https://pypi.org/project/greybeard/
Monitor the workflow at: https://github.com/btotharye/greybeard/actions/workflows/publish.yml
To test the release process without publishing to production PyPI:
- Go to https://test.pypi.org/manage/project/greybeard/settings/publishing/
- Add the same trusted publisher configuration as above, but with:
- Environment name:
testpypi
- Environment name:
Instead of creating a GitHub Release, manually trigger the workflow:
- Go to https://github.com/btotharye/greybeard/actions/workflows/publish.yml
- Click Run workflow
- Select your branch
- Click Run workflow
This will publish to TestPyPI only, allowing you to test installation:
uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ greybeardFollow Semantic Versioning:
- MAJOR (
1.0.0→2.0.0): Breaking changes - MINOR (
0.1.0→0.2.0): New features, backward compatible - PATCH (
0.1.0→0.1.1): Bug fixes, backward compatible
PyPI doesn't allow re-uploading the same version. Increment the version number.
The trusted publisher isn't configured. Follow the "One-time PyPI Setup" section above.
Check:
- The
pypienvironment exists in GitHub repo settings - The trusted publisher is configured on PyPI
- The workflow has
id-token: writepermissions (already configured)
Use manual workflow dispatch and modify the workflow to skip the publish-to-pypi job.
Using the helper script (recommended):
./release.sh 0.2.0
# Create and merge PR, then:
git checkout main
git pull origin main
git tag -a v0.2.0 -m "Release v0.2.0"
git push origin v0.2.0
# Create GitHub release when browser opensManual approach:
# 1. Create release branch
git checkout main
git pull origin main
git checkout -b release-0.2.0
# 2. Update version in pyproject.toml
# 3. Commit changes
git add pyproject.toml
git commit -m "chore: bump version to 0.2.0"
git push origin release-0.2.0
# 4. Create and merge PR
# 5. After PR merge, tag and push
git checkout main
git pull origin main
git tag v0.2.0
git push origin v0.2.0
# 6. Create GitHub Release at github.com/yourrepo/releases/new
# 7. GitHub Actions publishes to PyPI automaticallySee the GitHub Actions workflow or open an issue.