@@ -2,7 +2,11 @@ name: CI
22
33on :
44 pull_request :
5- types : [opened, synchronize, reopened, ready_for_review, labeled]
5+ types :
6+ - opened
7+ - synchronize
8+ - reopened
9+ - labeled
610 merge_group :
711 workflow_dispatch :
812 inputs :
2428 required : false
2529 default : ' false'
2630 runner :
27- description : where Build and Test runs (itp-slurm = sCluster via self-hosted dispatch)
31+ description : ' where Build and Test runs: Slurm or the isolated owned Ubuntu runner '
2832 type : choice
29- options : [itp-slurm, hosted]
33+ options :
34+ - itp-slurm
35+ - portable
3036 required : false
3137 default : itp-slurm
3238
3339# A new push cancels superseded PR checks. Label-triggered full-ci compiler
3440# checks keep their own group and do not cancel an ordinary PR run.
41+ push :
42+ branches :
43+ - main
3544concurrency :
36- group : >-
37- ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}-${{
38- github.event.action == 'labeled' && github.event.label.name == 'full-ci' && 'full' || 'std' }}
39- cancel-in-progress : ${{ github.event_name == 'pull_request' && github.event.action != 'labeled' }}
40-
45+ group : ${{ github.workflow }}-${{ github.event.pull_request.number || format('{0}-{1}', github.ref, github.run_id) }}
46+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
4147permissions :
4248 contents : write
4349 pull-requests : write
@@ -50,14 +56,18 @@ jobs:
5056 permissions :
5157 contents : read
5258 name : Changed-line lint
53- runs-on : ubuntu-24.04
54- if : github.event_name == 'pull_request'
59+ runs-on :
60+ - self-hosted
61+ - itp-ubuntu24
62+ if : >-
63+ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')
64+
5565
5666 steps :
5767 - uses : actions/checkout@v6
5868 with :
5969 fetch-depth : 0
60- ref : ${{ github.event.pull_request.head.sha }}
70+ ref : ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }}
6171
6272 - name : Set up Python
6373 uses : actions/setup-python@v6
@@ -72,28 +82,21 @@ jobs:
7282
7383 - name : Check changed lines
7484 run : >-
75- python tools/check_changed_lines.py
76- --base "${{ github.event.pull_request.base.sha }}"
85+ python tools/check_changed_lines.py --base "${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before || format('{0}^', github.sha) }}"
7786
78- # Every PR uses the hosted fast tier, including drafts and forks. The merge
79- # queue runs the full suite on sCluster; dispatch retains its runner choice.
80- # full-ci adds compiler/VMEC++ checks but never moves PR tests onto sCluster .
87+ # Ordinary PR events skip without allocating a runner. Explicit PR validation
88+ # uses the isolated owned Ubuntu runner. The merge queue runs the full suite
89+ # on sCluster; dispatch selects either owned capacity .
8190 test :
8291 name : Build and Test
83- strategy :
84- fail-fast : false
85- matrix :
86- shard : ${{ fromJSON(github.event_name == 'pull_request' && '[1,2]' || '[1]') }}
8792 runs-on : >-
88- ${{ (github.event_name == 'pull_request' ||
89- inputs.runner == 'hosted') && 'ubuntu-24.04' || fromJSON('["self-hosted","itp-slurm"]') }}
93+ ${{ (github.event_name == 'pull_request' || inputs.runner == 'portable' || inputs.runner == 'hosted') && fromJSON('["self-hosted","itp-ubuntu24"]') || fromJSON('["self-hosted","itp-dispatch"]') }}
9094 timeout-minutes : 150
9195 env :
9296 OMP_NUM_THREADS : 2
9397 OPENBLAS_NUM_THREADS : 1
9498 CI_HOSTED : >-
95- ${{ (github.event_name == 'pull_request' ||
96- inputs.runner == 'hosted') && 'true' || 'false' }}
99+ ${{ (github.event_name == 'pull_request' || inputs.runner == 'portable' || inputs.runner == 'hosted') && 'true' || 'false' }}
97100
98101 steps :
99102 - uses : actions/checkout@v6
@@ -102,10 +105,7 @@ jobs:
102105
103106 - name : Set up Python for the offline bundle
104107 if : env.CI_HOSTED != 'true'
105- uses : actions/setup-python@v6
106- with :
107- python-version : " 3.11"
108-
108+ run : python3 --version
109109 - name : Build and test on sCluster
110110 if : env.CI_HOSTED != 'true'
111111 env :
@@ -235,16 +235,14 @@ jobs:
235235
236236 - name : Run Fast Tests (Fortran only)
237237 if : env.CI_HOSTED == 'true' && (github.event_name != 'workflow_dispatch' || inputs.full == 'true')
238- env :
239- TEST_SHARD : ${{ matrix.shard }}
240238 run : |
241239 CTEST_PARALLEL_LEVEL=$(env -u OMP_NUM_THREADS -u OMP_THREAD_LIMIT nproc)
242240 export CTEST_PARALLEL_LEVEL
243241 config=Release
244242 [ "$GITHUB_EVENT_NAME" != pull_request ] || config=Fast
245243 if [ "$GITHUB_EVENT_NAME" = pull_request ]; then
246244 /usr/bin/time -v make test-fast CONFIG="$config" \
247- CTEST_CMD="cd build && ctest --test-dir test --output-on-failure -I $TEST_SHARD,,2 "
245+ CTEST_CMD="cd build && ctest --test-dir test --output-on-failure"
248246 else
249247 /usr/bin/time -v make test-fast CONFIG="$config"
250248 fi
@@ -268,26 +266,26 @@ jobs:
268266 if : always() && env.CI_HOSTED == 'true'
269267 uses : actions/upload-artifact@v6
270268 with :
271- name : ${{ github.event_name == 'pull_request' && format(' test-results-{0}', matrix.shard) || 'test-results' }}
269+ name : test-results
272270 path : |
273271 build/test/Testing/
274272 build/test/tests/golden_record/runs/**/simple.in
275273 build/test/tests/golden_record/runs/**/start.dat
276274 build/test/tests/golden_record/runs/**/times_lost.dat
277275 build/test/tests/golden_record/runs/**/orbit_exit_code.dat
278276
277+ if : >-
278+ github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')
279279 gcc-matrix :
280280 permissions :
281281 contents : read
282282 name : GCC ${{ matrix.gcc }}
283- runs-on : ubuntu-24.04
283+ runs-on :
284+ - self-hosted
285+ - itp-ubuntu24
284286 timeout-minutes : 45
285287 if : >-
286- (github.event_name == 'merge_group' ||
287- (github.event_name == 'workflow_dispatch' && inputs.full == 'true') ||
288- (github.event_name == 'pull_request' && github.event.pull_request.draft == false)) &&
289- (github.event_name != 'pull_request' ||
290- contains(github.event.pull_request.labels.*.name, 'full-ci'))
288+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && ((github.event_name == 'merge_group' || (github.event_name == 'workflow_dispatch' && inputs.full == 'true') || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)) && (github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-ci')))
291289 strategy :
292290 fail-fast : false
293291 matrix :
@@ -311,8 +309,12 @@ jobs:
311309 gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }} gfortran-${{ matrix.gcc }} \
312310 git-lfs cmake ninja-build pkg-config lcov \
313311 libgsl-dev libhdf5-dev libfftw3-dev libnetcdf-dev libnetcdff-dev \
314- libopenblas-dev liblapack-dev openmpi-bin libopenmpi-dev
315- python -m pip install numpy netCDF4
312+ libopenblas-dev liblapack-dev openmpi-bin libopenmpi-dev \
313+ python3-venv
314+ # System pip is externally managed (PEP 668); use a private venv.
315+ python3 -m venv "$RUNNER_TEMP/venv"
316+ "$RUNNER_TEMP/venv/bin/python" -m pip install numpy netCDF4
317+ echo "$RUNNER_TEMP/venv/bin" >> "$GITHUB_PATH"
316318
317319 - name : Build and run tests
318320 env :
@@ -332,8 +334,11 @@ jobs:
332334 permissions :
333335 contents : read
334336 name : Intel ifx smoke tests (non-blocking)
335- runs-on : ubuntu-24.04
336- if : github.event_name == 'workflow_dispatch' && inputs.experimental_compilers
337+ runs-on :
338+ - self-hosted
339+ - itp-ubuntu24
340+ if : >-
341+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (github.event_name == 'workflow_dispatch' && inputs.experimental_compilers)
337342 continue-on-error : true
338343 timeout-minutes : 30
339344 container :
@@ -377,8 +382,11 @@ jobs:
377382 permissions :
378383 contents : read
379384 name : LLVM flang smoke tests (non-blocking)
380- runs-on : ubuntu-24.04
381- if : github.event_name == 'workflow_dispatch' && inputs.experimental_compilers
385+ runs-on :
386+ - self-hosted
387+ - itp-ubuntu24
388+ if : >-
389+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (github.event_name == 'workflow_dispatch' && inputs.experimental_compilers)
382390 continue-on-error : true
383391 timeout-minutes : 30
384392
@@ -415,11 +423,11 @@ jobs:
415423
416424 cgal-wall :
417425 name : CGAL Wall Unit Tests
418- runs-on : ubuntu-24.04
426+ runs-on :
427+ - self-hosted
428+ - itp-ubuntu24
419429 if : >-
420- github.event_name == 'merge_group' ||
421- github.event_name == 'workflow_dispatch' ||
422- github.event_name == 'pull_request'
430+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request')
423431
424432 timeout-minutes : 20
425433 env :
@@ -489,13 +497,11 @@ jobs:
489497
490498 vmecpp :
491499 name : VMEC++ Direct Geometry
492- runs-on : ubuntu-24.04
500+ runs-on :
501+ - self-hosted
502+ - itp-ubuntu24
493503 if : >-
494- (github.event_name == 'merge_group' ||
495- github.event_name == 'workflow_dispatch' ||
496- (github.event_name == 'pull_request' && github.event.pull_request.draft == false)) &&
497- (github.event_name != 'pull_request' ||
498- contains(github.event.pull_request.labels.*.name, 'full-ci'))
504+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && ((github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)) && (github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'full-ci')))
499505
500506 timeout-minutes : 60
501507 env :
@@ -546,9 +552,12 @@ jobs:
546552
547553 build-docs :
548554 name : Build Documentation
549- if : github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'full-ci'))
550- runs-on : ubuntu-24.04
555+ if : >-
556+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (github.event_name == 'workflow_dispatch')
557+ runs-on :
551558
559+ - self-hosted
560+ - itp-ubuntu24
552561 steps :
553562 - uses : actions/checkout@v6
554563
@@ -578,11 +587,14 @@ jobs:
578587
579588 verification-report :
580589 name : Generate Verification Report
581- runs-on : ubuntu-24.04
590+ runs-on :
591+ - self-hosted
592+ - itp-ubuntu24
582593 timeout-minutes : 20
583594 permissions :
584595 contents : read
585- if : github.event_name == 'workflow_dispatch' && inputs.verification_report == 'true'
596+ if : >-
597+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (github.event_name == 'workflow_dispatch' && inputs.verification_report == 'true')
586598 steps :
587599 - uses : actions/checkout@v6
588600 with :
@@ -625,9 +637,12 @@ jobs:
625637 build-and-test-result :
626638 permissions : {}
627639 name : Build and Test
628- if : always()
640+ if : >-
641+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (always())
629642 needs : [test]
630- runs-on : ubuntu-24.04
643+ runs-on :
644+ - self-hosted
645+ - itp-light
631646 steps :
632647 - name : Require successful test shards
633648 env :
@@ -639,9 +654,12 @@ jobs:
639654 ci-result :
640655 permissions : {}
641656 name : CI result
642- if : always()
657+ if : >-
658+ (github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.actor != 'github-merge-queue[bot]')) && (always())
643659 needs : [build-and-test-result, gcc-matrix, cgal-wall, vmecpp]
644- runs-on : ubuntu-24.04
660+ runs-on :
661+ - self-hosted
662+ - itp-light
645663 steps :
646664 - name : Check gating jobs
647665 if : contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
0 commit comments