How to Publish to TestPyPI Before PyPI
Upload to test.pypi.org first to validate metadata and install, then publish the identical artifacts to PyPI once the dry run succeeds.
TestPyPI is a separate index for rehearsing releases. Point twine at https://test.pypi.org/legacy/ or set repository-url on pypa/gh-action-pypi-publish. TestPyPI supports its own trusted publishers, so OIDC works there too.
Steps
- Build once with
python -m build. - Upload to TestPyPI with the test
repository-urland verifypip installfrom it. - Promote the same
dist/to PyPI in a later job or run.
Workflow
.github/workflows/ci.yml
jobs:
test-publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install --upgrade build
- run: python -m build
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/Verify the install
Terminal
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ my-packageGotchas
- TestPyPI accounts and tokens are separate from PyPI; register both.
- Use
--extra-index-urlso dependencies resolve from real PyPI during the test install.
Related guides
How to Publish to PyPI With Trusted Publishing (OIDC)Publish to PyPI from CI without a stored token using trusted publishing, where PyPI verifies the workflow OID…
How to Publish a Python Package to PyPI With twinePublish a Python package to PyPI from CI by building sdist and wheel with python -m build, then uploading wit…
How to Dry-Run a Publish in CIRehearse a publish in CI without shipping using dry-run flags like npm publish --dry-run, cargo publish --dry…