# 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 }} WINDOWS_ARM64_SUPPORTED: ${{ steps.get-vars.outputs.windows_arm64_supported }} WINDOWS_ARM64_SINGLE_CUDA_MAJOR: ${{ steps.get-vars.outputs.windows_arm64_single_cuda_major }} PYTHON_SUPPORTED: ${{ steps.get-vars.outputs.python_supported }} steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 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 # Flattened one-line JSON for pass-through to build-wheel.yml via # fromJSON on the receiving side. python_supported=$(yq -o json -I 0 '.python.supported' ci/versions.yml) echo "python_supported=$python_supported" >> $GITHUB_OUTPUT # Windows ARM64 is available starting with CUDA 13.4. if [[ "$cuda_build_ver" =~ ^([0-9]+)\.([0-9]+)(\.|$) ]]; then cuda_build_major="${BASH_REMATCH[1]}" cuda_build_minor="${BASH_REMATCH[2]}" else echo "Invalid CUDA build version: $cuda_build_ver" >&2 exit 1 fi if (( cuda_build_major > 13 || (cuda_build_major == 13 && cuda_build_minor >= 4) )); then windows_arm64_supported=true else windows_arm64_supported=false fi echo "windows_arm64_supported=$windows_arm64_supported" >> $GITHUB_OUTPUT # No CUDA 13 windows-arm64 toolkit exists for a major other than the # current one (windows-arm64 support started mid-way through the 13.x # series), so cuda.core can only be built against a single CUDA major # while the build major is still 13. Once the build major advances to # 14, a CUDA 13 windows-arm64 toolkit will exist as the prior major. if [[ "$cuda_build_major" == "13" ]]; then windows_arm64_single_cuda_major=true else windows_arm64_single_cuda_major=false fi echo "windows_arm64_single_cuda_major=$windows_arm64_single_cuda_major" >> $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: Compute whether to skip builds and tests id: get-should-skip env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} 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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: # Only PR mirrors need full ancestry to find their merge base. fetch-depth: ${{ startsWith(github.ref_name, 'pull-request/') && '0' || '1' }} 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 '.python.supported[]' ci/versions.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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 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 }} python-versions: ${{ needs.ci-vars.outputs.PYTHON_SUPPORTED }} # 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 }} python-versions: ${{ needs.ci-vars.outputs.PYTHON_SUPPORTED }} # 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 }} python-versions: ${{ needs.ci-vars.outputs.PYTHON_SUPPORTED }} # Windows ARM64 is available starting with CUDA 13.4. Build only the current # CUDA major because no prior-major toolkit or wheel artifacts exist. build-windows-arm64: needs: - ci-vars - should-skip - detect-changes name: Build win-arm64, 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) && needs.ci-vars.outputs.WINDOWS_ARM64_SUPPORTED == 'true' && 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: win-arm64 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 }} single-cuda-major: ${{ needs.ci-vars.outputs.WINDOWS_ARM64_SINGLE_CUDA_MAJOR == 'true' }} python-versions: ${{ needs.ci-vars.outputs.PYTHON_SUPPORTED }} # 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' }} 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 - build-windows-arm64 - 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 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 }}" windows_arm64_supported="${{ needs.ci-vars.outputs.WINDOWS_ARM64_SUPPORTED }}" 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, and docs 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" # 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" windows_arm64_expected="skipped" if [[ "$windows_arm64_supported" == "true" ]]; then windows_arm64_expected="$windows_expected" fi check_result "build-windows-arm64" "$windows_arm64_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" # API compatibility checks against the merge base (api-check-core-vs-base) # are purely informational, since it is fine for API to drift during development # when it hasn't been released yet. [[ "$status" == "success" ]]