@@ -3,73 +3,112 @@ name: Test
33on :
44 push :
55 branches : [main]
6- tags : ["v*"] # Push events to matching v*, i.e. v1.0, v20.15.10
6+ tags : ["v*"]
77 pull_request :
8- branches : ["*"]
8+ branches : [main]
9+ schedule :
10+ - cron : " 0 5 1,15 * *"
11+
12+ concurrency :
13+ group : ${{ github.workflow }}-${{ github.ref }}
14+ cancel-in-progress : true
15+
16+ env :
17+ MPLBACKEND : agg
918
1019jobs :
11- test :
20+ # Dynamically extract the test matrix from hatch so pyproject.toml is the single source of truth.
21+ # See [[tool.hatch.envs.hatch-test.matrix]] in pyproject.toml.
22+ get-environments :
1223 runs-on : ubuntu-latest
24+ outputs :
25+ envs : ${{ steps.get-envs.outputs.envs }}
26+ steps :
27+ - uses : actions/checkout@v5
28+ with :
29+ filter : blob:none
30+ fetch-depth : 0
31+ - name : Install uv
32+ uses : astral-sh/setup-uv@v7
33+ - name : Get test environments
34+ id : get-envs
35+ run : |
36+ ENVS_JSON=$(uvx hatch env show --json | jq -c 'to_entries
37+ | map(
38+ select(.key | startswith("hatch-test"))
39+ | {
40+ name: .key,
41+ label: (if (.key | contains("pre")) then .key + " (PRE-RELEASE DEPENDENCIES)" else .key end),
42+ python: .value.python
43+ }
44+ )')
45+ echo "envs=${ENVS_JSON}" | tee $GITHUB_OUTPUT
46+
47+ test :
48+ needs : get-environments
49+ permissions :
50+ id-token : write # for codecov OIDC
51+
1352 strategy :
1453 fail-fast : false
1554 matrix :
16- env : ["dev-py311", "dev-py313"]
55+ os : [ubuntu-latest]
56+ env : ${{ fromJSON(needs.get-environments.outputs.envs) }}
1757
18- # Configure pytest-xdist
19- env :
20- OMP_NUM_THREADS : " 1"
21- OPENBLAS_NUM_THREADS : " 1"
22- MKL_NUM_THREADS : " 1"
23- NUMEXPR_MAX_THREADS : " 1"
24- MPLBACKEND : " agg"
25- DISPLAY : " :42"
26- PYTEST_ADDOPTS : " -n auto --dist=load --durations=10"
58+ name : ${{ matrix.env.label }}
59+ runs-on : ${{ matrix.os }}
60+ continue-on-error : ${{ contains(matrix.env.name, 'pre') }}
2761
2862 steps :
29- - uses : actions/checkout@v4
30-
31- # Cache rattler's shared package cache (speeds up downloads)
32- - name : Restore rattler cache
33- uses : actions/cache@v4
63+ - uses : actions/checkout@v5
3464 with :
35- path : ~/.cache/rattler
36- key : rattler-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('pyproject.toml') }}
37- restore-keys : |
38- rattler-${{ runner.os }}-${{ matrix.env }}-
39- rattler-${{ runner.os }}-
40-
41- # Install pixi and the requested environment
42- - uses : prefix-dev/setup-pixi@v0.9.0
65+ filter : blob:none
66+ fetch-depth : 0
67+ - name : Install uv
68+ uses : astral-sh/setup-uv@v7
4369 with :
44- environments : ${{ matrix.env }}
45- # We're not comitting the pixi-lock file
46- locked : false
47- cache : false
48- activate-environment : ${{ matrix.env }}
49-
50- - name : Show versions
51- run : |
52- python --version
53- pixi --version
54-
70+ python-version : ${{ matrix.env.python }}
71+ - name : Ensure figure directory exists
72+ run : mkdir -p tests/figures
73+ - name : Create hatch environment
74+ run : uvx hatch env create ${{ matrix.env.name }}
5575 - name : Run tests
5676 env :
57- MPLBACKEND : agg
5877 DISPLAY : " :42"
78+ run : >-
79+ uvx hatch run ${{ matrix.env.name }}:${{
80+ matrix.env.name == 'hatch-test.py3.14-stable' && 'run-cov' || 'run'
81+ }} -v --color=yes ${{
82+ matrix.env.name == 'hatch-test.py3.14-stable' && ' ' || '-n auto'
83+ }}
84+ - name : Generate coverage report
85+ if : matrix.env.name == 'hatch-test.py3.14-stable'
5986 run : |
60- pytest -v --cov --color=yes -- cov-report=xml
61-
62- - name : Archive figures generated during testing
87+ test -f .coverage || uvx hatch run ${{ matrix.env.name }}: cov-combine
88+ uvx hatch run ${{ matrix.env.name }}:cov-report
89+ - name : Archive visual test figures
6390 if : always()
6491 uses : actions/upload-artifact@v4
6592 with :
66- name : visual_test_results_${{ matrix.env }}
67- path : /home/runner/work/spatialdata-plot/spatialdata-plot/tests/figures/*
93+ name : visual_test_results_${{ matrix.env.name }}
94+ path : tests/figures/*
95+ - name : Upload coverage
96+ if : matrix.env.name == 'hatch-test.py3.14-stable'
97+ uses : codecov/codecov-action@v5
98+ with :
99+ fail_ci_if_error : true
100+ use_oidc : true
68101
69- - name : Upload coverage to Codecov
70- uses : codecov/codecov-action@v4
102+ # Single required check for branch protection.
103+ # See https://github.com/re-actors/alls-green#why
104+ check :
105+ name : Tests pass in all hatch environments
106+ if : always()
107+ needs :
108+ - get-environments
109+ - test
110+ runs-on : ubuntu-latest
111+ steps :
112+ - uses : re-actors/alls-green@release/v1
71113 with :
72- name : coverage
73- verbose : true
74- env :
75- CODECOV_TOKEN : ${{ secrets.CODECOV_TOKEN }}
114+ jobs : ${{ toJSON(needs) }}
0 commit comments