This guide explains how to publish the toon_format package to PyPI (Python Package Index).
Create accounts on both platforms:
- TestPyPI (for testing): https://test.pypi.org/account/register/
- PyPI (production): https://pypi.org/account/register/
The publish workflow uses GitHub environments with trusted publishing (no API tokens needed!).
- Go to your repository Settings > Environments
- Create two environments:
testpypi- for TestPyPI releasespypi- for production PyPI releases
- For each environment, configure:
- Deployment protection rules (optional but recommended):
- Required reviewers (for production releases)
- Wait timer (optional delay before deployment)
- Deployment protection rules (optional but recommended):
For TestPyPI:
- Log in to https://test.pypi.org
- Go to Account Settings > Publishing
- Add a new pending publisher:
- PyPI Project Name:
toon_format - Owner:
toon-format - Repository:
toon-python - Workflow:
publish.yml - Environment:
testpypi
- PyPI Project Name:
For PyPI:
- Log in to https://pypi.org
- Go to Account Settings > Publishing
- Add a new pending publisher:
- PyPI Project Name:
toon_format - Owner:
toon-format - Repository:
toon-python - Workflow:
publish.yml - Environment:
pypi
- PyPI Project Name:
Note: After the first successful publish, the project will be registered and future publishes will use the same trusted publisher configuration.
-
Update version number in two places:
pyproject.toml(line 3):version = "X.Y.Z"src/toon_format/__init__.py(line 28):__version__ = "X.Y.Z"
-
Update changelog (if exists) or create release notes
-
Run tests locally:
uv run pytest uv run ruff check . uv run mypy src/toon_format -
Build and test locally:
# Clean previous builds rm -rf dist/ build/ *.egg-info # Build the package python -m build # Verify the package contents python -m zipfile -l dist/toon_format-X.Y.Z-py3-none-any.whl # Test installation in a clean environment python -m venv test_env test_env/bin/pip install dist/toon_format-X.Y.Z-py3-none-any.whl test_env/bin/python -c "import toon_format; print(toon_format.__version__)" rm -rf test_env
-
Commit version changes:
git add pyproject.toml src/toon_format/__init__.py git commit -m "Bump version to X.Y.Z" -
Create and push tag:
git tag -a vX.Y.Z -m "Release version X.Y.Z" git push origin main git push origin vX.Y.Z
Before publishing to production PyPI, test on TestPyPI:
-
Go to GitHub Actions: https://github.com/toon-format/toon-python/actions
-
Select the "Publish to PyPI" workflow
-
Click "Run workflow"
-
Select branch:
main(or the tagvX.Y.Z) -
Click "Run workflow"
- Note: Manual workflow dispatch automatically publishes to TestPyPI
-
Verify the TestPyPI upload:
- Check the package: https://test.pypi.org/project/toon_format/
- Test installation:
pip install --index-url https://test.pypi.org/simple/ toon_format
Automatic (via GitHub Release)
- Go to https://github.com/toon-format/toon-python/releases/new
- Select the tag you created:
vX.Y.Z - Release title:
Version X.Y.Z - Description: Add release notes and changelog
- Click "Publish release"
- The GitHub Action will automatically build and publish to PyPI
- Check PyPI: https://pypi.org/project/toon_format/
- Test installation:
pip install toon_format python -c "import toon_format; print(toon_format.__version__)" - Update README badge (optional):
[](https://pypi.org/project/toon_format/)
This is usually a configuration issue in pyproject.toml. Verify:
- All required fields are present (name, version, description, etc.)
- Project URLs are properly formatted
- Author email is valid
If the trusted publisher configuration fails:
- Verify the environment name matches exactly
- Check that the repository owner and name are correct
- Ensure the workflow file path is correct (
publish.yml) - Make sure the PyPI project name is available or already claimed by you
PyPI doesn't allow overwriting published versions. You must:
- Increment the version number
- Create a new tag
- Publish the new version
Follow Semantic Versioning:
- MAJOR version (X.0.0): Incompatible API changes
- MINOR version (0.X.0): New functionality, backward compatible
- PATCH version (0.0.X): Bug fixes, backward compatible
- 0.8.x - Initial code set, tests, documentation, migration from toon-llm
- 0.9.x - Serializer, spec compliance, publishing to PyPI (test and prod)
- 1.0.0-rc.x - Production readiness candidates
- 1.0.0 - Official stable release 🎉
Examples:
0.9.0-beta.1- First beta release for testing0.9.0-beta.2- Second beta with fixes0.9.0- First minor release with new features1.0.0-rc.1- Release candidate1.0.0- First stable release
Before each release, verify:
- All tests pass (
uv run pytest) - Linting passes (
uv run ruff check .) - Type checking passes (
uv run mypy src/toon_format) - Version updated in
pyproject.tomlandsrc/toon_format/__init__.py - Changes committed and pushed to
main - Git tag created and pushed
- Package tested on TestPyPI (optional but recommended)
- GitHub Release created
- Package verified on PyPI
- Installation tested from PyPI