| name | pypi-publish |
| description | Publishing duroxide-python to PyPI. Use when releasing a new version, building platform wheels, or publishing to the Python Package Index. |
Publishing duroxide-python to PyPI
Pre-Publish Checklist
Before publishing, verify ALL of the following:
1. Clean Build
cd duroxide-python
source .venv/bin/activate
cargo clippy --all-targets
maturin develop --release
2. Tests Pass
pytest -v
3. Changelog Updated
CHANGELOG.md must have an entry for the new version
- Follow Keep a Changelog format
- Include all Added/Changed/Fixed/Removed sections as applicable
4. README Points to Changelog
Verify README.md contains a link to CHANGELOG.md:
See [CHANGELOG.md](CHANGELOG.md) for release notes.
5. Version Bumped
Update version in pyproject.toml:
[project]
name = "duroxide"
version = "0.1.2"
Also update Cargo.toml version to match:
[package]
version = "0.1.2"
Build Platform Wheels
PyPI uses wheels — one per platform + Python version combo. Unlike npm (separate packages per platform), PyPI serves all wheels under the same package name. pip install duroxide automatically picks the right one.
Local Build (current platform only)
maturin build --release
Cross-Platform Builds via GitHub Actions (Recommended)
Use maturin's official GitHub Action to build for all platforms:
name: Publish to PyPI
on:
release:
types: [published]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: PyO3/maturin-action@v1
with:
command: build
args: --release --out dist
manylinux: auto
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}-${{ matrix.python-version }}
path: dist/*.whl
publish:
needs:
Supported Platforms
| Platform | Target | Notes |
|---|
| macOS ARM | aarch64-apple-darwin | Native build on M1/M2 |
| macOS Intel | x86_64-apple-darwin | Cross-compile from ARM |
| Linux x64 | x86_64-unknown-linux-gnu | Use manylinux Docker |
| Linux ARM | aarch64-unknown-linux-gnu | Cross-compile via QEMU |
| Windows x64 | x86_64-pc-windows-msvc | Native build on Windows |
Docker Build for Linux (manylinux)
docker run --rm -v "$(pwd):/io" -w /io ghcr.io/pyo3/maturin build --release
Publish to PyPI
Option 1: maturin publish (build + upload in one step)
export MATURIN_PYPI_TOKEN=pypi-...
maturin publish --skip-existing
Option 2: Build then upload with twine
maturin build --release
pip install twine
twine upload target/wheels/*.whl
Option 3: Test on TestPyPI first
maturin publish --repository testpypi
pip install --index-url https://test.pypi.org/simple/ duroxide
PyPI Authentication
[pypi]
username = __token__
password = pypi-...
- Never commit tokens to source code
Verify Published Package
python3 -m venv /tmp/test-duroxide
source /tmp/test-duroxide/bin/activate
pip install duroxide
python -c "from duroxide import SqliteProvider; print('loaded successfully')"
deactivate
rm -rf /tmp/test-duroxide
Key Differences from npm Publishing
| Aspect | npm (duroxide-node) | PyPI (duroxide-python) |
|---|
| Packages per platform | Separate (@duroxide/darwin-arm64) | One package, multiple wheels |
| Publish order | Platform packages first, then main | Just publish all wheels |
| Binary selection | optionalDependencies in package.json | pip auto-selects by wheel filename |
| Build tool | npx napi build | maturin build |
| Upload tool | npm publish | maturin publish or twine upload |
| Token type | npm Automation token | PyPI API token |
Summary Checklist