-
Notifications
You must be signed in to change notification settings - Fork 330
704 lines (653 loc) · 25.9 KB
/
Copy pathci.yml
File metadata and controls
704 lines (653 loc) · 25.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Note: This name is referred to in the test job, so make sure any changes are sync'd up!
# Further this is referencing a run in the backport branch to fetch old bindings.
name: "CI"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
on:
push:
branches:
- "pull-request/[0-9]+"
- "main"
tags:
# Build release artifacts from tag refs so setuptools-scm resolves exact
# release versions instead of .dev+local variants.
- "v*"
- "cuda-core-v*"
- "cuda-pathfinder-v*"
schedule:
# every 24 hours at midnight UTC
- cron: "0 0 * * *"
workflow_dispatch: {}
jobs:
ci-vars:
if: ${{ github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
outputs:
CUDA_BUILD_VER: ${{ steps.get-vars.outputs.cuda_build_ver }}
CUDA_PREV_BUILD_VER: ${{ steps.get-vars.outputs.cuda_prev_build_ver }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
- name: Get CUDA build versions
id: get-vars
run: |
cuda_build_ver=$(yq '.cuda.build.version' ci/versions.yml)
echo "cuda_build_ver=$cuda_build_ver" >> $GITHUB_OUTPUT
cuda_prev_build_ver=$(yq '.cuda.prev_build.version' ci/versions.yml)
echo "cuda_prev_build_ver=$cuda_prev_build_ver" >> $GITHUB_OUTPUT
should-skip:
if: ${{ github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
skip: ${{ steps.get-should-skip.outputs.skip }}
doc-only: ${{ steps.get-should-skip.outputs.doc_only }}
base-ref: ${{ steps.get-should-skip.outputs.base_ref }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Compute whether to skip builds and tests
id: get-should-skip
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euxo pipefail
if ${{ startsWith(github.ref_name, 'pull-request/') }}; then
pr_number="$(grep -Po '(\d+)$' <<< '${{ github.ref_name }}')"
pr="$(gh pr view "${pr_number}" --json baseRefName,title)"
pr_title="$(jq -r '.title' <<< "${pr}")"
base_ref="$(jq -r '.baseRefName' <<< "${pr}")"
skip="$(echo "${pr_title}" | grep -q '\[no-ci\]' && echo true || echo false)"
doc_only="$(echo "${pr_title}" | grep -q '\[doc-only\]' && echo true || echo false)"
else
skip=false
doc_only=false
base_ref=""
fi
echo "skip=${skip}" >> "$GITHUB_OUTPUT"
echo "doc_only=${doc_only}" >> "$GITHUB_OUTPUT"
echo "base_ref=${base_ref}" >> "$GITHUB_OUTPUT"
# Detect which packages were touched by the PR so downstream build and test
# jobs can avoid rebuilding/retesting packages unaffected by the change.
# See issue #299.
#
# Dependency graph (verified in pyproject.toml files):
# cuda_pathfinder -> (no internal deps)
# cuda_bindings -> cuda_pathfinder
# cuda_core -> cuda_pathfinder, cuda_bindings
# cuda_python -> cuda_pathfinder, cuda_bindings, cuda_core (meta package)
#
# A change to cuda_pathfinder (or shared infra) forces a rebuild of every
# downstream module. A change to cuda_bindings forces rebuild of cuda_core.
# A change to cuda_core alone skips rebuilding/retesting cuda_bindings and
# cuda_pathfinder, but still retests the downstream cuda-python metapackage.
# Shared build/orchestration changes run the full pipeline; test-only CI
# infrastructure runs every test suite without rebuilding package wheels.
# On push to main, tag refs, schedule, or workflow_dispatch events we
# unconditionally run everything because there is no meaningful "changed
# paths" baseline for those events.
detect-changes:
if: ${{ github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
needs: should-skip
permissions:
actions: read
contents: read
outputs:
workplan: ${{ steps.workplan.outputs.workplan }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# Treeless clone: the commit graph is needed to resolve the PR merge
# base and classify its changed paths, but historical blobs aren't.
fetch-depth: 0
filter: blob:none
- name: Resolve PR merge base
id: merge-base
if: ${{ startsWith(github.ref_name, 'pull-request/') }}
env:
BASE_REF: ${{ needs.should-skip.outputs.base-ref }}
run: |
set -euo pipefail
if [[ -z "${BASE_REF}" ]]; then
echo "Could not resolve PR base branch" >&2
exit 1
fi
base=$(git merge-base HEAD "origin/${BASE_REF}")
echo "sha=${base}" >> "$GITHUB_OUTPUT"
- name: Resolve reusable base artifacts
id: baseline
if: ${{ startsWith(github.ref_name, 'pull-request/') }}
env:
BASE_REF: ${{ needs.should-skip.outputs.base-ref }}
MERGE_BASE: ${{ steps.merge-base.outputs.sha }}
GH_TOKEN: ${{ github.token }}
run: |
set -uo pipefail
unavailable() {
echo "No complete reusable artifact set was found; this run will build and test everything." >> "$GITHUB_STEP_SUMMARY"
exit 0
}
if [[ -z "${BASE_REF}" ]]; then
unavailable
fi
merge_base="${MERGE_BASE}"
if [[ -z "${merge_base}" ]]; then
unavailable
fi
if ! runs=$(gh run list \
--repo "${{ github.repository }}" \
--branch "${BASE_REF}" \
--commit "${merge_base}" \
--event push \
--workflow ci.yml \
--status success \
--limit 1 \
--json databaseId,headSha); then
unavailable
fi
# Reuse only artifacts produced from the exact commit used as the
# PR diff base. Using the latest base-branch run is unsafe for a PR
# that was opened before newer changes landed on that branch.
run_id=$(jq -r '.[0].databaseId // empty' <<< "$runs")
run_sha=$(jq -r '.[0].headSha // empty' <<< "$runs")
if [[ -z "${run_id}" || "${run_sha}" != "${merge_base}" ]]; then
unavailable
fi
if ! artifact_names=$(gh api \
"repos/${{ github.repository }}/actions/runs/${run_id}/artifacts?per_page=100" \
--paginate \
--jq '.artifacts[] | select(.expired == false) | .name'); then
unavailable
fi
has_artifact() {
grep -Fxq "$1" <<< "$artifact_names"
}
missing=()
for name in cuda-pathfinder-wheel cuda-python-wheel; do
has_artifact "$name" || missing+=("$name")
done
cuda_version=$(yq '.cuda.build.version' ci/versions.yml)
if ! python_versions=$(yq -r '.jobs.build.strategy.matrix."python-version"[]' .github/workflows/build-wheel.yml); then
unavailable
fi
if ! platforms=$(yq -r '.platforms[]' ci/test-matrix.yml); then
unavailable
fi
if [[ -z "${python_versions}" || -z "${platforms}" ]]; then
unavailable
fi
while IFS= read -r python_version; do
python=${python_version//./}
while IFS= read -r platform; do
binding="cuda-bindings-python${python}-cuda${cuda_version}-${platform}-${merge_base}"
core="cuda-core-python${python}-${platform}-${merge_base}"
has_artifact "$binding" || missing+=("$binding")
has_artifact "$core" || missing+=("$core")
done <<< "${platforms}"
done <<< "${python_versions}"
if (( ${#missing[@]} != 0 )); then
printf 'Missing reusable artifact: %s\n' "${missing[@]}" >&2
unavailable
fi
echo "run_id=${run_id}" >> "$GITHUB_OUTPUT"
{
echo
echo "Reusable artifacts: run \`${run_id}\` at \`${merge_base}\` on \`${BASE_REF}\`."
} >> "$GITHUB_STEP_SUMMARY"
- name: Test CI workplan planner
run: python3 -m unittest ci/tools/tests/test_compute_ci_plan.py
- name: Compute CI workplan
id: workplan
env:
MERGE_BASE: ${{ steps.merge-base.outputs.sha }}
BASELINE_RUN_ID: ${{ steps.baseline.outputs.run_id }}
run: |
set -euo pipefail
workplan=$(python3 ci/tools/compute_ci_plan.py \
--merge-base "$MERGE_BASE" \
--baseline-run-id "$BASELINE_RUN_ID")
echo "workplan=$workplan" >> "$GITHUB_OUTPUT"
{
echo
echo "### CI workplan"
echo '```json'
jq . <<< "$workplan"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
api-check-core-vs-release:
name: API check (cuda_core vs. latest release)
if: >-
${{ !fromJSON(needs.should-skip.outputs.skip) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.core_api_checks }}
runs-on: ubuntu-latest
needs:
- should-skip
- detect-changes
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
filter: blob:none
- name: Find latest release tag
id: latest-tag
shell: bash --noprofile --norc -euo pipefail {0}
env:
GH_TOKEN: ${{ github.token }}
run: |
# --paginate fetches all pages; jq outputs one name per line per page;
# sed prints the first (newest) match while consuming all pages, so
# gh can complete without SIGPIPE. Fails if no cuda-core-v* tag is found.
tag="$(gh api "repos/$GITHUB_REPOSITORY/tags" --paginate \
--jq '.[] | select(.name | startswith("cuda-core-v")) | .name' \
| sed -n '1p')"
if [[ -z "${tag}" ]]; then
echo "::error::No cuda-core-v* tag found in the repository." >&2
exit 1
fi
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
- name: Fetch release tag
shell: bash --noprofile --norc -euo pipefail {0}
run: |
git fetch --depth=1 --filter=blob:none origin \
"refs/tags/${{ steps.latest-tag.outputs.tag }}:refs/tags/${{ steps.latest-tag.outputs.tag }}"
- name: Check cuda_core public API
id: griffe
uses: ./.github/actions/griffe-api-check
with:
package-name: cuda.core
package-dir: cuda_core
merge-base: ${{ steps.latest-tag.outputs.tag }}
api-check-core-vs-base:
name: API check (cuda_core vs. merge base)
if: >-
${{ startsWith(github.ref_name, 'pull-request/') &&
!fromJSON(needs.should-skip.outputs.skip) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.core_api_checks }}
runs-on: ubuntu-latest
needs:
- should-skip
- detect-changes
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
filter: blob:none
- name: Fetch merge base commit
shell: bash --noprofile --norc -euo pipefail {0}
run: |
git fetch --depth=1 --filter=blob:none origin \
"${{ fromJSON(needs.detect-changes.outputs.workplan).merge_base }}"
- name: Check cuda_core public API
id: griffe
uses: ./.github/actions/griffe-api-check
with:
package-name: cuda.core
package-dir: cuda_core
merge-base: ${{ fromJSON(needs.detect-changes.outputs.workplan).merge_base }}
# NOTE: Build jobs are intentionally split by platform rather than using a single
# matrix. This lets each test job consume its platform-specific artifacts as
# soon as they are ready. ARM64 and Windows tests also wait for linux-64,
# which produces the universal pathfinder and cuda-python wheels. Keep these
# job definitions textually identical except for:
# - host-platform value
# - if: condition (build-linux-64 omits doc-only check since it's needed for docs)
build-linux-64:
needs:
- ci-vars
- should-skip
- detect-changes
strategy:
fail-fast: false
matrix:
host-platform:
- linux-64
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
permissions:
actions: read
contents: read
secrets: inherit
uses: ./.github/workflows/build-wheel.yml
with:
host-platform: ${{ matrix.host-platform }}
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# See build-linux-64 for why build jobs are split by platform.
build-linux-aarch64:
needs:
- ci-vars
- should-skip
- detect-changes
strategy:
fail-fast: false
matrix:
host-platform:
- linux-aarch64
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.skip) &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.linux }}
permissions:
actions: read
contents: read
secrets: inherit
uses: ./.github/workflows/build-wheel.yml
with:
host-platform: ${{ matrix.host-platform }}
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# See build-linux-64 for why build jobs are split by platform.
build-windows:
needs:
- ci-vars
- should-skip
- detect-changes
strategy:
fail-fast: false
matrix:
host-platform:
- win-64
name: Build ${{ matrix.host-platform }}, CUDA ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.skip) &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.windows }}
permissions:
actions: read
contents: read
secrets: inherit
uses: ./.github/workflows/build-wheel.yml
with:
host-platform: ${{ matrix.host-platform }}
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
prev-cuda-version: ${{ needs.ci-vars.outputs.CUDA_PREV_BUILD_VER }}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# NOTE: test-sdist jobs are split by platform (mirroring build-* and test-wheel-*)
# so platform-specific sources (e.g. cuda_bindings/*_windows.pyx selected by
# build_hooks.py) are exercised on their target OS. Keep these job definitions
# textually identical except for:
# - host-platform value
# - uses: (test-sdist-linux.yml vs test-sdist-windows.yml)
test-sdist-linux:
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
name: Test sdist linux-64
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.skip) &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.sdist_tests }}
permissions:
actions: read
contents: read
secrets: inherit
uses: ./.github/workflows/test-sdist-linux.yml
with:
host-platform: linux-64
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# See test-sdist-linux for why sdist test jobs are split by platform.
test-sdist-windows:
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
- build-windows
name: Test sdist win-64
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.skip) &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.sdist_tests }}
permissions:
actions: read
contents: read
secrets: inherit
uses: ./.github/workflows/test-sdist-windows.yml
with:
host-platform: win-64
cuda-version: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# NOTE: Test jobs are split by platform for the same reason as build jobs (see
# build-linux-64). Keep these job definitions textually identical except for:
# - host-platform value
# - build job under needs:
# - uses: (test-wheel-linux.yml vs test-wheel-windows.yml)
test-linux-64:
strategy:
fail-fast: false
matrix:
host-platform:
- linux-64
name: Test ${{ matrix.host-platform }}
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.linux }}
permissions:
actions: read
contents: read # This is required for actions/checkout
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
secrets: inherit
uses: ./.github/workflows/test-wheel-linux.yml
with:
build-type: pull-request
host-platform: ${{ matrix.host-platform }}
build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
nruns: ${{ (github.event_name == 'schedule' && 5) || 1}}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# See test-linux-64 for why test jobs are split by platform.
test-linux-aarch64:
strategy:
fail-fast: false
matrix:
host-platform:
- linux-aarch64
name: Test ${{ matrix.host-platform }}
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.linux }}
permissions:
actions: read
contents: read # This is required for actions/checkout
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
- build-linux-aarch64
secrets: inherit
uses: ./.github/workflows/test-wheel-linux.yml
with:
build-type: pull-request
host-platform: ${{ matrix.host-platform }}
build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
nruns: ${{ (github.event_name == 'schedule' && 5) || 1}}
workplan: ${{ needs.detect-changes.outputs.workplan }}
# See test-linux-64 for why test jobs are split by platform.
test-windows:
strategy:
fail-fast: false
matrix:
host-platform:
- win-64
name: Test ${{ matrix.host-platform }}
if: ${{ github.repository_owner == 'nvidia' &&
!fromJSON(needs.should-skip.outputs.doc-only) &&
fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.windows }}
permissions:
actions: read
contents: read # This is required for actions/checkout
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
- build-windows
secrets: inherit
uses: ./.github/workflows/test-wheel-windows.yml
with:
build-type: pull-request
host-platform: ${{ matrix.host-platform }}
build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }}
nruns: ${{ (github.event_name == 'schedule' && 5) || 1}}
workplan: ${{ needs.detect-changes.outputs.workplan }}
doc:
name: Docs
if: ${{ github.repository_owner == 'nvidia' }}
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
id-token: write
contents: write
pull-requests: write
needs:
- ci-vars
- build-linux-64
secrets: inherit
uses: ./.github/workflows/build-docs.yml
with:
is-release: ${{ github.ref_type == 'tag' }}
precommit-windows:
name: Pre-commit on Windows
runs-on: windows-latest
if: ${{ github.repository_owner == 'nvidia' && !fromJSON(needs.should-skip.outputs.skip) }}
needs:
- should-skip
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.13'
- name: Install pre-commit
shell: bash
run: |
set -euxo pipefail
python -m pip install --upgrade pip pre-commit
- name: Run pre-commit
shell: bash
run: |
set -euxo pipefail
SKIP=lychee pre-commit run --all-files
checks:
name: Check job status
if: ${{ always() && github.repository_owner == 'nvidia' }}
runs-on: ubuntu-latest
needs:
- ci-vars
- should-skip
- detect-changes
- build-linux-64
- build-linux-aarch64
- build-windows
- test-sdist-linux
- test-sdist-windows
- test-linux-64
- test-linux-aarch64
- test-windows
- api-check-core-vs-release
- api-check-core-vs-base
- doc
- precommit-windows
steps:
- name: Exit
env:
NEEDS_JSON: ${{ toJSON(needs) }}
run: |
# GitHub treats `result == 'skipped'` as success for required
# status checks (see CCCL gate comment + cccl#605). The previous
# `cancelled || failure` predicate let upstream build failures
# propagate as `skipped` on downstream test jobs and silently
# pass this aggregator. Adopt CCCL's `check_result` pattern:
# require an explicit `expected` status per dependency, where
# anything else (including `skipped` from a failed upstream)
# fails the gate. `if: always()` on the job still ensures this
# step runs even when needs are skipped.
if [[ "${{ needs.should-skip.outputs.skip }}" == "true" ]]; then
echo "[no-ci] - skipping aggregator checks"
exit 0
fi
doc_only="${{ needs.should-skip.outputs.doc-only }}"
linux_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.linux || false }}"
windows_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.platforms.windows || false }}"
build_selected="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.sdist_tests || false }}"
run_core_api_check="${{ needs.detect-changes.outputs.workplan && fromJSON(needs.detect-changes.outputs.workplan).jobs.core_api_checks || false }}"
is_pr="${{ startsWith(github.ref_name, 'pull-request/') }}"
status="success"
check_result() {
local name=$1 expected=$2 result
result=$(jq -r --arg name "$name" '.[$name].result // "missing"' <<< "$NEEDS_JSON")
echo "Checking $name: result='$result' (expected '$expected')"
if [[ "$result" != "$expected" ]]; then
echo "::error::$name did not match expected result"
status="failed"
fi
}
# Control jobs, the universal linux build, docs, and Windows
# pre-commit checks always run.
check_result "ci-vars" "success"
check_result "should-skip" "success"
check_result "detect-changes" "success"
check_result "build-linux-64" "success"
check_result "doc" "success"
check_result "precommit-windows" "success"
# Optional platform builds and wheel tests share the platform plan.
linux_expected="skipped"
if [[ "$doc_only" != "true" && "$linux_selected" == "true" ]]; then
linux_expected="success"
fi
windows_expected="skipped"
if [[ "$doc_only" != "true" && "$windows_selected" == "true" ]]; then
windows_expected="success"
fi
check_result "build-linux-aarch64" "$linux_expected"
check_result "build-windows" "$windows_expected"
# Sdist tests follow build selection; wheel tests follow the platform plan.
expected="skipped"
if [[ "$doc_only" != "true" && "$build_selected" == "true" ]]; then
expected="success"
fi
check_result "test-sdist-linux" "$expected"
check_result "test-sdist-windows" "$expected"
check_result "test-linux-64" "$linux_expected"
check_result "test-linux-aarch64" "$linux_expected"
check_result "test-windows" "$windows_expected"
# API compatibility checks run for cuda_core source changes and for
# conservative full runs when reusable base artifacts are unavailable.
expected="skipped"
if [[ "$run_core_api_check" == "true" ]]; then expected="success"; fi
check_result "api-check-core-vs-release" "$expected"
expected="skipped"
if [[ "$is_pr" == "true" && "$run_core_api_check" == "true" ]]; then expected="success"; fi
check_result "api-check-core-vs-base" "$expected"
[[ "$status" == "success" ]]