This document describes how to release a new version of the Alternator Load Balancing Client for Python.
- You must have write access to the repository
- The
pypienvironment must be configured in GitHub with PyPI trusted publishing - (Optional) GPG signing keys must be configured for signed releases
Before choosing the next version, review docs/COMPATIBILITY_AND_RELEASE.md.
Use a minor release for additive compatible APIs and opt-in capabilities. Use a major release for changed defaults, removed deprecated names, removed legacy credential kwargs, changed default routing fallback, changed default auth, or default-enabled node health/quarantine behavior.
Release notes for capability work should call out auth defaults, routing fallback behavior, deprecated-name migration, key-affinity behavior, and whether node health remains planning-only. Use docs/RELEASE_NOTES.md as the release-note source.
Update the version in alternator/_version.py:
__version__ = "1.0.0"Commit and push this change to the main branch.
- Go to the repository's Actions tab
- Select the Release workflow
- Click Run workflow
- Enter the version number (must match
_version.py) - Click Run workflow
The workflow will:
- Validate the version format and match with
_version.py - Run all tests and linters
- Build the package (wheel and source distribution)
- Sign artifacts with GPG
- Generate SHA256 checksums
- Publish to PyPI
- Create a GitHub release with the tag
vX.Y.Z
GPG signing provides cryptographic verification that releases are authentic and haven't been tampered with.
# Generate a new key
gpg --full-generate-key
# Choose:
# - RSA and RSA
# - 4096 bits
# - Key does not expire (or set expiration)
# - Your name and email
# List your keys
gpg --list-secret-keys --keyid-format LONG
# Example output:
# sec rsa4096/ABCD1234EFGH5678 2024-01-01 [SC]
# 1234567890ABCDEF1234567890ABCDEF12345678
# uid [ultimate] Your Name <your@email.com>
# ssb rsa4096/IJKL9012MNOP3456 2024-01-01 [E]# Export the private key (ASCII armored)
gpg --armor --export-secret-keys ABCD1234EFGH5678 > private-key.asc
# The output will look like:
# -----BEGIN PGP PRIVATE KEY BLOCK-----
# ...
# -----END PGP PRIVATE KEY BLOCK-----Add the following secrets to your repository (Settings → Secrets and variables → Actions):
| Secret Name | Description |
|---|---|
GPG_PRIVATE_KEY |
The full ASCII-armored private key (including BEGIN/END markers) |
GPG_PASSPHRASE |
The passphrase for the GPG key (leave empty if no passphrase) |
For users to verify signatures, they need your public key:
# Export public key
gpg --armor --export ABCD1234EFGH5678 > public-key.asc
# Upload to a keyserver
gpg --keyserver keyserver.ubuntu.com --send-keys ABCD1234EFGH5678Add the key ID and fingerprint to your project documentation so users know how to verify.
# Download the checksums file
curl -LO https://github.com/scylladb/alternator-client-python/releases/download/v1.0.0/SHA256SUMS
# Download the package
curl -LO https://github.com/scylladb/alternator-client-python/releases/download/v1.0.0/alternator_client-1.0.0.tar.gz
# Verify
sha256sum -c SHA256SUMS# Import the signing key (first time only)
gpg --keyserver keyserver.ubuntu.com --recv-keys A97AF2DE72D4293398AF8274FC93C043D8ADA78E
# Download the signature
curl -LO https://github.com/scylladb/alternator-client-python/releases/download/v1.0.0/SHA256SUMS.asc
# Verify the checksums file signature
gpg --verify SHA256SUMS.asc SHA256SUMS
# Or verify individual files
curl -LO https://github.com/scylladb/alternator-client-python/releases/download/v1.0.0/alternator_client-1.0.0.tar.gz.asc
gpg --verify alternator_client-1.0.0.tar.gz.asc alternator_client-1.0.0.tar.gz# Fetch tags
git fetch --tags
# Verify tag signature
git tag -v v1.0.0- Ensure the version in
_version.pymatches exactly what you entered - Version format must be
X.Y.ZorX.Y.Z-suffix(e.g.,1.0.0-beta.1)
- Verify
GPG_PRIVATE_KEYsecret contains the full key including headers - Verify
GPG_PASSPHRASEis correct (or empty if no passphrase) - Check the key hasn't expired
- Ensure the
pypienvironment is configured with trusted publishing - Check that the version doesn't already exist on PyPI
If a release needs to be removed:
# Yank a specific version (marks it as not recommended but still installable
# by pinned requirements)
pip install twine
twine yank alternator-client==1.0.0- Go to the repository's Releases page
- Find the release (e.g.,
v1.0.0) - Click Delete on the release
- Optionally delete the git tag:
git push --delete origin v1.0.0
- Fix the issue on the main branch
- Bump the version to a new patch version (e.g.,
1.0.1) - Follow the normal release process above
Note: PyPI does not allow re-uploading the same version number. You must always use a new version.
This project follows Semantic Versioning:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality additions
- PATCH version for backwards-compatible bug fixes
Pre-release versions use suffixes like -alpha.1, -beta.1, -rc.1.