From 50c83b73cd264b9dd636f8107a0c2a976a24a824 Mon Sep 17 00:00:00 2001 From: Omar Atie Date: Fri, 14 Aug 2026 16:54:30 -0700 Subject: [PATCH 1/3] ci: run released cuda-core compat on bindings PRs (#2449) Wire the existing nightly-cuda-core test mode into PR CI when cuda_bindings or related paths change, and add guardrail tests so the workflow wiring stays aligned with the nightly jobs. Signed-off-by: Omar Atie --- .github/workflows/ci.yml | 41 ++++++++++ ci/tools/tests/test_ci_pr_cuda_core_compat.py | 79 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 ci/tools/tests/test_ci_pr_cuda_core_compat.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2aadf222306..3ab15728e8f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -435,6 +435,37 @@ jobs: nruns: ${{ (github.event_name == 'schedule' && 5) || 1}} test-bindings: ${{ fromJSON(needs.detect-changes.outputs.test_bindings) }} + # Released cuda-core from PyPI against PR-built pathfinder/bindings. + # Mirrors ci-nightly.yml test-cuda-core-linux-64 but uses this run's + # artifacts and only runs when bindings-related paths change (#2449). + test-cuda-core-linux-64: + name: Test released cuda-core (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.test_bindings) }} + permissions: + contents: read + actions: read + needs: + - ci-vars + - should-skip + - detect-changes + - build-linux-64 + secrets: inherit + uses: ./.github/workflows/test-wheel-linux.yml + with: + build-type: nightly + host-platform: linux-64 + build-ctk-ver: ${{ needs.ci-vars.outputs.CUDA_BUILD_VER }} + test-mode: nightly-cuda-core + matrix_filter: 'map(select(.ENV.MODE == "nightly-cuda-core"))' + test-core: false + test-bindings: false + test-pathfinder: false + test-python: false + # See test-linux-64 for why test jobs are split by platform. test-linux-aarch64: strategy: @@ -543,6 +574,7 @@ jobs: - test-sdist-linux - test-sdist-windows - test-linux-64 + - test-cuda-core-linux-64 - test-linux-aarch64 - test-windows - doc @@ -589,4 +621,13 @@ jobs: check_result "test-linux-aarch64" "$expected" "${{ needs.test-linux-aarch64.result }}" check_result "test-windows" "$expected" "${{ needs.test-windows.result }}" + # Released cuda-core compat runs only when bindings-related paths change. + test_bindings="${{ needs.detect-changes.outputs.test_bindings }}" + if [[ "$doc_only" == "true" ]] || [[ "$test_bindings" != "true" ]]; then + cuda_core_expected="skipped" + else + cuda_core_expected="success" + fi + check_result "test-cuda-core-linux-64" "$cuda_core_expected" "${{ needs.test-cuda-core-linux-64.result }}" + [[ "$status" == "success" ]] diff --git a/ci/tools/tests/test_ci_pr_cuda_core_compat.py b/ci/tools/tests/test_ci_pr_cuda_core_compat.py new file mode 100644 index 00000000000..6cb452489e2 --- /dev/null +++ b/ci/tools/tests/test_ci_pr_cuda_core_compat.py @@ -0,0 +1,79 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Guardrails for PR CI wiring of nightly-cuda-core (#2449).""" + +from __future__ import annotations + +import re +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[3] +CI_YML = REPO_ROOT / ".github" / "workflows" / "ci.yml" +CI_NIGHTLY_YML = REPO_ROOT / ".github" / "workflows" / "ci-nightly.yml" + + +def _job_block(workflow_text: str, job_id: str) -> str: + """Return the YAML block for a top-level job (through the next job header).""" + pattern = rf"(?ms)^ {re.escape(job_id)}:\n.*?(?=^ \w|^jobs:|\Z)" + match = re.search(pattern, workflow_text) + assert match, f"job {job_id!r} not found" + return match.group(0) + + +@pytest.fixture(scope="module") +def ci_yml_text() -> str: + return CI_YML.read_text(encoding="utf-8") + + +@pytest.fixture(scope="module") +def test_cuda_core_job(ci_yml_text: str) -> str: + return _job_block(ci_yml_text, "test-cuda-core-linux-64") + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_pr_ci_defines_released_cuda_core_job(test_cuda_core_job: str) -> None: + assert "test-mode: nightly-cuda-core" in test_cuda_core_job + assert 'matrix_filter: \'map(select(.ENV.MODE == "nightly-cuda-core"))\'' in test_cuda_core_job + assert "build-type: nightly" in test_cuda_core_job + assert "host-platform: linux-64" in test_cuda_core_job + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_pr_cuda_core_job_uses_pr_artifact_build(test_cuda_core_job: str) -> None: + # PR CI must consume wheels from this run, not a pinned main run-id/sha. + assert "run-id:" not in test_cuda_core_job + assert "sha:" not in test_cuda_core_job + assert "build-linux-64" in test_cuda_core_job + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_pr_cuda_core_job_gated_on_bindings_changes(test_cuda_core_job: str) -> None: + assert "detect-changes.outputs.test_bindings" in test_cuda_core_job + assert "should-skip.outputs.doc-only" in test_cuda_core_job + assert "should-skip.outputs.skip" in test_cuda_core_job + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_pr_cuda_core_job_skips_standard_module_tests(test_cuda_core_job: str) -> None: + assert "test-core: false" in test_cuda_core_job + assert "test-bindings: false" in test_cuda_core_job + assert "test-pathfinder: false" in test_cuda_core_job + assert "test-python: false" in test_cuda_core_job + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_checks_aggregator_tracks_cuda_core_job(ci_yml_text: str) -> None: + checks = _job_block(ci_yml_text, "checks") + assert "test-cuda-core-linux-64" in checks + assert 'check_result "test-cuda-core-linux-64"' in checks + assert "detect-changes.outputs.test_bindings" in checks + + +@pytest.mark.agent_authored(model="composer-2.5-fast") +def test_nightly_still_defines_cuda_core_jobs() -> None: + nightly = CI_NIGHTLY_YML.read_text(encoding="utf-8") + assert _job_block(nightly, "test-cuda-core-linux-64") + assert _job_block(nightly, "test-cuda-core-windows") From 0e4c3207aeb772e5e9c772ac0d28cafed2f38cfe Mon Sep 17 00:00:00 2001 From: Omar Atie Date: Fri, 14 Aug 2026 16:57:19 -0700 Subject: [PATCH 2/3] fix: keep pathfinder/bindings downloads for cuda-core PR job nightly-cuda-core still needs PR-built pathfinder/bindings wheels; only disable standard cuda-core and meta-package pytest runs. Signed-off-by: Omar Atie --- .github/workflows/ci.yml | 2 -- ci/tools/tests/test_ci_pr_cuda_core_compat.py | 8 +++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ab15728e8f..fd1609de67a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -462,8 +462,6 @@ jobs: test-mode: nightly-cuda-core matrix_filter: 'map(select(.ENV.MODE == "nightly-cuda-core"))' test-core: false - test-bindings: false - test-pathfinder: false test-python: false # See test-linux-64 for why test jobs are split by platform. diff --git a/ci/tools/tests/test_ci_pr_cuda_core_compat.py b/ci/tools/tests/test_ci_pr_cuda_core_compat.py index 6cb452489e2..5fac42bf279 100644 --- a/ci/tools/tests/test_ci_pr_cuda_core_compat.py +++ b/ci/tools/tests/test_ci_pr_cuda_core_compat.py @@ -57,11 +57,13 @@ def test_pr_cuda_core_job_gated_on_bindings_changes(test_cuda_core_job: str) -> @pytest.mark.agent_authored(model="composer-2.5-fast") -def test_pr_cuda_core_job_skips_standard_module_tests(test_cuda_core_job: str) -> None: +def test_pr_cuda_core_job_skips_standard_core_and_meta_tests(test_cuda_core_job: str) -> None: + # pathfinder/bindings downloads stay enabled (defaults) so nightly-cuda-core + # can install PR-built wheels; only skip standard cuda-core/meta pytest. assert "test-core: false" in test_cuda_core_job - assert "test-bindings: false" in test_cuda_core_job - assert "test-pathfinder: false" in test_cuda_core_job assert "test-python: false" in test_cuda_core_job + assert "test-bindings: false" not in test_cuda_core_job + assert "test-pathfinder: false" not in test_cuda_core_job @pytest.mark.agent_authored(model="composer-2.5-fast") From ce5eebbdcf56bf3e6cfa85e10446f141f295e70c Mon Sep 17 00:00:00 2001 From: Omar Atie Date: Fri, 14 Aug 2026 16:58:13 -0700 Subject: [PATCH 3/3] style: ruff-format ci guardrail test (#2449) Apply ruff format to test_ci_pr_cuda_core_compat.py for pre-commit.ci. Signed-off-by: Omar Atie --- ci/tools/tests/test_ci_pr_cuda_core_compat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/tools/tests/test_ci_pr_cuda_core_compat.py b/ci/tools/tests/test_ci_pr_cuda_core_compat.py index 5fac42bf279..0659ec3f706 100644 --- a/ci/tools/tests/test_ci_pr_cuda_core_compat.py +++ b/ci/tools/tests/test_ci_pr_cuda_core_compat.py @@ -36,7 +36,7 @@ def test_cuda_core_job(ci_yml_text: str) -> str: @pytest.mark.agent_authored(model="composer-2.5-fast") def test_pr_ci_defines_released_cuda_core_job(test_cuda_core_job: str) -> None: assert "test-mode: nightly-cuda-core" in test_cuda_core_job - assert 'matrix_filter: \'map(select(.ENV.MODE == "nightly-cuda-core"))\'' in test_cuda_core_job + assert "matrix_filter: 'map(select(.ENV.MODE == \"nightly-cuda-core\"))'" in test_cuda_core_job assert "build-type: nightly" in test_cuda_core_job assert "host-platform: linux-64" in test_cuda_core_job