1313 FORCE_COLOR : " 3"
1414 UVX_CONSTRAINT : requirements/lock/uvx-tools.txt
1515 UVX_COMMAND : uvx -crequirements/lock/uvx-tools.txt
16+ EXTRA_PYTHON_VERSIONS : " pypy-3.11"
1617
1718permissions : {}
1819
1920jobs :
21+ pre_job :
22+ # continue-on-error: true # Uncomment once integration is finished
23+ runs-on : ubuntu-latest
24+ outputs :
25+ should_skip : ${{ steps.skip_check.outputs.should_skip }}
26+ steps :
27+ - id : skip_check
28+ uses : fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf # v5.3.1
29+ with :
30+ paths_ignore : ' [".cruft.json", ".copier.yml"]'
31+
2032 build-package :
2133 name : Build & verify package
34+ needs : pre_job
35+ if : needs.pre_job.outputs.should_skip != 'true'
2236 runs-on : ubuntu-latest
23-
2437 steps :
2538 - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2639 with :
2740 persist-credentials : false
28-
2941 - uses : hynek/build-and-inspect-python-package@efb823f52190ad02594531168b7a2d5790e66516 # v2.14.0
3042 id : baipp
3143
@@ -40,26 +52,48 @@ jobs:
4052 import json
4153 from pathlib import Path
4254
43- python_versions = json.loads(os.getenv("python_classifiers"))
4455 default_python_version = Path(".python-version").read_text().strip()
56+ python_versions = json.loads(os.getenv("python_classifiers"))
57+ extra_python_versions = [_.strip() for _ in os.getenv("EXTRA_PYTHON_VERSIONS", "").split(",") if _]
58+
59+ min_python_version = python_versions[0]
60+ max_python_version = python_versions[-1]
61+ minmax_python_versions = [min_python_version, max_python_version, *extra_python_versions]
62+ minmax_default_python_versions = list({*minmax_python_versions, default_python_version})
63+ all_python_versions = list({*python_versions, *extra_python_versions})
64+
65+ print("{default_python_version=:s}")
66+ print("{min_python_version=:s}")
67+ print("{max_python_version=:s}")
68+ print("{minmax_python_versions=}")
69+ print("{minmax_default_python_versions=}")
70+ print("{all_python_version=}")
4571
46- # min max and default pythons
47- matrix_test_python = list({ python_versions[0], python_versions[-1], default_python_version, f"pypy-3.11" })
4872
4973 with open(os.getenv("GITHUB_OUTPUT"), "a") as f:
5074 f.write(f"{default_python_version=:s}\n")
51- f.write(f"matrix_test_python={json.dumps(matrix_test_python)}\n")
75+ f.write(f"{min_python_version=:s}\n")
76+ f.write(f"{max_python_version=:s}\n")
77+ f.write(f"minmax_python_versions={json.dumps(minmax_python_versions)}\n")
78+ f.write(f"minmax_default_python_versions={json.dumps(minmax_default_python_versions)}\n")
79+ f.write(f"all_python_versions={json.dumps(all_python_versions)}\n")
5280
5381 outputs :
54- supported-python-versions :
55- ${{ steps.baipp.outputs.supported_python_classifiers_json_array }}
5682 default-python-version :
5783 ${{ steps.versions.outputs.default_python_version }}
58- matrix-test-python : ${{ steps.versions.outputs.matrix_test_python }}
84+ min-python-version : ${{ steps.versions.outputs.min_python_version }}
85+ max-python-version : ${{ steps.versions.outputs.max_python_version }}
86+ minmax-python-versions :
87+ ${{ steps.versions.outputs.minmax_python_versions }}
88+ minmax-default-python-versions :
89+ ${{ steps.versions.outputs.minmax_default_python_versions }}
90+ all-python-version : ${{ steps.versions.outputs.all_python_versions }}
5991
6092 lint :
6193 # only run checks not covered by pre-commit.ci
6294 name : Lint package
95+ needs : pre_job
96+ if : needs.pre_job.outputs.should_skip != 'true'
6397 runs-on : ubuntu-latest
6498 steps :
6599 - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -92,8 +126,27 @@ jobs:
92126 prek run --show-diff-on-failure --color=always --all-files
93127 --hook-stage=manual -v
94128
129+ pinact :
130+ name : Pin actions
131+ needs : pre_job
132+ if : needs.pre_job.outputs.should_skip != 'true'
133+ runs-on : ubuntu-latest
134+ permissions :
135+ contents : write
136+ steps :
137+ - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
138+ with :
139+ persist-credentials : false
140+
141+ - name : Pin actions
142+ uses : suzuki-shunsuke/pinact-action@1081f5ad49ac904b7d977784f338145150a32112 # v1.4.0
143+ with :
144+ skip_push : " true"
145+
95146 typecheck :
96147 name : Typecheck package
148+ needs : pre_job
149+ if : needs.pre_job.outputs.should_skip != 'true'
97150 runs-on : ${{ matrix.os }}
98151 strategy :
99152 fail-fast : false
@@ -121,15 +174,20 @@ jobs:
121174
122175 test :
123176 name : Test package across pythons
124- needs : build-package
177+ needs :
178+ - pre_job
179+ - build-package
180+ if : needs.pre_job.outputs.should_skip != 'true'
125181 runs-on : ${{ matrix.os }}
126182 strategy :
127183 fail-fast : false
128184 matrix :
129185 os :
130186 - ubuntu-latest
131187 python-version :
132- ${{ fromJson(needs.build-package.outputs.matrix-test-python) }}
188+ ${{
189+ fromJson(needs.build-package.outputs.minmax-default-python-versions)
190+ }}
133191 include :
134192 - os : windows-latest
135193 python-version :
@@ -155,7 +213,7 @@ jobs:
155213 shell : bash
156214
157215 - name : Upload coverage data
158- uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 .0.0
216+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 .0.0
159217 with :
160218 name : coverage-data-${{ matrix.os }}-${{ matrix.python-version }}
161219 path : .nox/test-*/tmp/.coverage*
@@ -164,7 +222,10 @@ jobs:
164222
165223 coverage :
166224 name : Combine coverage
167- needs : test
225+ needs :
226+ - pre_job
227+ - test
228+ if : needs.pre_job.outputs.should_skip != 'true'
168229 runs-on : ubuntu-latest
169230
170231 steps :
@@ -194,47 +255,36 @@ jobs:
194255 $UVX_COMMAND nox -s coverage -- ++coverage report ++coverage-options --fail-under=100
195256 shell : bash
196257 - name : Upload HTML report if check failed.
197- uses : actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 .0.0
258+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 .0.0
198259 with :
199260 name : html-report
200261 path : htmlcov
201262 if : ${{ failure() }}
202263
203264 docs :
265+ needs : pre_job
266+ if : needs.pre_job.outputs.should_skip != 'true'
204267 permissions :
205268 contents : write
206269 uses : ./.github/workflows/docs.yml
207270 with :
208271 deploy : false
209272
210- pinact :
211- name : Pin actions
212- runs-on : ubuntu-latest
213- permissions :
214- contents : write
215- steps :
216- - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
217- with :
218- persist-credentials : false
219-
220- - name : Pin actions
221- uses : suzuki-shunsuke/pinact-action@1081f5ad49ac904b7d977784f338145150a32112 # v1.4.0
222- with :
223- skip_push : " true"
224-
225273 # Ensure everything required is passing for branch protection.
226274 required-checks-pass :
227275 if : always()
228276 needs :
277+ - pre_job
229278 - lint
279+ - pinact
230280 - typecheck
231281 - test
232282 - coverage
233- - pinact
234283 - docs
235284 runs-on : ubuntu-latest
236285 steps :
237286 - name : Decide whether the needed jobs succeeded or failed
238287 uses : re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
239288 with :
289+ allowed-skips : " lint,pinact,typecheck,test,coverage,docs"
240290 jobs : ${{ toJSON(needs) }}
0 commit comments