11name : Tests
22
3- # gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because
4- # it prevents to mark a job as mandatory. A PR cannot be merged if a job is
5- # mandatory but not scheduled because of "paths-ignore".
63on :
74 workflow_dispatch :
85 push :
@@ -31,70 +28,19 @@ concurrency:
3128
3229jobs :
3330 check_source :
34- name : ' Check for source changes'
35- runs-on : ubuntu-latest
36- timeout-minutes : 10
37- outputs :
38- run-docs : ${{ steps.docs-changes.outputs.run-docs || false }}
39- run_tests : ${{ steps.check.outputs.run_tests }}
40- run_hypothesis : ${{ steps.check.outputs.run_hypothesis }}
41- config_hash : ${{ steps.config_hash.outputs.hash }}
42- steps :
43- - uses : actions/checkout@v4
44- - name : Check for source changes
45- id : check
46- run : |
47- if [ -z "$GITHUB_BASE_REF" ]; then
48- echo "run_tests=true" >> $GITHUB_OUTPUT
49- else
50- git fetch origin $GITHUB_BASE_REF --depth=1
51- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
52- # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
53- # but it requires to download more commits (this job uses
54- # "git fetch --depth=1").
55- #
56- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
57- # 2.26, but Git 2.28 is stricter and fails with "no merge base".
58- #
59- # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
60- # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
61- # into the PR branch anyway.
62- #
63- # https://github.com/python/core-workflow/issues/373
64- git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc|^\.pre-commit-config\.yaml$|\.ruff\.toml$)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
65- fi
66-
67- # Check if we should run hypothesis tests
68- GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
69- echo $GIT_BRANCH
70- if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then
71- echo "Branch too old for hypothesis tests"
72- echo "run_hypothesis=false" >> $GITHUB_OUTPUT
73- else
74- echo "Run hypothesis tests"
75- echo "run_hypothesis=true" >> $GITHUB_OUTPUT
76- fi
77- - name : Compute hash for config cache key
78- id : config_hash
79- run : |
80- echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
81- - name : Get a list of the changed documentation-related files
82- if : github.event_name == 'pull_request'
83- id : changed-docs-files
84- uses : Ana06/get-changed-files@v2.3.0
85- with :
86- filter : |
87- Doc/**
88- Misc/**
89- .github/workflows/reusable-docs.yml
90- format : csv # works for paths with spaces
91- - name : Check for docs changes
92- if : >-
93- github.event_name == 'pull_request'
94- && steps.changed-docs-files.outputs.added_modified_renamed != ''
95- id : docs-changes
96- run : |
97- echo "run-docs=true" >> "${GITHUB_OUTPUT}"
31+ name : Change detection
32+ # To use boolean outputs from this job, parse them as JSON.
33+ # Here's some examples:
34+ #
35+ # if: fromJSON(needs.check_source.outputs.run-docs)
36+ #
37+ # ${{
38+ # fromJSON(needs.check_source.outputs.run_tests)
39+ # && 'truthy-branch'
40+ # || 'falsy-branch'
41+ # }}
42+ #
43+ uses : ./.github/workflows/reusable-change-detection.yml
9844
9945 check-docs :
10046 name : Docs
@@ -216,42 +162,101 @@ jobs:
216162 run : make check-c-globals
217163
218164 build_windows :
219- name : ' Windows'
165+ name : >-
166+ Windows
167+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
220168 needs : check_source
221- if : needs.check_source.outputs.run_tests == 'true'
169+ if : fromJSON(needs.check_source.outputs.run_tests)
170+ strategy :
171+ matrix :
172+ arch :
173+ - Win32
174+ - x64
175+ - arm64
176+ free-threading :
177+ - false
178+ # - true
222179 uses : ./.github/workflows/reusable-windows.yml
180+ with :
181+ arch : ${{ matrix.arch }}
182+ free-threading : ${{ matrix.free-threading }}
183+
184+ build_windows_msi :
185+ name : >- # ${{ '' } is a hack to nest jobs under the same sidebar category
186+ Windows MSI${{ '' }}
187+ needs : check_source
188+ if : fromJSON(needs.check_source.outputs.run-win-msi)
189+ strategy :
190+ matrix :
191+ arch :
192+ - x86
193+ - x64
194+ - arm64
195+ uses : ./.github/workflows/reusable-windows-msi.yml
196+ with :
197+ arch : ${{ matrix.arch }}
223198
224199 build_macos :
225- name : ' macOS'
200+ name : >-
201+ macOS
202+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
226203 needs : check_source
227204 if : needs.check_source.outputs.run_tests == 'true'
205+ strategy :
206+ fail-fast : false
207+ matrix :
208+ # Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
209+ # macOS 13 only runs tests against the GIL-enabled CPython.
210+ # Cirrus used for upstream, macos-14 for forks.
211+ os :
212+ - ghcr.io/cirruslabs/macos-runner:sonoma
213+ - macos-14
214+ - macos-13
215+ is-fork : # only used for the exclusion trick
216+ - ${{ github.repository_owner != 'python' }}
217+ free-threading :
218+ - false
219+ # - true
220+ exclude :
221+ - os : ghcr.io/cirruslabs/macos-runner:sonoma
222+ is-fork : true
223+ - os : macos-14
224+ is-fork : false
225+ - os : macos-13
226+ free-threading : true
228227 uses : ./.github/workflows/reusable-macos.yml
229228 with :
230229 config_hash : ${{ needs.check_source.outputs.config_hash }}
230+ free-threading : ${{ matrix.free-threading }}
231+ os : ${{ matrix.os }}
231232
232233 build_ubuntu :
233- name : ' Ubuntu'
234+ name : >-
235+ Ubuntu
236+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
234237 needs : check_source
235238 if : needs.check_source.outputs.run_tests == 'true'
239+ strategy :
240+ matrix :
241+ free-threading :
242+ - false
243+ # - true
236244 uses : ./.github/workflows/reusable-ubuntu.yml
237245 with :
238246 config_hash : ${{ needs.check_source.outputs.config_hash }}
239- options : |
240- ../cpython-ro-srcdir/configure \
241- --config-cache \
242- --with-pydebug \
243- --with-openssl=$OPENSSL_DIR
247+ free-threading : ${{ matrix.free-threading }}
244248
245249 build_ubuntu_ssltests :
246250 name : ' Ubuntu SSL tests with OpenSSL'
247- runs-on : ubuntu-22.04
251+ runs-on : ${{ matrix.os }}
248252 timeout-minutes : 60
249253 needs : check_source
250254 if : needs.check_source.outputs.run_tests == 'true'
251255 strategy :
252256 fail-fast : false
253257 matrix :
254- openssl_ver : [1.1.1w, 3.0.13, 3.1.5, 3.2.1]
258+ os : [ubuntu-22.04]
259+ openssl_ver : [3.0.15, 3.1.7, 3.2.3, 3.3.2]
255260 env :
256261 OPENSSL_VER : ${{ matrix.openssl_ver }}
257262 MULTISSL_DIR : ${{ github.workspace }}/multissl
@@ -280,7 +285,7 @@ jobs:
280285 uses : actions/cache@v4
281286 with :
282287 path : ./multissl/openssl/${{ env.OPENSSL_VER }}
283- key : ${{ runner .os }}-multissl-openssl-${{ env.OPENSSL_VER }}
288+ key : ${{ matrix .os }}-multissl-openssl-${{ env.OPENSSL_VER }}
284289 - name : Install OpenSSL
285290 if : steps.cache-openssl.outputs.cache-hit != 'true'
286291 run : python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
@@ -307,7 +312,7 @@ jobs:
307312 needs : check_source
308313 if : needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_hypothesis == 'true'
309314 env :
310- OPENSSL_VER : 3.0.13
315+ OPENSSL_VER : 3.0.15
311316 PYTHONSTRICTEXTENSIONBUILD : 1
312317 steps :
313318 - uses : actions/checkout@v4
@@ -385,7 +390,7 @@ jobs:
385390 path : ./hypothesis
386391 key : hypothesis-database-${{ github.head_ref || github.run_id }}
387392 restore-keys : |
388- - hypothesis-database-
393+ hypothesis-database-
389394 - name : " Run tests"
390395 working-directory : ${{ env.CPYTHON_BUILDDIR }}
391396 run : |
@@ -420,7 +425,7 @@ jobs:
420425 needs : check_source
421426 if : needs.check_source.outputs.run_tests == 'true'
422427 env :
423- OPENSSL_VER : 3.0.13
428+ OPENSSL_VER : 3.0.15
424429 PYTHONSTRICTEXTENSIONBUILD : 1
425430 ASAN_OPTIONS : detect_leaks=0:allocator_may_return_null=1:handle_segv=0
426431 steps :
@@ -450,7 +455,7 @@ jobs:
450455 uses : actions/cache@v4
451456 with :
452457 path : ./multissl/openssl/${{ env.OPENSSL_VER }}
453- key : ${{ runner .os }}-multissl-openssl-${{ env.OPENSSL_VER }}
458+ key : ${{ matrix .os }}-multissl-openssl-${{ env.OPENSSL_VER }}
454459 - name : Install OpenSSL
455460 if : steps.cache-openssl.outputs.cache-hit != 'true'
456461 run : python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux
@@ -492,6 +497,7 @@ jobs:
492497 - build_ubuntu
493498 - build_ubuntu_ssltests
494499 - build_windows
500+ - build_windows_msi
495501 - test_hypothesis
496502 - build_asan
497503 - build_tsan
@@ -505,6 +511,7 @@ jobs:
505511 allowed-failures : >-
506512 build_macos,
507513 build_ubuntu_ssltests,
514+ build_windows_msi,
508515 test_hypothesis,
509516 allowed-skips : >-
510517 ${{
0 commit comments