@@ -27,11 +27,31 @@ jobs:
2727    runs-on : ubuntu-latest 
2828    timeout-minutes : 10 
2929    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+       # 
3050      run-docs : ${{ steps.docs-changes.outputs.run-docs || false }} 
31-       run_tests : ${{ steps.check.outputs.run_tests }} 
32-       run_hypothesis : ${{ steps.check.outputs.run_hypothesis }} 
33-       run_cifuzz : ${{ steps.check.outputs.run_cifuzz }} 
34-       config_hash : ${{ steps.config_hash.outputs.hash }} 
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 
3555    steps :
3656      - uses : actions/checkout@v4 
3757      - name : Check for source changes 
5474            # into the PR branch anyway. 
5575            # 
5676            # https://github.com/python/core-workflow/issues/373 
57-             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  
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  
5878          fi 
5979
6080          # Check if we should run hypothesis tests 
@@ -179,18 +199,24 @@ jobs:
179199        run : make check-c-globals 
180200
181201  build_windows :
182-     name : ' Windows' 
202+     name : >- 
203+       Windows 
204+       ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }} 
183205needs : check_source 
184-     if : needs.check_source.outputs.run_tests == 'true' 
185-     uses : ./.github/workflows/reusable-windows.yml 
186- 
187-   build_windows_free_threading :
188-     name : ' Windows (free-threading)' 
189-     needs : check_source 
190-     if : needs.check_source.outputs.run_tests == 'true' 
206+     if : fromJSON(needs.check_source.outputs.run_tests) 
207+     strategy :
208+       matrix :
209+         arch :
210+         - Win32 
211+         - x64 
212+         - arm64 
213+         free-threading :
214+         - false 
215+         - true 
191216    uses : ./.github/workflows/reusable-windows.yml 
192217    with :
193-       free-threading : true 
218+       arch : ${{ matrix.arch }} 
219+       free-threading : ${{ matrix.free-threading }} 
194220
195221  build_macos :
196222    name : ' macOS' 
@@ -199,8 +225,9 @@ jobs:
199225    uses : ./.github/workflows/reusable-macos.yml 
200226    with :
201227      config_hash : ${{ needs.check_source.outputs.config_hash }} 
202-       #  macos-14 is M1, macos-13 is Intel
203-       os-matrix : ' ["macos-14", "macos-13"]' 
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"]' 
204231
205232  build_macos_free_threading :
206233    name : ' macOS (free-threading)' 
@@ -210,35 +237,25 @@ jobs:
210237    with :
211238      config_hash : ${{ needs.check_source.outputs.config_hash }} 
212239      free-threading : true 
213-       #  macos-14-large is Intel with 12 cores (most parallelism)
214-       os-matrix : ' ["macos-14"]' 
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"]' 
215243
216244  build_ubuntu :
217-     name : ' Ubuntu' 
218-     needs : check_source 
219-     if : needs.check_source.outputs.run_tests == 'true' 
220-     uses : ./.github/workflows/reusable-ubuntu.yml 
221-     with :
222-       config_hash : ${{ needs.check_source.outputs.config_hash }} 
223-       options : | 
224-         ../cpython-ro-srcdir/configure \ 
225-           --config-cache \ 
226-           --with-pydebug \ 
227-           --with-openssl=$OPENSSL_DIR 
228- 
229- build_ubuntu_free_threading :
230-     name : ' Ubuntu (free-threading)' 
245+     name : >- 
246+       Ubuntu 
247+       ${{ fromJSON(matrix.free-threading) && '(free-threading)' || '' }} 
231248needs : check_source 
232249    if : needs.check_source.outputs.run_tests == 'true' 
250+     strategy :
251+       matrix :
252+         free-threading :
253+         - false 
254+         - true 
233255    uses : ./.github/workflows/reusable-ubuntu.yml 
234256    with :
235257      config_hash : ${{ needs.check_source.outputs.config_hash }} 
236-       options : | 
237-         ../cpython-ro-srcdir/configure \ 
238-           --config-cache \ 
239-           --with-pydebug \ 
240-           --with-openssl=$OPENSSL_DIR \ 
241-           --disable-gil 
258+       free-threading : ${{ matrix.free-threading }} 
242259
243260  build_ubuntu_ssltests :
244261    name : ' Ubuntu SSL tests with OpenSSL' 
@@ -290,7 +307,7 @@ jobs:
290307      with :
291308        save : false 
292309    - name : Configure CPython 
293-       run : ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR 
310+       run : ./configure --config-cache --enable-slower-safety -- with-pydebug --with-openssl=$OPENSSL_DIR 
294311    - name : Build CPython 
295312      run : make -j4 
296313    - name : Display build info 
@@ -363,6 +380,7 @@ jobs:
363380        ../cpython-ro-srcdir/configure \ 
364381          --config-cache \ 
365382          --with-pydebug \ 
383+           --enable-slower-safety \ 
366384          --with-openssl=$OPENSSL_DIR 
367385name : Build CPython out-of-tree 
368386      working-directory : ${{ env.CPYTHON_BUILDDIR }} 
@@ -391,7 +409,7 @@ jobs:
391409        path : ${{ env.CPYTHON_BUILDDIR }}/.hypothesis/ 
392410        key : hypothesis-database-${{ github.head_ref || github.run_id }} 
393411        restore-keys : | 
394-           -  hypothesis-database- 
412+           hypothesis-database- 
395413name : " Run tests" 
396414      working-directory : ${{ env.CPYTHON_BUILDDIR }} 
397415      run : | 
@@ -550,11 +568,9 @@ jobs:
550568    - build_macos 
551569    - build_macos_free_threading 
552570    - build_ubuntu 
553-     - build_ubuntu_free_threading 
554571    - build_ubuntu_ssltests 
555572    - build_wasi 
556573    - build_windows 
557-     - build_windows_free_threading 
558574    - test_hypothesis 
559575    - build_asan 
560576    - build_tsan 
@@ -586,11 +602,9 @@ jobs:
586602            build_macos, 
587603            build_macos_free_threading, 
588604            build_ubuntu, 
589-             build_ubuntu_free_threading, 
590605            build_ubuntu_ssltests, 
591606            build_wasi, 
592607            build_windows, 
593-             build_windows_free_threading, 
594608            build_asan, 
595609            build_tsan, 
596610            build_tsan_free_threading, 
0 commit comments