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 :
@@ -23,106 +20,19 @@ concurrency:
2320
2421jobs :
2522 check_source :
26- name : ' Check for source changes'
27- runs-on : ubuntu-latest
28- timeout-minutes : 10
29- outputs :
30- # Some of the referenced steps set outputs conditionally and there may be
31- # cases when referencing them evaluates to empty strings. It is nice to
32- # work with proper booleans so they have to be evaluated through JSON
33- # conversion in the expressions. However, empty strings used like that
34- # may trigger all sorts of undefined and hard-to-debug behaviors in
35- # GitHub Actions CI/CD. To help with this, all of the outputs set here
36- # that are meant to be used as boolean flags (and not arbitrary strings),
37- # MUST have fallbacks with default values set. A common pattern would be
38- # to add ` || false` to all such expressions here, in the output
39- # definitions. They can then later be safely used through the following
40- # idiom in job conditionals and other expressions. Here's some examples:
41- #
42- # if: fromJSON(needs.check_source.outputs.run-docs)
43- #
44- # ${{
45- # fromJSON(needs.check_source.outputs.run_tests)
46- # && 'truthy-branch'
47- # || 'falsy-branch'
48- # }}
49- #
50- run-docs : ${{ steps.docs-changes.outputs.run-docs || false }}
51- run_tests : ${{ steps.check.outputs.run_tests || false }}
52- run_hypothesis : ${{ steps.check.outputs.run_hypothesis || false }}
53- run_cifuzz : ${{ steps.check.outputs.run_cifuzz || false }}
54- config_hash : ${{ steps.config_hash.outputs.hash }} # str
55- steps :
56- - uses : actions/checkout@v4
57- - name : Check for source changes
58- id : check
59- run : |
60- if [ -z "$GITHUB_BASE_REF" ]; then
61- echo "run_tests=true" >> $GITHUB_OUTPUT
62- else
63- git fetch origin $GITHUB_BASE_REF --depth=1
64- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more
65- # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots),
66- # but it requires to download more commits (this job uses
67- # "git fetch --depth=1").
68- #
69- # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git
70- # 2.26, but Git 2.28 is stricter and fails with "no merge base".
71- #
72- # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on
73- # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF
74- # into the PR branch anyway.
75- #
76- # https://github.com/python/core-workflow/issues/373
77- git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc|^\.pre-commit-config\.yaml$|\.ruff\.toml$|\.md$|mypy\.ini$)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true
78- fi
79-
80- # Check if we should run hypothesis tests
81- GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}
82- echo $GIT_BRANCH
83- if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then
84- echo "Branch too old for hypothesis tests"
85- echo "run_hypothesis=false" >> $GITHUB_OUTPUT
86- else
87- echo "Run hypothesis tests"
88- echo "run_hypothesis=true" >> $GITHUB_OUTPUT
89- fi
90-
91- # oss-fuzz maintains a configuration for fuzzing the main branch of
92- # CPython, so CIFuzz should be run only for code that is likely to be
93- # merged into the main branch; compatibility with older branches may
94- # be broken.
95- FUZZ_RELEVANT_FILES='(\.c$|\.h$|\.cpp$|^configure$|^\.github/workflows/build\.yml$|^Modules/_xxtestfuzz)'
96- if [ "$GITHUB_BASE_REF" = "main" ] && [ "$(git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qE $FUZZ_RELEVANT_FILES; echo $?)" -eq 0 ]; then
97- # The tests are pretty slow so they are executed only for PRs
98- # changing relevant files.
99- echo "Run CIFuzz tests"
100- echo "run_cifuzz=true" >> $GITHUB_OUTPUT
101- else
102- echo "Branch too old for CIFuzz tests; or no C files were changed"
103- echo "run_cifuzz=false" >> $GITHUB_OUTPUT
104- fi
105- - name : Compute hash for config cache key
106- id : config_hash
107- run : |
108- echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT
109- - name : Get a list of the changed documentation-related files
110- if : github.event_name == 'pull_request'
111- id : changed-docs-files
112- 113- with :
114- filter : |
115- Doc/**
116- Misc/**
117- .github/workflows/reusable-docs.yml
118- format : csv # works for paths with spaces
119- - name : Check for docs changes
120- if : >-
121- github.event_name == 'pull_request'
122- && steps.changed-docs-files.outputs.added_modified_renamed != ''
123- id : docs-changes
124- run : |
125- echo "run-docs=true" >> "${GITHUB_OUTPUT}"
23+ name : Change detection
24+ # To use boolean outputs from this job, parse them as JSON.
25+ # Here's some examples:
26+ #
27+ # if: fromJSON(needs.check_source.outputs.run-docs)
28+ #
29+ # ${{
30+ # fromJSON(needs.check_source.outputs.run_tests)
31+ # && 'truthy-branch'
32+ # || 'falsy-branch'
33+ # }}
34+ #
35+ uses : ./.github/workflows/reusable-change-detection.yml
12636
12737 check-docs :
12838 name : Docs
@@ -218,55 +128,70 @@ jobs:
218128 arch : ${{ matrix.arch }}
219129 free-threading : ${{ matrix.free-threading }}
220130
221- build_macos :
222- name : ' macOS'
131+ build_windows_msi :
132+ name : >- # ${{ '' } is a hack to nest jobs under the same sidebar category
133+ Windows MSI${{ '' }}
223134 needs : check_source
224- if : needs.check_source.outputs.run_tests == 'true'
225- uses : ./.github/workflows/reusable-macos.yml
135+ if : fromJSON(needs.check_source.outputs.run-win-msi)
136+ strategy :
137+ matrix :
138+ arch :
139+ - x86
140+ - x64
141+ - arm64
142+ uses : ./.github/workflows/reusable-windows-msi.yml
226143 with :
227- config_hash : ${{ needs.check_source.outputs.config_hash }}
228- # Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
229- # Cirrus used for upstream, macos-14 for forks.
230- os-matrix : ' ["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-14", "macos-13"]'
144+ arch : ${{ matrix.arch }}
231145
232- build_macos_free_threading :
233- name : ' macOS (free-threading)'
146+ build_macos :
147+ name : >-
148+ macOS
149+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
234150 needs : check_source
235151 if : needs.check_source.outputs.run_tests == 'true'
152+ strategy :
153+ fail-fast : false
154+ matrix :
155+ # Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
156+ # macOS 13 only runs tests against the GIL-enabled CPython.
157+ # Cirrus used for upstream, macos-14 for forks.
158+ os :
159+ - ghcr.io/cirruslabs/macos-runner:sonoma
160+ - macos-14
161+ - macos-13
162+ is-fork : # only used for the exclusion trick
163+ - ${{ github.repository_owner != 'python' }}
164+ free-threading :
165+ - false
166+ - true
167+ exclude :
168+ - os : ghcr.io/cirruslabs/macos-runner:sonoma
169+ is-fork : true
170+ - os : macos-14
171+ is-fork : false
172+ - os : macos-13
173+ free-threading : true
236174 uses : ./.github/workflows/reusable-macos.yml
237175 with :
238176 config_hash : ${{ needs.check_source.outputs.config_hash }}
239- free-threading : true
240- # Cirrus and macos-14 are M1.
241- # Cirrus used for upstream, macos-14 for forks.
242- os-matrix : ' ["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-14"]'
177+ free-threading : ${{ matrix.free-threading }}
178+ os : ${{ matrix.os }}
243179
244180 build_ubuntu :
245- name : ' Ubuntu'
246- needs : check_source
247- if : needs.check_source.outputs.run_tests == 'true'
248- uses : ./.github/workflows/reusable-ubuntu.yml
249- with :
250- config_hash : ${{ needs.check_source.outputs.config_hash }}
251- options : |
252- ../cpython-ro-srcdir/configure \
253- --config-cache \
254- --with-pydebug \
255- --with-openssl=$OPENSSL_DIR
256-
257- build_ubuntu_free_threading :
258- name : ' Ubuntu (free-threading)'
181+ name : >-
182+ Ubuntu
183+ ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }}
259184 needs : check_source
260185 if : needs.check_source.outputs.run_tests == 'true'
186+ strategy :
187+ matrix :
188+ free-threading :
189+ - false
190+ - true
261191 uses : ./.github/workflows/reusable-ubuntu.yml
262192 with :
263193 config_hash : ${{ needs.check_source.outputs.config_hash }}
264- options : |
265- ../cpython-ro-srcdir/configure \
266- --config-cache \
267- --with-pydebug \
268- --with-openssl=$OPENSSL_DIR \
269- --disable-gil
194+ free-threading : ${{ matrix.free-threading }}
270195
271196 build_ubuntu_ssltests :
272197 name : ' Ubuntu SSL tests with OpenSSL'
@@ -318,7 +243,7 @@ jobs:
318243 with :
319244 save : false
320245 - name : Configure CPython
321- run : ./configure -- config-cache --with-pydebug --with-openssl=$OPENSSL_DIR
246+ run : ./configure CFLAGS="-fdiagnostics-format=json" -- config-cache --enable-slower-safety --with-pydebug --with-openssl=$OPENSSL_DIR
322247 - name : Build CPython
323248 run : make -j4
324249 - name : Display build info
@@ -391,6 +316,7 @@ jobs:
391316 ../cpython-ro-srcdir/configure \
392317 --config-cache \
393318 --with-pydebug \
319+ --enable-slower-safety \
394320 --with-openssl=$OPENSSL_DIR
395321 - name : Build CPython out-of-tree
396322 working-directory : ${{ env.CPYTHON_BUILDDIR }}
@@ -576,12 +502,11 @@ jobs:
576502 - check-docs
577503 - check_generated_files
578504 - build_macos
579- - build_macos_free_threading
580505 - build_ubuntu
581- - build_ubuntu_free_threading
582506 - build_ubuntu_ssltests
583507 - build_wasi
584508 - build_windows
509+ - build_windows_msi
585510 - test_hypothesis
586511 - build_asan
587512 - build_tsan
@@ -596,6 +521,7 @@ jobs:
596521 with :
597522 allowed-failures : >-
598523 build_ubuntu_ssltests,
524+ build_windows_msi,
599525 cifuzz,
600526 test_hypothesis,
601527 allowed-skips : >-
@@ -611,9 +537,7 @@ jobs:
611537 && '
612538 check_generated_files,
613539 build_macos,
614- build_macos_free_threading,
615540 build_ubuntu,
616- build_ubuntu_free_threading,
617541 build_ubuntu_ssltests,
618542 build_wasi,
619543 build_windows,
0 commit comments