This guide explains how to release a new version of the package.
Setup trusted publishing on PyPI to avoid managing API tokens:
- Go to https://pypi.org/manage/account/publishing/
- Add a new "pending publisher":
- PyPI Project Name:
capiscio-sdk - Owner:
capiscio - Repository:
capiscio-sdk-python - Workflow:
publish.yml - Environment: (leave empty)
- PyPI Project Name:
This allows GitHub Actions to publish directly without storing secrets.
If not using trusted publishing, you'll need a PyPI API token:
- Generate token at https://pypi.org/manage/account/token/
- Add to GitHub Secrets as
PYPI_API_TOKEN - Update
.github/workflows/publish.ymlto use password authentication
-
Update version in
pyproject.toml:version = "0.2.0" # Increment appropriately
-
Update CHANGELOG.md:
## [0.2.0] - 2025-10-11 ### Added - New features ### Changed - Breaking changes ### Fixed - Bug fixes
-
Update documentation if needed (README, docs/)
-
Run tests to ensure everything works:
pytest
-
Commit changes:
git add pyproject.toml CHANGELOG.md git commit -m "Prepare v0.2.0 release" git push
-
Tag the release:
git tag v0.2.0 git push origin v0.2.0
-
GitHub Action automatically:
- Builds the package
- Runs checks
- Publishes to PyPI
- Creates GitHub release with notes
- Check PyPI: https://pypi.org/project/capiscio-sdk/
- Test installation:
pip install capiscio-sdk==0.2.0 python -c "import capiscio_sdk; print('✓ Works!')" - Check GitHub Release: https://github.com/capiscio/capiscio-sdk-python/releases
If the GitHub Action fails or you need to publish manually:
# 1. Clean previous builds
rm -rf dist/ build/
# 2. Build package
python -m build
# 3. Check package
python -m twine check dist/*
# 4. Upload to PyPI
python -m twine upload dist/*
# Enter your PyPI username and API token when prompted
# 5. Create GitHub release manually
# Go to: https://github.com/capiscio/capiscio-sdk-python/releases/new
# - Tag: v0.2.0
# - Title: Release v0.2.0
# - Description: Copy from CHANGELOG.md
# - Upload dist/* filesWe follow Semantic Versioning:
- MAJOR (1.0.0): Breaking changes
- MINOR (0.2.0): New features, backward compatible
- PATCH (0.1.1): Bug fixes, backward compatible
0.1.0→0.1.1: Bug fix0.1.0→0.2.0: New feature (scoring system update)0.1.0→1.0.0: First stable release with API guarantees
For testing releases before official:
# Alpha release
version = "0.2.0a1"
git tag v0.2.0a1
# Beta release
version = "0.2.0b1"
git tag v0.2.0b1
# Release candidate
version = "0.2.0rc1"
git tag v0.2.0rc1If a release has critical issues:
- You cannot delete a version from PyPI
- Instead, release a new patch version with fixes
- Update documentation to warn about the bad version
- Delete the release (but not the tag if on PyPI)
- Delete the tag locally:
git tag -d v0.2.0 - Delete remote tag:
git push origin :refs/tags/v0.2.0
Before each release:
- Version bumped in
pyproject.toml - CHANGELOG.md updated
- Documentation updated (if needed)
- Smoke tests pass:
python smoke_test.py - All changes committed and pushed
- Tag created and pushed
- GitHub Action succeeded
- Package visible on PyPI
- Installation tested
- GitHub release created
- You cannot re-upload the same version
- Increment version and create new release
- Verify configuration at https://pypi.org/manage/account/publishing/
- Ensure workflow name matches exactly
- Check repository owner and name are correct
- Check GitHub Actions logs
- Verify pyproject.toml syntax
- Ensure all files are committed
- Check package structure with:
python -m zipfile -l dist/*.whl - Verify
__init__.pyexports are correct - Test in clean virtual environment