No, I don’t use GHA locally, but the actions are defined to run the same things that I do run locally (e.g. invoke nox
). I try to keep the GHA-exclusive boilerplate to a minimum. Steps can be like:
- name: fetch code
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
allow-prereleases: true
python-version: |
3.13
3.12
3.11
3.10
3.9
3.8
3.7
- run: pipx install nox
- name: run ward tests in nox environment
run: nox -s test test_without_toml combine_coverage --force-color
env:
PYTHONIOENCODING: utf-8
- name: upload coverage data
uses: codecov/codecov-action@v4
with:
files: ./coverage.json
token: ${{ secrets.CODECOV_TOKEN }}
Sometimes if I want a higher level interface to tasks that run nox
or other things locally, I use taskipy
to define them in my pyproject.toml
, like:
[tool.taskipy.tasks]
fmt = "nox -s fmt"
lock = "nox -s lock"
test = "nox -s test test_without_toml typecheck -p 3.12"
docs = "nox -s render_readme render_api_docs"
As someone’s new comments just brought me back to this post, I’ll point out that these days there’s another good option: uv run.