Releasing to PyPI

Complete guide for publishing Prismo releases to PyPI.

Quick Release

For maintainers who have already set up PyPI:

# 1. Ensure everything is ready
pytest tests/ -v
ruff check src/
black --check src/

# 2. Create and push tag
git tag -a v0.2.0 -m "Release v0.2.0: Add mode ports"
git push origin v0.2.0

# 3. Create GitHub Release
# Go to: https://github.com/rithulkamesh/prismo/releases/new
# Select the tag, add release notes, publish

# 4. Automatic PyPI upload via GitHub Actions! ✨
# Check: https://pypi.org/project/prismo/

First-Time Setup

1. PyPI Account

# Create accounts
# - https://pypi.org/account/register/
# - https://test.pypi.org/account/register/

# Enable 2FA (required)

2. Configure Trusted Publishing

On PyPI:

  1. Go to: https://pypi.org/manage/account/publishing/

  2. Click “Add a new publisher”

  3. Fill in:

    • PyPI Project Name: pyprismo

    • Owner: rithulkamesh

    • Repository: prismo

    • Workflow: publish-pypi.yml

    • Environment: pypi

Important: The PyPI package name is pyprismo (because prismo was taken), but the import name remains prismo.

On GitHub:

  1. Go to: Repository → Settings → Environments

  2. Create environment: pypi

  3. (Optional) Add protection rules requiring approval

Repeat for TestPyPI with environment testpypi.

3. Verify Configuration

The repository already includes:

  • .github/workflows/publish-pypi.yml - Automated publishing

  • pyproject.toml - Package metadata

  • MANIFEST.in - File inclusion rules

  • LICENSE - MIT license

  • README.md - Package description

Local Testing

Build Package Locally

# Use the provided script
./scripts/build_package.sh

# Or manually
python -m build

# Check the built files
twine check dist/*

Test Installation Locally

# Install from local wheel
pip install dist/pyprismo-*.whl

# Verify
python -c "import prismo; print(prismo.__version__)"
python -c "from prismo import Simulation; print('✓ Import successful')"

Test on TestPyPI

# Upload to TestPyPI
twine upload --repository testpypi dist/*

# Install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple/ \
    pyprismo

# Test
python -c "import prismo; print(prismo.__version__)"

Version Management

Current Version

Version is automatically determined by hatch-vcs from git tags:

# Check current version
python -c "from prismo import __version__; print(__version__)"

# Or
git describe --tags

Dev Versions

Commits between tags get dev versions:

  • Tag: v0.1.0

  • Next commit: 0.1.1.dev1+g1234567

Version Scheme

v0.1.0          → 0.1.0           (release)
v0.1.0-rc1      → 0.1.0rc1        (release candidate)
v0.1.0-alpha    → 0.1.0a0         (alpha)
v0.1.0-beta.1   → 0.1.0b1         (beta)

Release Types

Patch Release (0.1.0 → 0.1.1)

Bug fixes only:

git tag -a v0.1.1 -m "Patch release: Bug fixes"

Minor Release (0.1.0 → 0.2.0)

New features (backward compatible):

git tag -a v0.2.0 -m "Minor release: New features"

Major Release (0.2.0 → 1.0.0)

Breaking changes or major milestone:

git tag -a v1.0.0 -m "Major release: Production ready"

Pre-releases

Alpha, beta, or release candidates:

# Alpha
git tag -a v0.2.0a1 -m "Alpha release for testing"

# Beta
git tag -a v0.2.0b1 -m "Beta release"

# Release Candidate
git tag -a v0.2.0rc1 -m "Release candidate 1"

PyPI Package Page

Enhance your PyPI presence:

Project Description

The README.md is automatically used as the long description on PyPI.

Project URLs

Already configured in pyproject.toml:

[project.urls]
Homepage = "https://github.com/rithulkamesh/prismo"
Documentation = "https://prismo.readthedocs.io"
Repository = "https://github.com/rithulkamesh/prismo.git"
Issues = "https://github.com/rithulkamesh/prismo/issues"

Classifiers

Update as project matures:

classifiers = [
    "Development Status :: 3 - Alpha",  # Update to "4 - Beta" or "5 - Production/Stable"
    # ... other classifiers
]

Rollback

If a release has critical issues:

# 1. Delete the GitHub release (not the tag)
# 2. Contact PyPI to yank the release
#    (https://pypi.org/help/#yanked)
# 3. Release a patch version with fixes
git tag -a v0.2.1 -m "Fix critical bug from v0.2.0"

Note: You cannot delete PyPI releases, only “yank” them.

Automation Summary

Current Setup:

  • ✅ Automated PyPI publishing via GitHub Actions

  • ✅ Trusted Publishing (no tokens needed)

  • ✅ Automatic version from git tags

  • ✅ Build verification

  • ✅ TestPyPI support

When you create a GitHub release:

  1. GitHub Actions automatically triggers

  2. Package is built

  3. Tests run

  4. Upload to PyPI happens automatically

  5. Package is available at https://pypi.org/project/prismo/

No manual steps required after GitHub release! 🎉

See Also