Deployment and Publishing
This guide is for maintainers who publish releases to PyPI.
Overview
EffDim uses GitHub Actions to automatically build and publish prebuilt wheels for multiple platforms and Python versions.
Prerequisites
PyPI Account Setup
- Create a PyPI account at pypi.org
- Generate an API token:
- Go to Account Settings → API Tokens
- Click "Add API token"
- Name:
effdim-github-actions - Scope:
Project: effdim - Copy the token (starts with
pypi-)
GitHub Repository Setup
- Go to repository Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
PYPI_API_TOKEN - Value: [paste PyPI token]
- Click Add secret
Release Process
1. Update Version
Edit pyproject.toml:
2. Update Changelog
Document changes in CHANGELOG.md or release notes:
## [0.1.1] - 2024-01-23
### Added
- New feature X
- Performance improvements
### Fixed
- Bug in function Y
3. Commit Changes
4. Create and Push Tag
# Create annotated tag
git tag -a v0.1.1 -m "Release version 0.1.1"
# Push tag to trigger workflow
git push origin v0.1.1
5. Monitor Build
- Go to Actions tab in GitHub
- Watch the "Build and Publish to PyPI" workflow
- Verify all jobs complete successfully:
- ✅ Build wheels (Linux, macOS, Windows)
- ✅ Build source distribution
- ✅ Publish to PyPI
6. Verify Release
After successful workflow:
# Wait a few minutes for PyPI to update
pip install --upgrade effdim
# Verify version
python -c "import effdim; print(effdim.__version__)"
Build Matrix
The CI workflow builds wheels for:
Platforms and Architectures
Linux
- manylinux: x86_64, aarch64
- musllinux: x86_64, aarch64
Windows
- x64 (64-bit)
- x86 (32-bit)
macOS
- x86_64 (Intel) - macOS 13+
- aarch64 (Apple Silicon) - macOS 14+
Python Versions
The workflow uses --find-interpreter to automatically build for all available Python versions (3.8-3.12) on each platform.
Total Artifacts
Approximately 40+ wheels + 1 source distribution per release, covering all combinations of platforms, architectures, and Python versions.
Workflow Files
.github/workflows/CI.yml
The main CI/CD workflow based on maturin's recommended structure:
- Triggered by: Pushes to main/master, PRs, tags, or manual dispatch
- Separate jobs for: linux, musllinux, windows, macos, sdist, release
- Publishes: To PyPI on version tags (automatically)
Key features:
- Uses PyO3/maturin-action
- Enables sccache for faster builds (disabled on release tags)
- Builds manylinux and musllinux for maximum compatibility
- Unique artifact naming prevents conflicts
- Includes build attestations for security
.github/workflows/publish_docs.yml
Publishes documentation to GitHub Pages (unchanged).
Testing Before Release
Option 1: Manual Workflow Trigger
- Go to Actions → Build and Publish to PyPI
- Click Run workflow
- Select branch
- Review artifacts (won't publish without tag)
Option 2: Test with TestPyPI
Modify workflow temporarily to use TestPyPI:
- name: Publish to TestPyPI
uses: PyO3/maturin-action@v1
env:
MATURIN_PYPI_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
with:
command: upload
args: --non-interactive --repository-url https://test.pypi.org/legacy/ dist/*
Then install from TestPyPI:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple effdim
Versioning Strategy
EffDim follows Semantic Versioning:
- MAJOR (0.x.x → 1.x.x): Breaking API changes
- MINOR (x.1.x → x.2.x): New features, backwards compatible
- PATCH (x.x.1 → x.x.2): Bug fixes, backwards compatible
Pre-releases
For beta/RC versions:
Tag as: v0.2.0b1, v0.2.0rc1
Troubleshooting
Build Failures
Rust compilation errors:
Python compatibility issues:
- Ensure
requires-pythoninpyproject.tomlmatches tested versions - Check minimum Rust version in
Cargo.toml
Upload Failures
Invalid token:
- Regenerate PyPI token
- Update
PYPI_API_TOKENsecret in GitHub
Package name conflict:
- First release must be manually created on PyPI
- Or use different package name
File already exists:
- Can't re-upload same version
- Bump version and retry
- Use
--skip-existingflag (already in workflow)
Workflow Not Triggering
Tag format issues:
Branch protection:
- Ensure tags can be pushed to repository
- Check branch protection rules
Rollback Procedure
If a bad release is published:
Option 1: Yank Release (Recommended)
On PyPI:
- Go to project page
- Click on problematic version
- Click "Options" → "Yank release"
- Publish fixed version
Option 2: Delete Release
⚠️ Not recommended - breaks existing installations
Then publish corrected version.
Security
API Token Management
- Rotate tokens periodically (every 6-12 months)
- Use project-scoped tokens (not account-wide)
- Never commit tokens to repository
- Store in GitHub Secrets only
Dependency Security
Automated security scanning:
- Dependabot alerts (GitHub)
cargo auditfor Rust dependenciespip-auditfor Python dependencies
Maintenance Checklist
Before each release:
- [ ] All tests passing
- [ ] Documentation updated
- [ ] Changelog updated
- [ ] Version bumped
- [ ] Dependencies updated
- [ ] Security audit clean
- [ ] Performance benchmarks run
- [ ] Breaking changes documented