My collection of github reusable workflows and composite actions for checking, testing, publishing and releasing python packages. I have put these in this repo so I can re-use them in my python projects.
These workflows use the uv python package tool
for managing the project virtual environments, running tests and building and
publishing python packages.
-
To get started, copy
examples/ci.yamlto the.github/workflows/directory of your project repo and adjust according to the project needs. Configure the CI workflow by editting theenvvariables which select the workflow depending on what event triggered the workflow:env: on-push-tag-*: | # Push version tag matching "v*", eg. "v1.0.0" jobs=["test", "build", "publish", "release"] python-version=["3.9", "3.10", "3.11", "3.12", "3.13"] os=["ubuntu-latest", "windows-latest", "macos-latest"] on-push-branch-main: | # Push commits to main branch jobs=["test", "build", "publish-test"] python-version=["3.9", "3.10", "3.11", "3.12", "3.13"] os=["ubuntu-latest", "windows-latest", "macos-latest"] on-push-branch-*: | # Push commits to other branches (including dev) jobs=["test", "build"] python-version=["3.9", "3.13"] os=["ubuntu-latest"] on-workflow_dispatch-branch-*: | # Manual trigger of the workflow jobs=["test", "build"] python-version=["3.9", "3.13"] os=["ubuntu-latest"]
This workflow uses
toxandtox-ghto run and orchestrate the github CI workflow. In this way, the same CI workflows are run on github and locally withuv run tox. -
An example
pyproject.tomlfile to use with the github workflow files:- Uses
hatch-vcsto dynamically update the project version (in_version.pyfile) based on git tags - Compatible
toxconfiguration to run tests using:uv run tox - Default configs for
uv,mypy,ruffandpytest. - Assumes:
- project python code is in the
srcsub-directory - pytest-based tests are in the
testssub-directory
- project python code is in the
To ensure that the
_version.pyfile is updated with a new version after every commit or checkout, add this command to the.git/hooks/post-commitand.git/hooks/post-checkoutfiles:uv run hatch build --hooks-only > /dev/null
- Uses
-
.github/workflows/test-tox.yaml:Run CI test workflows on the project. Uses
toxto run the ci tests; anduvto manage the python versions and virtual env. Assumestoxconfiguration is completely provided in configuration files and the CI workflow is configured in thetox-ghconfig (eg.pyproject.toml). (See https://github.com/tox-dev/tox-gh).Input options:
os: a json string containing the list of operating systems on which to run tests.- Default is
'["ubuntu-latest", "windows-latest", "macos-latest"]'.
- Default is
python-version: a json string containing the list of python versions on which to run tests.- Default is
'["3.9", "3.10", "3.11", "3.12", "3.13"]'.
- Default is
Invoke with:
uses: glenn20/python-ci/.github/workflows/test-tox.yaml@v2 -
.github/workflows/code-check.yaml:Run code checks on the codebase. Uses
mypyfor type checking andrufffor linting and format checking. Assumesmypyandruffconfiguration is completely provided in configuration files (eg.pyproject.toml).This workflow is unnecessary if using
test-tox.yamland the static code checks are configured viatox-gh.Invoke with:
uses: glenn20/python-ci/.github/workflows/code-check.yaml@v2 -
.github/workflows/test-pytest.yaml:Run CI test workflows on the project. Uses
pytestto run the ci tests; anduvto manage the python versions and virtual env. Assumespytestconfiguration is completely provided in configuration files (eg.pyproject.toml).Input options:
os: a json string containing the list of operating systems on which to run tests.- Default is
'["ubuntu-latest", "windows-latest", "macos-latest"]'.
- Default is
python-version: a json string containing the list of python versions on which to run tests.- Default is
'["3.9", "3.10", "3.11", "3.12", "3.13"]'.
- Default is
Invoke with:
uses: glenn20/python-ci/.github/workflows/test-pytest.yaml@v2 -
Build the python package (using
uv build) and upload as a workflow artifact to the github repo.Invoke with
uses: glenn20/python-ci/.github/workflow/build.yaml@v1 -
.github/workflows/github-release.yaml:Use sigstore to sign the python package files and upload to a GitHub Release. Assumes the python package has been saved as a workflow artifact. Adapted from the PYPA Python Packaging User Guide
Input options:
tag: tagname: name of the release. Defaults to the current git tag if the workflow is triggered by a tag push, else the version number from the python package wheel file.
Invoke with
uses: glenn20/python-ci/.github/workflow/github-release.yaml@v2
-
A github action to publish a python package to https://pypi.org or https://pypi.org. The publish workflow can't support pypi trusted publishing when run as a reusable workflow from an external repo, so it is provided here as a github composite action.
Input options:
test-only- Only publish to https://test.pypi.org if set 'true' (default)
Outputs:
package-name: the name of the package file publishedpackage-version: the version number of the package, eg. "1.3.2"
Invoke with:
uses: glenn20/python-ci/actions/publish@v2 -
Install
uvand python and setup the python virtual environment (venv).This action is used internally by the reusable workflows above.
Input options:
python-version:set the python version to install (default "3.12").
Invoke with:
uses: glenn20/python-ci/actions/setup@v2