2424
2525 strategy :
2626 matrix :
27- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
27+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
28+ free_threaded : [false, true]
29+ exclude :
30+ - python : ' 3.10'
31+ free_threaded : true
32+ - python : ' 3.11'
33+ free_threaded : true
34+ - python : ' 3.12'
35+ free_threaded : true
36+ - python : ' 3.13'
37+ free_threaded : true
2838 steps :
2939 - name : Cancel Previous Runs
3040 uses : styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0
@@ -57,26 +67,28 @@ jobs:
5767 shell : bash -l {0}
5868 run : |
5969 echo "WHEELS_OUTPUT_FOLDER=$GITHUB_WORKSPACE${{ runner.os == 'Linux' && '/' || '\\' }}" >> $GITHUB_ENV
60- - name : Build conda package
70+ - name : Build conda package (Python 3.14 with GIL)
71+ if : ${{ matrix.python == '3.14' && !matrix.free_threaded }}
6172 run : |
6273 # use bootstrap channel to pull NumPy linked with OpenBLAS
6374 CHANNELS="-c conda-forge --override-channels"
64- VERSIONS="--python ${{ matrix.python }} --numpy 2.0"
65- TEST="--no-test"
66- conda build \
67- $TEST \
68- $VERSIONS \
69- $CHANNELS \
70- conda-recipe
75+ conda build --no-test --extra-deps python-gil --python ${{ matrix.python }} --numpy 2.0 $CHANNELS conda-recipe
76+
77+ - name : Build conda package (default)
78+ if : ${{ matrix.python != '3.14' || matrix.free_threaded }}
79+ run : |
80+ # use bootstrap channel to pull NumPy linked with OpenBLAS
81+ CHANNELS="-c conda-forge --override-channels"
82+ conda build --no-test --python ${{ matrix.python }} --numpy 2.0 $CHANNELS conda-recipe
7183 - name : Upload artifact
7284 uses : actions/upload-artifact@v6.0.0
7385 with :
74- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
86+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
7587 path : /usr/share/miniconda/conda-bld/linux-64/${{ env.PACKAGE_NAME }}-*.conda
7688 - name : Upload wheels artifact
7789 uses : actions/upload-artifact@v6.0.0
7890 with :
79- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}
91+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
8092 path : ${{ env.WHEELS_OUTPUT_FOLDER }}${{ env.PACKAGE_NAME }}-*.whl
8193
8294 build_windows :
8597
8698 strategy :
8799 matrix :
88- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
100+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
101+ free_threaded : [false, true]
102+ exclude :
103+ - python : ' 3.10'
104+ free_threaded : true
105+ - python : ' 3.11'
106+ free_threaded : true
107+ - python : ' 3.12'
108+ free_threaded : true
109+ - python : ' 3.13'
110+ free_threaded : true
89111 steps :
90112 - name : Cancel Previous Runs
91113 uses : styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0
@@ -129,7 +151,17 @@ jobs:
129151 echo "CONDA_BLD=$CONDA/conda-bld/win-64/" | tr "\\\\" '/' >> $GITHUB_ENV
130152 echo "WHEELS_OUTPUT_FOLDER=$GITHUB_WORKSPACE${{ runner.os == 'Linux' && '/' || '\\' }}" >> $GITHUB_ENV
131153
132- - name : Build conda package
154+ - name : Build conda package (Python 3.14 with GIL)
155+ if : ${{ matrix.python == '3.14' && !matrix.free_threaded }}
156+ env :
157+ OVERRIDE_INTEL_IPO : 1 # IPO requires more resources that GH actions VM provides
158+ run : |
159+ conda activate
160+ # TODO: roll back use of Intel channel when 2025.1 is available on conda-forge
161+ conda build --no-test --extra-deps python-gil --python ${{ matrix.python }} --numpy 2.0 -c ${{ env.INTEL_CHANNEL }} -c conda-forge --override-channels conda-recipe
162+
163+ - name : Build conda package (default)
164+ if : ${{ matrix.python != '3.14' || matrix.free_threaded }}
133165 env :
134166 OVERRIDE_INTEL_IPO : 1 # IPO requires more resources that GH actions VM provides
135167 run : |
@@ -140,13 +172,13 @@ jobs:
140172 - name : Upload artifact
141173 uses : actions/upload-artifact@v6.0.0
142174 with :
143- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
175+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
144176 path : ${{ env.CONDA_BLD }}${{ env.PACKAGE_NAME }}-*.conda
145177
146178 - name : Upload wheels artifact
147179 uses : actions/upload-artifact@v6.0.0
148180 with :
149- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}
181+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
150182 path : ${{ env.WHEELS_OUTPUT_FOLDER }}${{ env.PACKAGE_NAME }}-*.whl
151183
152184 test_linux :
@@ -156,7 +188,17 @@ jobs:
156188
157189 strategy :
158190 matrix :
159- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
191+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
192+ free_threaded : [false, true]
193+ exclude :
194+ - python : ' 3.10'
195+ free_threaded : true
196+ - python : ' 3.11'
197+ free_threaded : true
198+ - python : ' 3.12'
199+ free_threaded : true
200+ - python : ' 3.13'
201+ free_threaded : true
160202 experimental : [false]
161203 runner : [ubuntu-22.04]
162204 continue-on-error : ${{ matrix.experimental }}
@@ -171,7 +213,7 @@ jobs:
171213 - name : Download artifact
172214 uses : actions/download-artifact@v7
173215 with :
174- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
216+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
175217 - name : Add conda to system path
176218 run : echo $CONDA/bin >> $GITHUB_PATH
177219 - name : Install conda-index
@@ -191,8 +233,12 @@ jobs:
191233 - name : Collect dependencies
192234 run : |
193235 CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}"
236+ PY_GIL_SPEC=""
237+ if [ "${{ matrix.python }}" = "3.14" ] && [ "${{ matrix.free_threaded }}" = "false" ]; then
238+ PY_GIL_SPEC="python-gil"
239+ fi
194240 export PACKAGE_VERSION=$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")
195- conda create -n ${{ env.TEST_ENV_NAME }} $PACKAGE_NAME=${PACKAGE_VERSION} python=${{ matrix.python }} $CHANNELS --only-deps --dry-run > lockfile
241+ conda create -n ${{ env.TEST_ENV_NAME }} $PACKAGE_NAME=${PACKAGE_VERSION} python=${{ matrix.python }} $PY_GIL_SPEC $ CHANNELS --only-deps --dry-run > lockfile
196242 cat lockfile
197243 - name : Set pkgs_dirs
198244 run : |
@@ -211,9 +257,13 @@ jobs:
211257 - name : Install dpctl
212258 run : |
213259 export CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}"
214- export TEST_DEPENDENCIES="pytest pytest-cov cython setuptools"
260+ PY_GIL_SPEC=""
261+ if [ "${{ matrix.python }}" = "3.14" ] && [ "${{ matrix.free_threaded }}" = "false" ]; then
262+ PY_GIL_SPEC="python-gil"
263+ fi
264+ export TEST_DEPENDENCIES="pytest cython setuptools"
215265 export PACKAGE_VERSION=$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")
216- conda create -n ${{ env.TEST_ENV_NAME }} $PACKAGE_NAME=${PACKAGE_VERSION} ${TEST_DEPENDENCIES} python=${{ matrix.python }} ${CHANNELS}
266+ conda create -n ${{ env.TEST_ENV_NAME }} $PACKAGE_NAME=${PACKAGE_VERSION} ${TEST_DEPENDENCIES} python=${{ matrix.python }} ${PY_GIL_SPEC} ${ CHANNELS}
217267 # Test installed packages
218268 conda list -n ${{ env.TEST_ENV_NAME }}
219269 - name : Smoke test
@@ -252,7 +302,17 @@ jobs:
252302 shell : cmd /C CALL {0}
253303 strategy :
254304 matrix :
255- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
305+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
306+ free_threaded : [false, true]
307+ exclude :
308+ - python : ' 3.10'
309+ free_threaded : true
310+ - python : ' 3.11'
311+ free_threaded : true
312+ - python : ' 3.12'
313+ free_threaded : true
314+ - python : ' 3.13'
315+ free_threaded : true
256316 experimental : [false]
257317 runner : [windows-latest]
258318 continue-on-error : ${{ matrix.experimental }}
@@ -272,7 +332,7 @@ jobs:
272332 - name : Download artifact
273333 uses : actions/download-artifact@v7
274334 with :
275- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
335+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
276336
277337 - uses : conda-incubator/setup-miniconda@v3
278338 with :
@@ -329,7 +389,9 @@ jobs:
329389 FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO (
330390 SET PACKAGE_VERSION=%%F
331391 )
332- conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile
392+ SET PY_GIL_SPEC=
393+ IF "${{ matrix.python }}"=="3.14" IF "${{ matrix.free_threaded }}"=="false" SET PY_GIL_SPEC=python-gil
394+ conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} %PY_GIL_SPEC% -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile
333395
334396 - name : Display lockfile content
335397 shell : pwsh
@@ -362,8 +424,10 @@ jobs:
362424 FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO (
363425 SET PACKAGE_VERSION=%%F
364426 )
365- SET TEST_DEPENDENCIES=pytest"<8" pytest-cov cython setuptools
366- conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %TEST_DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }}
427+ SET PY_GIL_SPEC=
428+ IF "${{ matrix.python }}"=="3.14" IF "${{ matrix.free_threaded }}"=="false" SET PY_GIL_SPEC=python-gil
429+ SET TEST_DEPENDENCIES=pytest"<8" cython setuptools
430+ conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %TEST_DEPENDENCIES% python=${{ matrix.python }} %PY_GIL_SPEC% -c ${{ env.workdir }}/channel ${{ env.CHANNELS }}
367431
368432 - name : Report content of test environment
369433 shell : cmd /C CALL {0}
@@ -423,17 +487,27 @@ jobs:
423487 timeout-minutes : 20
424488 strategy :
425489 matrix :
426- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
490+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
491+ free_threaded : [false, true]
492+ exclude :
493+ - python : ' 3.10'
494+ free_threaded : true
495+ - python : ' 3.11'
496+ free_threaded : true
497+ - python : ' 3.12'
498+ free_threaded : true
499+ - python : ' 3.13'
500+ free_threaded : true
427501 steps :
428502 - name : Download conda artifact
429503 uses : actions/download-artifact@v7
430504 with :
431- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
505+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
432506
433507 - name : Download wheel artifact
434508 uses : actions/download-artifact@v7
435509 with :
436- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}
510+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
437511
438512 - name : Install anaconda-client
439513 run : conda install anaconda-client -c conda-forge --override-channels
@@ -467,17 +541,27 @@ jobs:
467541 timeout-minutes : 20
468542 strategy :
469543 matrix :
470- python : ['3.10', '3.11', '3.12', '3.13', '3.13t', '3.14', '3.14t']
544+ python : ['3.10', '3.11', '3.12', '3.13', '3.14']
545+ free_threaded : [false, true]
546+ exclude :
547+ - python : ' 3.10'
548+ free_threaded : true
549+ - python : ' 3.11'
550+ free_threaded : true
551+ - python : ' 3.12'
552+ free_threaded : true
553+ - python : ' 3.13'
554+ free_threaded : true
471555 steps :
472556 - name : Download artifact
473557 uses : actions/download-artifact@v7
474558 with :
475- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}
559+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
476560
477561 - name : Download wheel artifact
478562 uses : actions/download-artifact@v7
479563 with :
480- name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}
564+ name : ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }}${{ matrix.free_threaded && 't' || '' }}
481565
482566 - uses : conda-incubator/setup-miniconda@v3
483567 with :
0 commit comments