-
Notifications
You must be signed in to change notification settings - Fork 0
Trusted publishing ‐ It has never been easier to publish your python packages
Publishing Python packages used to be a daunting task, but not any more. Even better, it has become significantly more secure. Gone are the days of juggling usernames, passwords, or API tokens while relying on CLI tools. With trusted publishing, you simply provide PyPI with the details of your GitHub repository, and GitHub Actions takes care of the heavy lifting.
I will introduce a workflow that will publish your package to TestPyPi when a tag is created, or to PyPi when you merge to the main
branch.
Ensure your Python package follows PyPI’s packaging guidelines. At a minimum, you’ll need:
- A
setup.py orpyproject.toml file defining your package metadata. - Properly structured code with a clear directory layout.
- A README file to showcase your project on PyPI.
For a detailed checklist, refer to the Python Packaging User Guide.
Let's start by creating a new GitHub action .github/workflows/test-build-publish.yml
.
name: test-build-publish
on: [push, pull_request]
permissions:
contents: read
jobs:
build-and-check-package:
name: Build & inspect our package.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hynek/build-and-inspect-python-package@v2
This action will build your package and uploads the built wheel and the source distribution (SDist
) as GitHub Actions artefacts.
Next, we add a step to publish to TestPyPI. This step will run whenever a tag is created, ensuring that the build from the previous step has completed successfully. Replace PROJECT_OWNER and PROJECT_NAME with the appropriate values for your repository.
test-publish:
if: >-
github.event_name == 'push' &&
github.repository == 'PROJECT_OWNER/PROJECT_NAME' &&
startsWith(github.ref, 'refs/tags')
needs: build-and-check-package
name: Test publish on TestPyPI
runs-on: ubuntu-latest
environment: test-release
permissions:
id-token: write
steps:
- name: Download packages built by build-and-check-package
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- name: Upload package to Test PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
This step downloads the artefacts created during the build process and uploads them to TestPyPI for testing.
In the last step, we will upload the package to PyPI when a pull request is merged into the main
branch.
publish:
if: >-
github.event_name == 'push' &&
github.repository == 'PROJECT_OWNER/PROJECT_NAME' &&
github.ref == 'refs/heads/main'
needs: build-and-check-package
name: Publish to PyPI
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- name: Download packages built by build-and-check-package
uses: actions/download-artifact@v4
with:
name: Packages
path: dist
- name: Publish distribution 📦 to PyPI for push to main
uses: pypa/gh-action-pypi-publish@release/v1
To ensure that only specific tags trigger the publishing workflow and maintain control over your release process.
Create a new environment test-release
by navigating to Settings -> Environments in your GitHub repository.
Set up the environment and add a deployment tag rule.
Configure the target tags.
The pattern [0-9]*.[0-9]*.[0-9]*
matches semantic versioning tags such as 1.2.3
, 0.1.0
, or 2.5.1b3
, but it excludes arbitrary tags like bugfix-567
or feature-update
.
Repeat this for the release
environment to protect the main
branch
Create an account on PyPI if you don’t have one.
Navigate to your account, Publishing and add a new pending publisher.
Link your GitHub repository to the PyPI project by providing its name, your GitHub username, the repository name, the workflow name (test-build-publish.yml
) and the environment name (test-release
).
If you've been holding back on sharing your work, now is the perfect time to try trusted publishing.
Introducing 'Trusted Publishers' The Python Package Index Blog highlights a more secure publishing method that does not require long-lived passwords or API tokens to be shared with external systems. Publishing to PyPI with a Trusted Publisher The official PyPI documentation to get started with using trusted publishers on PyPI,