This guide explains how to publish PyPTV to PyPI and TestPyPI using GitHub Actions with trusted publishing.
PyPTV uses GitHub's OIDC (OpenID Connect) trusted publishing feature to securely publish packages to PyPI without using long-lived API tokens. This is the recommended approach by PyPI.
- Repository owner access to
alexlib/pyptv - PyPI/TestPyPI account with permissions to add trusted publishers
- GitHub Actions enabled in the repository
- Log in to TestPyPI
- Navigate to your project or create it first by doing a manual upload
- Go to "Publishing" section in your project settings
- Click "Add a new publisher"
- Fill in the following details:
- PyPI Project Name:
pyptv - Owner:
alexlib - Repository name:
pyptv - Workflow name:
publish-to-pypi.yml - Environment name:
testpypi
- PyPI Project Name:
- Save the configuration
- Log in to PyPI
- Navigate to your project
pyptv - Go to "Publishing" section in your project settings
- Click "Add a new publisher"
- Fill in the following details:
- PyPI Project Name:
pyptv - Owner:
alexlib - Repository name:
pyptv - Workflow name:
publish-to-pypi.yml - Environment name:
pypi
- PyPI Project Name:
- Save the configuration
The workflow uses GitHub Environments for additional security. Ensure the following environments exist in the repository:
-
pypi environment
- Used for production releases
- Can optionally require manual approval
-
testpypi environment
- Used for test releases
- Can optionally require manual approval
To create/verify environments:
- Go to repository Settings → Environments
- Create
pypiandtestpypienvironments if they don't exist - Optionally configure protection rules (e.g., required reviewers)
- Go to Actions tab in the GitHub repository
- Select "Publish Python Package to PyPI" workflow
- Click "Run workflow"
- Select branch:
master - Choose deploy target:
testpypi - Click "Run workflow"
The workflow will:
- Build the package
- Publish to TestPyPI using trusted publishing
- Create a deployment record
There are two ways to publish to PyPI:
- Create and push a version tag:
git tag v0.x.x git push origin v0.x.x
- Go to GitHub → Releases → "Draft a new release"
- Select the tag you just created
- Fill in release notes
- Click "Publish release"
The workflow will automatically trigger and publish to PyPI.
- Go to Actions tab in the GitHub repository
- Select "Publish Python Package to PyPI" workflow
- Click "Run workflow"
- Select branch:
master - Choose deploy target:
pypi - Click "Run workflow"
If you see an error like:
Token request failed: the server refused the request for the following reasons:
* `invalid-publisher`: valid token, but no corresponding publisher
This means the trusted publisher configuration on PyPI/TestPyPI doesn't match the workflow. Verify:
- The workflow file path is exactly:
.github/workflows/publish-to-pypi.yml - The environment name matches:
testpypiorpypi - The repository owner and name are correct:
alexlib/pyptv - The trusted publisher was added on the correct PyPI instance (TestPyPI vs PyPI)
If the workflow fails with environment errors:
- Create the missing environment in Settings → Environments
- Ensure the environment name matches what's in the workflow
If the build step fails:
- Check Python version compatibility
- Verify
pyproject.tomlconfiguration - Test build locally:
pip install build python -m build
The workflow file .github/workflows/publish-to-pypi.yml has three main jobs:
- build: Builds the distribution packages (wheel and source distribution)
- publish-to-pypi: Publishes to production PyPI (on release or manual trigger)
- publish-to-testpypi: Publishes to TestPyPI (on manual trigger only)
- The workflow uses
pypa/gh-action-pypi-publish@release/v1action - No API tokens are needed - authentication is handled via OIDC
- The
id-token: writepermission is required for trusted publishing - Artifacts are shared between jobs for efficiency
Always test on TestPyPI before publishing to PyPI:
- Publish to TestPyPI using manual workflow dispatch
- Install from TestPyPI and test:
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ pyptv
- Verify the package works as expected
- Then proceed with PyPI release
- Never commit API tokens to the repository
- Use environment protection rules to require approvals for production deployments
- Regularly review and rotate any API tokens (if used for other purposes)
- Monitor the workflow runs for any suspicious activity
- Keep the
pypa/gh-action-pypi-publishaction updated
- PyPI Help - Publishing - Official PyPI publishing documentation
- GitHub OIDC with PyPI - GitHub's guide for trusted publishing
- pypa/gh-action-pypi-publish - The GitHub Action used for publishing
- Trusted Publishers on PyPI - Introduction to trusted publishers