This repo contains a set of reusable workflows for use in GitHub Actions.
They are used by repos in the pyapp-kit organization, but you may use them as well if you find them useful for your own projects.
- test-pyrepo.yml - use to run tests for your python package
- test-dependents.yml - use to test that updates to your package don't break another package that depends on your package
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
Standard workflow to setup python and test a python package, in the following order:
- Checks out the repo using
actions/checkoutwithinputs.fetch-depth - Runs
actions/setup-pythonwithpython-version - If
inputs.qt != '': Installs Qt libs using tlambert03/setup-qt-libs - Installs dependencies using
pip install .[extras] - Runs
coverage run -m pytest ${{inputs.pytest-args}}unless overridden.- If
inputs.qt != '': Runs headlessly usingaganders3/headless-gui
- If
- Uploads coverage reports using
codecov/codecov-action - If
report-failures != ''Opens an issue to report failures. Useful for cron jobs for pre-release testing.
(All inputs are optional)
| Input | Type | Default | Description |
|---|---|---|---|
| python-version | string | 3.x | Python version to use. Passed to actions/setup-python. |
| os | string | ubuntu-latest | Operating system to use. Passed to runs-on:. |
| extras | string | test | Package extras to install (may use commas for multiples 'test,docs'). If you don't have an extra named 'test' you should change this. |
| pip-install-flags | string | Additional flags to pass to pip install. Can be used for --editable, --no-deps, etc. |
|
| pip-install-pre-release | boolean | False | Whether to install pre-releases in the pip install phase with --pre. |
| pip-install-min-reqs | boolean | False | Whether to install the minimum declared dependency versions. |
| pip-pre-installs | string | Packages to install before calling pip install . |
|
| pip-post-installs | string | Packages to install after pip install .. (these are called with --force-reinstall.) |
|
| qt | string | Version of qt to install (or none if blank). Will also install qt-libs and run tests headlessly if not blank. | |
| fetch-depth | number | 1 | The number of commits to fetch. 0 indicates all history for all branches and tags. |
| python-cache-dependency-path | string | pyproject.toml | passed to actions/setup-python |
| pytest-args | string | Additional arguments to pass to pytest. Can be used to specify paths or for for -k, -x, etc. |
|
| fail-on-coverage-error | boolean | True | Fail the build if codecov action fails. |
| hatch-build-hooks-enable | boolean | False | Value for HATCH_BUILD_HOOKS_ENABLE. |
| report-failures | string | (true or false). Whether to create a GitHub issue when a test fails. If not set, will be true for scheduled runs, and false otherwise. | |
| cache-key | string | Cache key to use for caching. If not set, no caching will be used. | |
| cache-path | string | Path to cache. If not set, no caching will be used. | |
| cache-script | string | Script to run to create the cache. If not set, no caching will be used. | |
| coverage-upload | string | codecov | How to upload coverage data. Options are 'artifact', 'codecov'. If using 'artifact', coverage must be sent to codecov in a separate workflow. (see upload-coverage.yml) |
Secrets:
| Input | Description |
|---|---|
| codecov_token | Token for codecov-action. Only used if coverage-upload is 'codecov'. |
See complete up-to-date list of options in test-pyrepo.yml
You can mix and match the inputs to suit your needs. But here are some common patterns.
name: CI
jobs:
run_tests:
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
extras: 'test' # this is the default... but you can specify others
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]Note that the default value for report-failures is ${{ github.event_name == 'schedule' }}, so you don't need to specify it unless you want to override the
default. However, you may wish to use
pip-install-pre-release: ${{ github.event_name == 'schedule' }}
to test pre-release versions when triggered by a cron job.
name: CI
on:
schedule:
- cron: "0 0 * * *"
jobs:
run_tests:
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
# Test pre-release versions when triggered by a schedule
# and open an issue if the tests fail
pip-install-pre-release: ${{ github.event_name == 'schedule' }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]Use the qt input to:
- install the specified Qt binding
- install libraries on linux using tlambert03/setup-qt-libs
- run headless tests using aganders3/headless-gui
name: CI
jobs:
run_tests:
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
qt: ${{ matrix.qt }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]
qt: ["", "PyQt6", "PySide6"]Because codecov can often fail, you might want to combine all
reports and upload in a single step. For this, change the
coverage-upload input to artifact and add a separate job
to upload the coverage report using upload-coverage.yml.
name: CI
jobs:
tests:
uses: pyapp-kit/workflows/.github/workflows/test-pyrepo.yml@v2
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
# changing this to "artifact" prevents uploading to codecov here,
# instead it uploads an artifact with the coverage data
coverage-upload: artifact
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]
# now add an additional job to combine and upload the coverage
upload_coverage:
if: always()
needs: [tests]
uses: pyapp-kit/workflows/.github/workflows/upload-coverage.yml@v2
secrets:
codecov_token: ${{ secrets.CODECOV_TOKEN }}uses: pyapp-kit/workflows/.github/workflows/test-dependents.yml@v2
This workflow is useful when your package is a dependency of other packages, and you would like to ensure that your changes don't break those packages.
- Checks out the "host" repo (the repo using this workflow) using
actions/checkout. - Checks out
dependency-repo@dependency-refusingactions/checkout. - Runs
actions/setup-pythonwithpython-version - If
inputs.qt != '': Installs Qt libs using tlambert03/setup-qt-libs - Installs dependencies for
dependency-repofollowed by the host repo. - Runs
pytest inputs.pytest-args(add specific paths or-kflags here)- If
inputs.qt != '': Runs headlessly usingaganders3/headless-gui
- If
(Only dependency-repo is required)
| Input | Type | Default | Description |
|---|---|---|---|
| dependency-repo | string | Repository name with owner of package to test (org/repo). | |
| dependency-ref | string | Ref to checkout in dependency-repo. Defaults to HEAD in default branch. | |
| python-version | string | 3.x | Python version to use. Passed to actions/setup-python. |
| os | string | ubuntu-latest | Operating system to use. Passed to runs-on:. |
| host-extras | string | Extras to use when installing host (package running this workflow). | |
| host-group | string | Group to use when installing host (package running this workflow). | |
| dependency-extras | string | test | Extras to use when installing dependency-repo. |
| dependency-group | string | test | Group to use when installing dependency-repo. |
| qt | string | Version of Qt to install. | |
| post-install-cmd | string | Command(s) to run after installing dependencies. | |
| pytest-args | string | Additional arguments to pass to pytest. Can be used to specify paths or for for -k, -x, etc. |
Here's an example where package Package B depends on Package A.
This workflow would go into Package A's repository, and tests that changes made to Package A don't break Package B.
name: CI
jobs:
test-package-b:
uses: pyapp-kit/workflows/.github/workflows/test-dependents.yml@v2
with:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
dependency-repo: some-org/package-b
dependency-ref: ${{ matrix.package-b-version }}
dependency-group: "test" # Group to use when installing dependency-repo.
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.10", "3.12"]
package-b-version: ["", "v0.5.0"]uses: pyapp-kit/workflows/.github/workflows/upload-coverage.yml@v2
This workflow is designed to be used in conjunction with the test-pyrepo.yml workflow
when the coverage-upload input is set to artifact.
| Input | Type | Default | Description |
|---|---|---|---|
| fail-on-coverage-error | boolean | True | Fail if codecov action fails. |
| artifact-pattern | string | covreport-* | glob pattern to the artifacts that should be downloaded for coverage reports. This should match the name you used for the upload-artifact step in the job that generates the coverage reports. (This default matches the name in test-pyrepo.yml) |
Secrets:
| Input | Description |
|---|---|
| codecov_token | Token for codecov-action. |