Skip to content

Commit

Permalink
feat: python test workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
lengau committed Oct 23, 2024
1 parent 7153678 commit 444d04f
Show file tree
Hide file tree
Showing 8 changed files with 325 additions and 41 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/lint-python.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Lint
on:
workflow_call:
# Because we have a uv.lock file, we can also use this workflow to lint ourselves.
pull_request:
branches:
- main
push:
branches:
- main

jobs:
files:
runs-on: ubuntu-latest
steps:
- name: Begin snap installs of common linters
id: snap-install
run: |
echo -n 'jobs="$(sudo snap install --no-wait codespell ruff shellcheck)"' >> $GITHUB_OUTPUT
- name: Check out code
uses: actions/checkout@v4
- name: Set up uv with caching
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
- name: Set up linters
run: |
for job in ${{ steps.snap-install.jobs }}; do
sudo snap watch $job
done
make setup-lint
- name: Run linters
run: make -k lint
40 changes: 0 additions & 40 deletions .github/workflows/lint.yaml

This file was deleted.

25 changes: 25 additions & 0 deletions .github/workflows/policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Check policy
on:
workflow_call:
pull_request:
branches:
- main
push:
branches:
- main

jobs:
cla:
name: Authors signed Canonical CLA
runs-on: ubuntu-latest
steps:
- name: Check if CLA signed
uses: canonical/has-signed-canonical-cla@v1
commits:
name: Conventional Commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: webiny/[email protected]
with:
allowed-commit-types: "build,chore,ci,docs,feat,fix,perf,refactor,style,test"
17 changes: 17 additions & 0 deletions .github/workflows/self-test-qa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: QA self-test
on:
pull_request:

jobs:
lint-python:
uses: ./.github/workflows/lint-python.yaml
test-python:
uses: ./.github/workflows/test-python.yaml
test-python-custom:
uses: ./.github/workflows/test-python.yaml
with:
unit-platforms: '["ubuntu-latest"]'
unit-python-versions: '["3.14"]'
integration-platforms: '["ubuntu-latest"]'
integration-python-versions: '["3.14"]'
lowest-python-version: '["3.0"]'
124 changes: 124 additions & 0 deletions .github/workflows/test-python.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: Test Python
on:
workflow_call:
inputs:
unit-platforms:
required: false
type: string
default: '["ubuntu-22.04", "ubuntu-24.04", "windows-latest", "macos-latest"]'
description: |
The platforms to run unit tests on, as a JSON array.
unit-python-versions:
required: false
type: string
default: '["3.10", "3.11", "3.12", "3.13"]'
description: |
The python versions to run unit tests on, as a JSON array.
lowest-python-version:
required: false
type: string
description: |
The Python version to run when using "lowest" resolution for unit tests.
integration-platforms:
type: string
default: '["ubuntu-latest", "windows-latest", "macos-latest"]'
description: |
The platforms to run integration tests on, as a JSON array.
integration-python-versions:
required: false
type: string
default: '["3.10"]'
description: |
The python versions to run integration tests on, as a JSON array.
jobs:
unit:
strategy:
matrix:
platform: ${{ fromJson(inputs.unit-platforms) }}
python-version: ${{ fromJson(inputs.unit-python-versions) }}
runs-on: ${{ matrix.platform }}
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up uv with caching
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ${{ matrix.platform }}
- name: Set up tests
run: make setup-tests
- name: Run tests
shell: bash
run: |
make coverage
- name: Upload coverage
if: ${{ inputs.target == 'coverage' }}
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.platform }}-${{ matrix.python-version }}
overwrite: true
path: |
./coverage.xml
htmlcov/**
- name: Run TICS analysis
uses: tiobe/tics-github-action@v3
if: ${{ runner.os == 'Linux' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/tics') }}
with:
mode: qserver
project: ${{ github.repository }}
viewerUrl: https://canonical.tiobe.com/tiobeweb/TICS/api/cfg?name=default
branchdir: ${{ github.workspace }}
ticsAuthToken: ${{ secrets.TICSAUTHTOKEN }}
installTics: true
unit-lowest:
name: unit (minimum deps)
if: ${{ inputs.lowest-python-version }} != ''
runs-on: ubuntu-20.04
env:
UV_PYTHON: ${{ inputs.lowest-python-version }}
UV_RESOLUTION: lowest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up uv with caching
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ${{ matrix.platform }}
- name: Install tools
run: |
make setup-tests
- name: Run unit tests
run: |
make coverage
integration:
strategy:
matrix:
platform: ${{ fromJson(inputs.integration-platforms) }}
python-version: ${{ fromJson(inputs.integration-python-versions) }}
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up uv with caching
id: setup-uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-suffix: ${{ matrix.platform }}
- name: Install tools
run: |
make setup-tests
- name: Integration tests
run: |
make test-integration
env:
PYTEST_ADDOPTS: "--no-header -v -rN"
7 changes: 7 additions & 0 deletions .test-data/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 34 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# https://github.com/snapcrafters/ci/blob/main/Makefile
.PHONY: help
help:
@echo "Usage:"
Expand All @@ -14,3 +13,37 @@ lint:
format:
## format: Formats both Markdown documents and YAML documents to preferred repository style.
npx prettier --print-width=99 --write .

.PHONY: setup
setup: setup-lint
## setup: Install the necessary tools for linting and testing.

.PHONY: setup-lint
setup-lint:
## setup-lint: Install the necessary tools for linting.
ifneq ($(shell which npx),)
else ifneq ($(shell which snap),)
sudo snap install --classic --channel 22 node
else
$(error Cannot find npx. Please install it on your system.)
endif
ifneq ($(shell which shellcheck),)
else ifneq ($(shell which snap),)
sudo snap install shellcheck
else
$(error Cannot find shellcheck. Please install it on your system.)
endif

.PHONY: setup-tests
setup-tests:
echo "Installing nothing..."
echo "Installed!"

.PHONY: test-unit
test-unit:

.PHONY: test-integration
test-integration:

.PHONY: coverage
coverage:
84 changes: 84 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,60 @@ Some of these automations are provided as [Reusable workflows](https://docs.gith
For these workflows, you can embed them in a workflow you run at the `job` level.
Examples are provided below.

## Lint

The lint workflow installs and runs the relevant linters for the repository. It expects the following
`make` targets:

- `setup-lint`: Installs relevant linters (only needs to work on Ubuntu)
- `lint`: Runs relevant linters

### Usage

An example workflow:

```yaml
name: QA
on:
push:
branches:
- "main"
- "feature/*"
- "hotfix/*"
- "release/*"
- "renovate/*"
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: lengau/starflow/lint@work/CRAFT-3602/test-workflows
```
## Policy check
The policy check workflow checks that contributions to the project follow both Canonical corporate policy
and team policy. It checks:
- That the user has signed the Canonical CLA
- That commits follow [Starcraft team standards using Conventional Commits](https://github.com/canonical/starbase/blob/main/HACKING.rst#commits)
### Usage
An example workflow that uses this reusable workflow:
```yaml
name: Check policy
on:
pull_request:

jobs:
policy:
uses: canonical/starflow/.github/workflows/policy.yaml@main
```
## Python security scanner
The Python security scanner workflow uses several tools (trivy, osv-scanner) to scan a
Expand Down Expand Up @@ -94,3 +148,33 @@ jobs:
# Use the standard extra args and ignore spread tests
trivy-extra-args: '--skip-dirs "tests/spread/**"'
```
## Python test runner
The Python test runner workflow uses GitHub workflows and `uv` to run Python tests in
several forms. It:

#. Runs unit tests across multiple platforms and Python versions.
#. Runs unit tests on Ubuntu with the oldest supported python version and uv resolution
set to `lowest`.
#. Integration tests across multiple platforms and Python versions.
#. Uploads coverage for unit tests as artefacts.
#. Runs TICS analysis on unit tests

In order to do so, it expects the following `make` targets:

- `setup-tests`: Configures the system, installing any other necessary tools.
- `coverage`: Runs unit tests with test coverage
- `test-integration`: Runs integration tests

An example workflow:

```yaml
name: Test Python
on:
pull_request:
jobs:
test:
uses: canonical/starflow/.github/workflows/test-python.yaml@main
```

0 comments on commit 444d04f

Please sign in to comment.