Releasing django-rls
This document describes the release process for django-rls.
Release Types
django-rls follows Semantic Versioning:
- Major (X.0.0): Breaking changes
- Minor (0.X.0): New features, backwards compatible
- Patch (0.0.X): Bug fixes, backwards compatible
- Pre-release: Alpha, Beta, RC versions (e.g., 1.0.0-alpha.1)
Automated Release Process
The preferred method is using GitHub Actions:
1. Via GitHub UI
- Go to Actions → Release to PyPI
- Click "Run workflow"
- Select version bump type:
patch: Bug fixes (0.1.0 → 0.1.1)minor: New features (0.1.0 → 0.2.0)major: Breaking changes (0.1.0 → 1.0.0)pre: Pre-release versions
- For pre-releases, select type:
alpha,beta, orrc - Click "Run workflow"
The workflow will:
- Run all tests
- Bump version
- Create git tag
- Build packages
- Upload to TestPyPI
- Test installation
- Upload to PyPI (for stable releases)
- Create GitHub release
2. Via Git Tags
Push a version tag to trigger release:
git tag v1.0.0
git push origin v1.0.0
Documentation versioning
The docs site uses Docusaurus versioning. When you release a new stable version:
cd documentation
npm ci
npm run docusaurus docs:version 1.0.0 # snapshots docs/ → versioned_docs/version-1.0.0/
docs/— in-development docs (labeled "Next" on the site)versioned_docs/version-X.Y.Z/— frozen docs for that releaseversions.json— version order (newest first)
After snapshotting, sync link fixes into the new version folder if needed, then npm run build before deploy.
Older releases (e.g. 0.4.1) remain available under the version dropdown with an "unmaintained" banner.
Manual Release Process
For local testing or manual releases:
1. Check Release Readiness
./scripts/release.sh check
This will:
- Verify git status is clean
- Check you're on main branch
- Run all tests
- Check coverage (>90%)
2. Bump Version
# Patch release (bug fixes)
./scripts/release.sh bump patch
# Minor release (new features)
./scripts/release.sh bump minor
# Major release (breaking changes)
./scripts/release.sh bump major
# Pre-release
./scripts/release.sh bump pre --pre-release alpha
./scripts/release.sh bump pre --pre-release beta
./scripts/release.sh bump pre --pre-release rc
3. Build Distribution
./scripts/release.sh build
4. Upload to TestPyPI
./scripts/release.sh test-pypi
Test installation:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple django-rls==VERSION
5. Upload to PyPI
./scripts/release.sh pypi
Version Bumping Examples
Current version: 0.1.0
patch→ 0.1.1minor→ 0.2.0major→ 1.0.0pre --pre-release alpha→ 0.1.1-alpha.1pre --pre-release alpha(again) → 0.1.1-alpha.2pre --pre-release beta→ 0.1.1-beta.1patch(from pre-release) → 0.1.1
Pre-release Workflow
-
Create alpha releases for early testing:
./scripts/release.sh bump pre --pre-release alpha -
Progress to beta when feature-complete:
./scripts/release.sh bump pre --pre-release beta -
Release candidates for final testing:
./scripts/release.sh bump pre --pre-release rc -
Final release:
./scripts/release.sh bump patch
GitHub Environments
The release workflow uses two environments:
-
test-release: For TestPyPI uploads
- No additional secrets required
- Automatic approval
-
release: For PyPI uploads
- Requires PyPI API token
- Manual approval for major versions
Setting Up PyPI Tokens
- Create account on PyPI
- Generate API token: Account settings → API tokens
- Add to GitHub secrets:
- Go to Settings → Secrets → Actions
- Add
PYPI_API_TOKEN
For TestPyPI:
- Create account on TestPyPI
- Generate API token
- Add
TEST_PYPI_API_TOKENto GitHub secrets
Post-Release Checklist
After a successful release:
- Verify package on PyPI: https://pypi.org/project/django-rls/
- Test installation:
pip install django-rls==VERSION - Check documentation is updated: https://django-rls.com
- Update changelog if needed
- Announce release (if major/minor)
Troubleshooting
Build Failures
# Clean build artifacts
rm -rf dist/ build/ *.egg-info
# Rebuild
poetry build
Version Conflicts
# Check current version
python -c "from django_rls.__version__ import __version__; print(__version__)"
# Reset to tag
git reset --hard v0.1.0
Failed TestPyPI Upload
- Check if version already exists
- Use
--skip-existingflag - Bump version and retry
Failed PyPI Upload
- Verify API token is correct
- Check version doesn't exist
- Ensure all tests pass
Emergency Rollback
If a bad release is published:
- Yank the release on PyPI (doesn't delete, just marks as "yanked")
- Fix the issue
- Release a new patch version
Note: Never delete or reuse version numbers!