Continuous Deployment#
Example job:
name: CD
on:
workflow_dispatch:
release:
types:
- published
jobs:
dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build SDist and wheel
run: pipx run build
- uses: actions/upload-artifact@v4
with:
path: dist/*
publish:
needs: [dist]
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v4
with:
name: artifact
path: dist
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository_url: https://test.pypi.org/legacy/
This workflow is triggerable manually (by clicking in the web interface), as well as on any “GitHub Release” (which uses or creates a Git tag, too).
This workflow has two jobs. One builds the artifacts (an SDist and a wheel), and the other takes those artifacts and pushes them to PyPI (test PyPI in this case, just in case!) The second job only runs if the first succeeds. It also only runs if this is a release; otherwise, if you triggered it manually, you can manually download the files from the first job.
This does not have to be in two jobs, but this does scale a bit better if you need to do something more complex, like build binaries.
If you aren’t setting up Trusted Publishing on the PyPI/TestPyPI sites, then
password: ${{ secrets.pypi_password }}
can be used to pass in a token.