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.yaml
to the.github/workflows/
directory of your project repo and adjust according to the project needs. Configure the CI workflow by editting theenv
variables 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
tox
andtox-gh
to 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.toml
file to use with the github workflow files:- Uses
hatch-vcs
to dynamically update the project version (in_version.py
file) based on git tags - Compatible
tox
configuration to run tests using:uv run tox
- Default configs for
uv
,mypy
,ruff
andpytest
. - Assumes:
- project python code is in the
src
sub-directory - pytest-based tests are in the
tests
sub-directory
- project python code is in the
To ensure that the
_version.py
file is updated with a new version after every commit or checkout, add this command to the.git/hooks/post-commit
and.git/hooks/post-checkout
files:uv run hatch build --hooks-only > /dev/null
- Uses
-
.github/workflows/test-tox.yaml
:Run CI test workflows on the project. Uses
tox
to run the ci tests; anduv
to manage the python versions and virtual env. Assumestox
configuration is completely provided in configuration files and the CI workflow is configured in thetox-gh
config (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
mypy
for type checking andruff
for linting and format checking. Assumesmypy
andruff
configuration is completely provided in configuration files (eg.pyproject.toml
).This workflow is unnecessary if using
test-tox.yaml
and 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
pytest
to run the ci tests; anduv
to manage the python versions and virtual env. Assumespytest
configuration 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
uv
and 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