From 8ed12d14af352fa5e607ac4f0c7d559368c74aae Mon Sep 17 00:00:00 2001 From: Jake Wang <2645794+jakezwang@users.noreply.github.com> Date: Sun, 27 Sep 2026 20:35:08 -0400 Subject: [PATCH 1/4] Skip third-party CI for ignored-only changes --- .github/workflows/ci-workflow-pull-request.yml | 11 +++++++++++ ci/inspect_changes.py | 11 ++++++++--- ci/project_files_and_dependencies.yaml | 17 +++++++++++------ ci/test/inspect_changes/c2h_dependency.output | 1 + ci/test/inspect_changes/core_dirty.output | 1 + .../inspect_changes/ignored_only.dirty_files | 2 ++ ci/test/inspect_changes/ignored_only.output | 1 + ci/test/inspect_changes/libcudacxx_both.output | 1 + .../libcudacxx_internal_only.output | 1 + .../libcudacxx_public_only.output | 1 + .../inspect_changes/libcudacxx_thrust.output | 1 + .../mixed_ignored_and_header.dirty_files | 3 +++ .../mixed_ignored_and_header.output | 3 +++ .../inspect_changes/multiple_projects.output | 1 + ci/test/inspect_changes/no_changes.output | 1 + ci/test/inspect_changes/packaging_only.output | 1 + ci/test/inspect_changes/regenerate_outputs.sh | 2 +- .../third_party_matx_script.dirty_files | 1 + .../third_party_matx_script.output | 3 +++ .../third_party_matx_workflow.dirty_files | 1 + .../third_party_matx_workflow.output | 3 +++ .../third_party_pytorch_script.dirty_files | 1 + .../third_party_pytorch_script.output | 3 +++ .../third_party_pytorch_workflow.dirty_files | 1 + .../third_party_pytorch_workflow.output | 3 +++ .../third_party_rapids_script.dirty_files | 1 + .../third_party_rapids_script.output | 3 +++ .../third_party_rapids_workflow.dirty_files | 1 + .../third_party_rapids_workflow.output | 3 +++ .../ci/references/change_detection.rst | 11 +++++++++-- 30 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 ci/test/inspect_changes/mixed_ignored_and_header.dirty_files create mode 100644 ci/test/inspect_changes/mixed_ignored_and_header.output create mode 100644 ci/test/inspect_changes/third_party_matx_script.dirty_files create mode 100644 ci/test/inspect_changes/third_party_matx_script.output create mode 100644 ci/test/inspect_changes/third_party_matx_workflow.dirty_files create mode 100644 ci/test/inspect_changes/third_party_matx_workflow.output create mode 100644 ci/test/inspect_changes/third_party_pytorch_script.dirty_files create mode 100644 ci/test/inspect_changes/third_party_pytorch_script.output create mode 100644 ci/test/inspect_changes/third_party_pytorch_workflow.dirty_files create mode 100644 ci/test/inspect_changes/third_party_pytorch_workflow.output create mode 100644 ci/test/inspect_changes/third_party_rapids_script.dirty_files create mode 100644 ci/test/inspect_changes/third_party_rapids_script.output create mode 100644 ci/test/inspect_changes/third_party_rapids_workflow.dirty_files create mode 100644 ci/test/inspect_changes/third_party_rapids_workflow.output diff --git a/.github/workflows/ci-workflow-pull-request.yml b/.github/workflows/ci-workflow-pull-request.yml index f2da3012ffb6..71e70d6737ac 100644 --- a/.github/workflows/ci-workflow-pull-request.yml +++ b/.github/workflows/ci-workflow-pull-request.yml @@ -54,6 +54,7 @@ jobs: rapids_enabled: ${{ steps.export-flags.outputs.rapids_enabled }} matx_enabled: ${{ steps.export-flags.outputs.matx_enabled }} pytorch_enabled: ${{ steps.export-flags.outputs.pytorch_enabled }} + third_party_changes: ${{ steps.inspect-third-party-changes.outputs.HAS_NON_IGNORED_CHANGES }} branch_notes_dirt: ${{ steps.branch-notes-dirt.outputs.branch_notes_dirt }} steps: - name: Export workflow flags @@ -87,6 +88,13 @@ jobs: echo "pr_number=${{ fromJSON(steps.get-pr-info.outputs.pr-info).number }}" | tee -a "${GITHUB_OUTPUT}" git fetch origin "${BASE_SHA}" -q echo "merge_base_sha=$(git merge-base "${BASE_SHA}" "${GITHUB_SHA}")" | tee -a "${GITHUB_OUTPUT}" + - name: Inspect changes for third-party tests + id: inspect-third-party-changes + env: + BASE_SHA: ${{ steps.export-pr-info.outputs.base_sha }} + run: | + # This also runs when the main matrix is disabled with [skip-matrix]. + ./ci/inspect_changes.py --refs "${BASE_SHA}" "${GITHUB_SHA}" - name: Build benchmark dispatch matrix id: build-bench-matrix run: | @@ -373,6 +381,7 @@ jobs: if: >- ${{ needs.build-workflow.outputs.rapids_enabled == 'true' && + needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit @@ -390,6 +399,7 @@ jobs: if: >- ${{ needs.build-workflow.outputs.matx_enabled == 'true' && + needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit @@ -404,6 +414,7 @@ jobs: if: >- ${{ needs.build-workflow.outputs.pytorch_enabled == 'true' && + needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit diff --git a/ci/inspect_changes.py b/ci/inspect_changes.py index cfd013ae456b..a8e3b5944d04 100755 --- a/ci/inspect_changes.py +++ b/ci/inspect_changes.py @@ -591,11 +591,16 @@ def compute_outputs( return full_output, lite_output -def emit_outputs(full_output: Sequence[str], lite_output: Sequence[str]) -> None: - """Write FULL_BUILD/LITE_BUILD strings to stdout and GitHub outputs.""" +def emit_outputs( + full_output: Sequence[str], + lite_output: Sequence[str], + has_non_ignored_changes: bool, +) -> None: + """Write rebuild lists and change detection results to GitHub outputs.""" print("Github Action Outputs:") write_output("FULL_BUILD", " ".join(full_output)) write_output("LITE_BUILD", " ".join(lite_output)) + write_output("HAS_NON_IGNORED_CHANGES", str(has_non_ignored_changes).lower()) print() @@ -671,7 +676,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: full_output, lite_output = compute_outputs(config, full_set, lite_set) print() - emit_outputs(full_output, lite_output) + emit_outputs(full_output, lite_output, bool(dirty_files)) with SummaryWriter(summary_path) as summary_writer: print("::group::Project Change Summary") diff --git a/ci/project_files_and_dependencies.yaml b/ci/project_files_and_dependencies.yaml index ce4556d082cd..6fc882e1e335 100644 --- a/ci/project_files_and_dependencies.yaml +++ b/ci/project_files_and_dependencies.yaml @@ -221,6 +221,17 @@ projects: full_dependencies: [] include_regexes: ["nvrtcc/"] + # These files must trigger third-party tests without adding CCCL matrix jobs. + third_party: + name: "Third-party Tests" + include_regexes: + - '\.github/workflows/build-matx\.yml' + - '\.github/workflows/build-pytorch\.yml' + - '\.github/workflows/build-rapids\.yml' + - 'ci/matx/' + - 'ci/pytorch/' + - 'ci/rapids/' + # This is a dummy project, and only really serves to encode dependencies. Any time any # of the C/C++ projects are modified, we want to launch one (and only one) clang-tidy # job for the whole of CCCL. @@ -268,9 +279,6 @@ ignore_regexes: - '\.github/workflows/bench.*\.yml' - '\.github/workflows/compile-time-bench\.yml' - '\.github/workflows/build-docs\.yml' - - '\.github/workflows/build-matx\.yml' - - '\.github/workflows/build-pytorch\.yml' - - '\.github/workflows/build-rapids\.yml' - '\.github/workflows/git-bisect\.yml' - '\.github/workflows/project_automation.*\.yml' - '\.github/workflows/release.*\.yml' @@ -282,8 +290,5 @@ ignore_regexes: - 'cccl-version.json' - 'ci/bench/' - 'ci/bench.+yaml' - - 'ci/matx/' - - 'ci/pytorch/' - - 'ci/rapids/' - 'docs/' - 'LICENSE' diff --git a/ci/test/inspect_changes/c2h_dependency.output b/ci/test/inspect_changes/c2h_dependency.output index 5e04c5875257..473ab9d4a77c 100644 --- a/ci/test/inspect_changes/c2h_dependency.output +++ b/ci/test/inspect_changes/c2h_dependency.output @@ -1,2 +1,3 @@ FULL_BUILD=tidy LITE_BUILD=libcudacxx cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 cccl_c_stf python packaging +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/core_dirty.output b/ci/test/inspect_changes/core_dirty.output index 456e3158f677..de5d5572c6db 100644 --- a/ci/test/inspect_changes/core_dirty.output +++ b/ci/test/inspect_changes/core_dirty.output @@ -1,2 +1,3 @@ FULL_BUILD=libcudacxx cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper nvrtcc tidy LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/ignored_only.dirty_files b/ci/test/inspect_changes/ignored_only.dirty_files index 7d2fa473a692..f6cde09e21c3 100644 --- a/ci/test/inspect_changes/ignored_only.dirty_files +++ b/ci/test/inspect_changes/ignored_only.dirty_files @@ -1 +1,3 @@ docs/index.rst +README.md +.github/actions/docs-build/action.yml diff --git a/ci/test/inspect_changes/ignored_only.output b/ci/test/inspect_changes/ignored_only.output index 4e9e2ba72280..c1be9e6a9c26 100644 --- a/ci/test/inspect_changes/ignored_only.output +++ b/ci/test/inspect_changes/ignored_only.output @@ -1,2 +1,3 @@ FULL_BUILD= LITE_BUILD= +HAS_NON_IGNORED_CHANGES=false diff --git a/ci/test/inspect_changes/libcudacxx_both.output b/ci/test/inspect_changes/libcudacxx_both.output index eddc77079559..51fdf3ade726 100644 --- a/ci/test/inspect_changes/libcudacxx_both.output +++ b/ci/test/inspect_changes/libcudacxx_both.output @@ -1,2 +1,3 @@ FULL_BUILD=libcudacxx tidy LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/libcudacxx_internal_only.output b/ci/test/inspect_changes/libcudacxx_internal_only.output index 8e8a2194ab5e..905962e3755a 100644 --- a/ci/test/inspect_changes/libcudacxx_internal_only.output +++ b/ci/test/inspect_changes/libcudacxx_internal_only.output @@ -1,2 +1,3 @@ FULL_BUILD=libcudacxx tidy LITE_BUILD=packaging +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/libcudacxx_public_only.output b/ci/test/inspect_changes/libcudacxx_public_only.output index eddc77079559..51fdf3ade726 100644 --- a/ci/test/inspect_changes/libcudacxx_public_only.output +++ b/ci/test/inspect_changes/libcudacxx_public_only.output @@ -1,2 +1,3 @@ FULL_BUILD=libcudacxx tidy LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/libcudacxx_thrust.output b/ci/test/inspect_changes/libcudacxx_thrust.output index 00f10a620f0f..2de3f0b57e32 100644 --- a/ci/test/inspect_changes/libcudacxx_thrust.output +++ b/ci/test/inspect_changes/libcudacxx_thrust.output @@ -1,2 +1,3 @@ FULL_BUILD=libcudacxx thrust tidy LITE_BUILD=cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/mixed_ignored_and_header.dirty_files b/ci/test/inspect_changes/mixed_ignored_and_header.dirty_files new file mode 100644 index 000000000000..3debeb65d005 --- /dev/null +++ b/ci/test/inspect_changes/mixed_ignored_and_header.dirty_files @@ -0,0 +1,3 @@ +docs/index.rst +README.md +libcudacxx/include/cuda/std/algorithm diff --git a/ci/test/inspect_changes/mixed_ignored_and_header.output b/ci/test/inspect_changes/mixed_ignored_and_header.output new file mode 100644 index 000000000000..51fdf3ade726 --- /dev/null +++ b/ci/test/inspect_changes/mixed_ignored_and_header.output @@ -0,0 +1,3 @@ +FULL_BUILD=libcudacxx tidy +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/multiple_projects.output b/ci/test/inspect_changes/multiple_projects.output index 9395cf0aeb6c..72f6f1018428 100644 --- a/ci/test/inspect_changes/multiple_projects.output +++ b/ci/test/inspect_changes/multiple_projects.output @@ -1,2 +1,3 @@ FULL_BUILD=python_v2 python_tsan python packaging LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/no_changes.output b/ci/test/inspect_changes/no_changes.output index 4e9e2ba72280..c1be9e6a9c26 100644 --- a/ci/test/inspect_changes/no_changes.output +++ b/ci/test/inspect_changes/no_changes.output @@ -1,2 +1,3 @@ FULL_BUILD= LITE_BUILD= +HAS_NON_IGNORED_CHANGES=false diff --git a/ci/test/inspect_changes/packaging_only.output b/ci/test/inspect_changes/packaging_only.output index a23e2374a4a6..f736032ac8fd 100644 --- a/ci/test/inspect_changes/packaging_only.output +++ b/ci/test/inspect_changes/packaging_only.output @@ -1,2 +1,3 @@ FULL_BUILD=packaging LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/regenerate_outputs.sh b/ci/test/inspect_changes/regenerate_outputs.sh index 464d09bab334..21abd9600f93 100755 --- a/ci/test/inspect_changes/regenerate_outputs.sh +++ b/ci/test/inspect_changes/regenerate_outputs.sh @@ -17,5 +17,5 @@ for dirty_file in *.dirty_files; do output_file="${test_name}.output" echo "Regenerating ${output_file}" python "${inspect_changes}" --file "${dirty_file}" \ - | awk '/^FULL_BUILD=/{print}/^LITE_BUILD=/{print}' > "${output_file}" + | awk '/^FULL_BUILD=/{print}/^LITE_BUILD=/{print}/^HAS_NON_IGNORED_CHANGES=/{print}' > "${output_file}" done diff --git a/ci/test/inspect_changes/third_party_matx_script.dirty_files b/ci/test/inspect_changes/third_party_matx_script.dirty_files new file mode 100644 index 000000000000..955170dd2597 --- /dev/null +++ b/ci/test/inspect_changes/third_party_matx_script.dirty_files @@ -0,0 +1 @@ +ci/matx/build_matx.sh diff --git a/ci/test/inspect_changes/third_party_matx_script.output b/ci/test/inspect_changes/third_party_matx_script.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_matx_script.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_matx_workflow.dirty_files b/ci/test/inspect_changes/third_party_matx_workflow.dirty_files new file mode 100644 index 000000000000..f5232e68fd6c --- /dev/null +++ b/ci/test/inspect_changes/third_party_matx_workflow.dirty_files @@ -0,0 +1 @@ +.github/workflows/build-matx.yml diff --git a/ci/test/inspect_changes/third_party_matx_workflow.output b/ci/test/inspect_changes/third_party_matx_workflow.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_matx_workflow.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_pytorch_script.dirty_files b/ci/test/inspect_changes/third_party_pytorch_script.dirty_files new file mode 100644 index 000000000000..911510bedc88 --- /dev/null +++ b/ci/test/inspect_changes/third_party_pytorch_script.dirty_files @@ -0,0 +1 @@ +ci/pytorch/build_pytorch.sh diff --git a/ci/test/inspect_changes/third_party_pytorch_script.output b/ci/test/inspect_changes/third_party_pytorch_script.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_pytorch_script.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_pytorch_workflow.dirty_files b/ci/test/inspect_changes/third_party_pytorch_workflow.dirty_files new file mode 100644 index 000000000000..d458aa23b368 --- /dev/null +++ b/ci/test/inspect_changes/third_party_pytorch_workflow.dirty_files @@ -0,0 +1 @@ +.github/workflows/build-pytorch.yml diff --git a/ci/test/inspect_changes/third_party_pytorch_workflow.output b/ci/test/inspect_changes/third_party_pytorch_workflow.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_pytorch_workflow.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_rapids_script.dirty_files b/ci/test/inspect_changes/third_party_rapids_script.dirty_files new file mode 100644 index 000000000000..e31fadcf77a5 --- /dev/null +++ b/ci/test/inspect_changes/third_party_rapids_script.dirty_files @@ -0,0 +1 @@ +ci/rapids/rapids-entrypoint.sh diff --git a/ci/test/inspect_changes/third_party_rapids_script.output b/ci/test/inspect_changes/third_party_rapids_script.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_rapids_script.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_rapids_workflow.dirty_files b/ci/test/inspect_changes/third_party_rapids_workflow.dirty_files new file mode 100644 index 000000000000..f25022d2ef38 --- /dev/null +++ b/ci/test/inspect_changes/third_party_rapids_workflow.dirty_files @@ -0,0 +1 @@ +.github/workflows/build-rapids.yml diff --git a/ci/test/inspect_changes/third_party_rapids_workflow.output b/ci/test/inspect_changes/third_party_rapids_workflow.output new file mode 100644 index 000000000000..bab5a4987878 --- /dev/null +++ b/ci/test/inspect_changes/third_party_rapids_workflow.output @@ -0,0 +1,3 @@ +FULL_BUILD= +LITE_BUILD= +HAS_NON_IGNORED_CHANGES=true diff --git a/docs/infrastructure/ci/references/change_detection.rst b/docs/infrastructure/ci/references/change_detection.rst index 197f64b3a8db..49162a0a5312 100644 --- a/docs/infrastructure/ci/references/change_detection.rst +++ b/docs/infrastructure/ci/references/change_detection.rst @@ -92,8 +92,8 @@ from any project in ``FULL_BUILD`` is added to ``LITE_BUILD``. Output ------ -``inspect_changes.py`` emits two GitHub Actions outputs, each a space-separated -list of ``matrix_project`` values: +``inspect_changes.py`` emits two GitHub Actions outputs containing space-separated +lists of ``matrix_project`` values: ``FULL_BUILD`` Projects that build and test their full job set. @@ -107,6 +107,13 @@ whose project is in ``FULL_BUILD``, then reads the ``pull_request_lite`` section and keeps only entries whose project is in ``LITE_BUILD``, then concatenates the two. A project absent from both lists contributes no jobs. +The additional ``HAS_NON_IGNORED_CHANGES`` output is ``true`` if any changed file +survives the global ignore filter, or ``false`` otherwise. The pull-request workflow +uses this to skip the optional MatX, PyTorch, and RAPIDS builds for documentation-only +and other ignored changes. Their own workflows and build scripts belong to the internal +``third_party`` project, so changes to those files still run third-party tests without +adding CCCL matrix jobs. The existing third-party skip tags continue to apply. + To see the exact lists for any change, run ``inspect_changes.py`` locally: .. code-block:: bash From 1ddb3bdf47be88f54adcd4ebdea479139b6922a5 Mon Sep 17 00:00:00 2001 From: Jake Wang <2645794+jakezwang@users.noreply.github.com> Date: Tue, 29 Sep 2026 02:29:48 -0400 Subject: [PATCH 2/4] Use existing flags for third-party change detection --- .../workflows/ci-workflow-pull-request.yml | 30 ++++++++----------- .../ci/references/change_detection.rst | 5 ++-- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci-workflow-pull-request.yml b/.github/workflows/ci-workflow-pull-request.yml index 71e70d6737ac..7474c2b53721 100644 --- a/.github/workflows/ci-workflow-pull-request.yml +++ b/.github/workflows/ci-workflow-pull-request.yml @@ -54,22 +54,8 @@ jobs: rapids_enabled: ${{ steps.export-flags.outputs.rapids_enabled }} matx_enabled: ${{ steps.export-flags.outputs.matx_enabled }} pytorch_enabled: ${{ steps.export-flags.outputs.pytorch_enabled }} - third_party_changes: ${{ steps.inspect-third-party-changes.outputs.HAS_NON_IGNORED_CHANGES }} branch_notes_dirt: ${{ steps.branch-notes-dirt.outputs.branch_notes_dirt }} steps: - - name: Export workflow flags - id: export-flags - env: - skip_tpt: ${{ contains(github.event.head_commit.message, '[bench-only]') || contains(github.event.head_commit.message, '[skip-tpt]') || contains(github.event.head_commit.message, '[skip-third-party-testing]') }} - run: | - output() { echo "$1=$2" | tee -a "${GITHUB_OUTPUT}"; } - - output matrix_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-matrix]') }}" - output vdc_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-vdc]') }}" - output docs_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-docs]') }}" - output rapids_enabled "${{ !contains(github.event.head_commit.message, '[skip-rapids]') && !fromJSON(env.skip_tpt) }}" - output matx_enabled "${{ !contains(github.event.head_commit.message, '[skip-matx]') && !fromJSON(env.skip_tpt) }}" - output pytorch_enabled "${{ !contains(github.event.head_commit.message, '[skip-pytorch]') && !fromJSON(env.skip_tpt) }}" - name: Checkout repo uses: actions/checkout@v6 with: @@ -95,6 +81,19 @@ jobs: run: | # This also runs when the main matrix is disabled with [skip-matrix]. ./ci/inspect_changes.py --refs "${BASE_SHA}" "${GITHUB_SHA}" + - name: Export workflow flags + id: export-flags + env: + skip_tpt: ${{ steps.inspect-third-party-changes.outputs.HAS_NON_IGNORED_CHANGES != 'true' || contains(github.event.head_commit.message, '[bench-only]') || contains(github.event.head_commit.message, '[skip-tpt]') || contains(github.event.head_commit.message, '[skip-third-party-testing]') }} + run: | + output() { echo "$1=$2" | tee -a "${GITHUB_OUTPUT}"; } + + output matrix_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-matrix]') }}" + output vdc_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-vdc]') }}" + output docs_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-docs]') }}" + output rapids_enabled "${{ !contains(github.event.head_commit.message, '[skip-rapids]') && !fromJSON(env.skip_tpt) }}" + output matx_enabled "${{ !contains(github.event.head_commit.message, '[skip-matx]') && !fromJSON(env.skip_tpt) }}" + output pytorch_enabled "${{ !contains(github.event.head_commit.message, '[skip-pytorch]') && !fromJSON(env.skip_tpt) }}" - name: Build benchmark dispatch matrix id: build-bench-matrix run: | @@ -381,7 +380,6 @@ jobs: if: >- ${{ needs.build-workflow.outputs.rapids_enabled == 'true' && - needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit @@ -399,7 +397,6 @@ jobs: if: >- ${{ needs.build-workflow.outputs.matx_enabled == 'true' && - needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit @@ -414,7 +411,6 @@ jobs: if: >- ${{ needs.build-workflow.outputs.pytorch_enabled == 'true' && - needs.build-workflow.outputs.third_party_changes == 'true' && github.repository == 'NVIDIA/cccl' }} secrets: inherit diff --git a/docs/infrastructure/ci/references/change_detection.rst b/docs/infrastructure/ci/references/change_detection.rst index 49162a0a5312..e0a330ca0b0b 100644 --- a/docs/infrastructure/ci/references/change_detection.rst +++ b/docs/infrastructure/ci/references/change_detection.rst @@ -109,8 +109,9 @@ two. A project absent from both lists contributes no jobs. The additional ``HAS_NON_IGNORED_CHANGES`` output is ``true`` if any changed file survives the global ignore filter, or ``false`` otherwise. The pull-request workflow -uses this to skip the optional MatX, PyTorch, and RAPIDS builds for documentation-only -and other ignored changes. Their own workflows and build scripts belong to the internal +uses this when exporting its existing ``matx_enabled``, ``pytorch_enabled``, and +``rapids_enabled`` flags to skip optional builds for documentation-only and other +ignored changes. Their own workflows and build scripts belong to the internal ``third_party`` project, so changes to those files still run third-party tests without adding CCCL matrix jobs. The existing third-party skip tags continue to apply. From bdc981ed7b49f2802040be6186f251fbf1fe915b Mon Sep 17 00:00:00 2001 From: Jake Wang <2645794+jakezwang@users.noreply.github.com> Date: Tue, 29 Sep 2026 21:23:01 -0400 Subject: [PATCH 3/4] Use project dependencies to select third-party CI builds --- .../workflows/ci-workflow-pull-request.yml | 9 +++--- ci/inspect_changes.py | 11 ++----- ci/project_files_and_dependencies.yaml | 29 +++++++++++++++---- ci/test/inspect_changes/c2h_dependency.output | 1 - ci/test/inspect_changes/core_dirty.output | 3 +- .../cub_public_only.dirty_files | 1 + .../inspect_changes/cub_public_only.output | 2 ++ .../cub_thrust_internal_only.dirty_files | 2 ++ .../cub_thrust_internal_only.output | 2 ++ .../cudax_public_only.dirty_files | 1 + .../inspect_changes/cudax_public_only.output | 2 ++ ci/test/inspect_changes/ignored_only.output | 1 - .../inspect_changes/libcudacxx_both.output | 3 +- .../libcudacxx_internal_only.output | 1 - .../libcudacxx_public_only.output | 3 +- .../inspect_changes/libcudacxx_thrust.output | 3 +- .../mixed_ignored_and_header.output | 3 +- .../inspect_changes/multiple_projects.output | 1 - ci/test/inspect_changes/no_changes.output | 1 - ci/test/inspect_changes/packaging_only.output | 1 - ci/test/inspect_changes/regenerate_outputs.sh | 2 +- .../third_party_matx_script.output | 3 +- .../third_party_matx_workflow.output | 3 +- .../third_party_pytorch_script.output | 3 +- .../third_party_pytorch_workflow.output | 3 +- .../third_party_rapids_script.output | 3 +- .../third_party_rapids_workflow.output | 3 +- .../thrust_public_only.dirty_files | 1 + .../inspect_changes/thrust_public_only.output | 2 ++ .../ci/references/change_detection.rst | 21 ++++++++------ 30 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 ci/test/inspect_changes/cub_public_only.dirty_files create mode 100644 ci/test/inspect_changes/cub_public_only.output create mode 100644 ci/test/inspect_changes/cub_thrust_internal_only.dirty_files create mode 100644 ci/test/inspect_changes/cub_thrust_internal_only.output create mode 100644 ci/test/inspect_changes/cudax_public_only.dirty_files create mode 100644 ci/test/inspect_changes/cudax_public_only.output create mode 100644 ci/test/inspect_changes/thrust_public_only.dirty_files create mode 100644 ci/test/inspect_changes/thrust_public_only.output diff --git a/.github/workflows/ci-workflow-pull-request.yml b/.github/workflows/ci-workflow-pull-request.yml index 7474c2b53721..0e2a7d457c1a 100644 --- a/.github/workflows/ci-workflow-pull-request.yml +++ b/.github/workflows/ci-workflow-pull-request.yml @@ -84,16 +84,17 @@ jobs: - name: Export workflow flags id: export-flags env: - skip_tpt: ${{ steps.inspect-third-party-changes.outputs.HAS_NON_IGNORED_CHANGES != 'true' || contains(github.event.head_commit.message, '[bench-only]') || contains(github.event.head_commit.message, '[skip-tpt]') || contains(github.event.head_commit.message, '[skip-third-party-testing]') }} + dirty_projects: ${{ format(' {0} {1} ', steps.inspect-third-party-changes.outputs.FULL_BUILD, steps.inspect-third-party-changes.outputs.LITE_BUILD) }} + skip_tpt: ${{ contains(github.event.head_commit.message, '[bench-only]') || contains(github.event.head_commit.message, '[skip-tpt]') || contains(github.event.head_commit.message, '[skip-third-party-testing]') }} run: | output() { echo "$1=$2" | tee -a "${GITHUB_OUTPUT}"; } output matrix_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-matrix]') }}" output vdc_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-vdc]') }}" output docs_enabled "${{ !contains(github.event.head_commit.message, '[bench-only]') && !contains(github.event.head_commit.message, '[skip-docs]') }}" - output rapids_enabled "${{ !contains(github.event.head_commit.message, '[skip-rapids]') && !fromJSON(env.skip_tpt) }}" - output matx_enabled "${{ !contains(github.event.head_commit.message, '[skip-matx]') && !fromJSON(env.skip_tpt) }}" - output pytorch_enabled "${{ !contains(github.event.head_commit.message, '[skip-pytorch]') && !fromJSON(env.skip_tpt) }}" + output rapids_enabled "${{ contains(env.dirty_projects, ' rapids ') && !contains(github.event.head_commit.message, '[skip-rapids]') && !fromJSON(env.skip_tpt) }}" + output matx_enabled "${{ contains(env.dirty_projects, ' matx ') && !contains(github.event.head_commit.message, '[skip-matx]') && !fromJSON(env.skip_tpt) }}" + output pytorch_enabled "${{ contains(env.dirty_projects, ' pytorch ') && !contains(github.event.head_commit.message, '[skip-pytorch]') && !fromJSON(env.skip_tpt) }}" - name: Build benchmark dispatch matrix id: build-bench-matrix run: | diff --git a/ci/inspect_changes.py b/ci/inspect_changes.py index a8e3b5944d04..cfd013ae456b 100755 --- a/ci/inspect_changes.py +++ b/ci/inspect_changes.py @@ -591,16 +591,11 @@ def compute_outputs( return full_output, lite_output -def emit_outputs( - full_output: Sequence[str], - lite_output: Sequence[str], - has_non_ignored_changes: bool, -) -> None: - """Write rebuild lists and change detection results to GitHub outputs.""" +def emit_outputs(full_output: Sequence[str], lite_output: Sequence[str]) -> None: + """Write FULL_BUILD/LITE_BUILD strings to stdout and GitHub outputs.""" print("Github Action Outputs:") write_output("FULL_BUILD", " ".join(full_output)) write_output("LITE_BUILD", " ".join(lite_output)) - write_output("HAS_NON_IGNORED_CHANGES", str(has_non_ignored_changes).lower()) print() @@ -676,7 +671,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: full_output, lite_output = compute_outputs(config, full_set, lite_set) print() - emit_outputs(full_output, lite_output, bool(dirty_files)) + emit_outputs(full_output, lite_output) with SummaryWriter(summary_path) as summary_writer: print("::group::Project Change Summary") diff --git a/ci/project_files_and_dependencies.yaml b/ci/project_files_and_dependencies.yaml index 6fc882e1e335..487a29e55af7 100644 --- a/ci/project_files_and_dependencies.yaml +++ b/ci/project_files_and_dependencies.yaml @@ -23,7 +23,7 @@ # Layout: # project_key: mapping from project key to configuration # name: display name used in logs/reports -# matrix_project: project name to use for matrix generation. If not provided, +# matrix_project: project name to use in the output lists. If not provided, # the project is considered internal-only and will not be listed # in the FULL_BUILD or LITE_BUILD outputs. # lite_dependencies: Add the current project to the `lite` matrix if any of these @@ -221,15 +221,32 @@ projects: full_dependencies: [] include_regexes: ["nvrtcc/"] - # These files must trigger third-party tests without adding CCCL matrix jobs. - third_party: - name: "Third-party Tests" + # Third-party jobs consume these output names directly; they have no matrix jobs. + matx: + name: "MatX" + matrix_project: "matx" + lite_dependencies: [libcudacxx_public, cub_public, thrust_public] + full_dependencies: [] include_regexes: - '\.github/workflows/build-matx\.yml' - - '\.github/workflows/build-pytorch\.yml' - - '\.github/workflows/build-rapids\.yml' - 'ci/matx/' + + pytorch: + name: "PyTorch" + matrix_project: "pytorch" + lite_dependencies: [libcudacxx_public, cub_public, thrust_public] + full_dependencies: [] + include_regexes: + - '\.github/workflows/build-pytorch\.yml' - 'ci/pytorch/' + + rapids: + name: "RAPIDS" + matrix_project: "rapids" + lite_dependencies: [libcudacxx_public, cub_public, thrust_public] + full_dependencies: [] + include_regexes: + - '\.github/workflows/build-rapids\.yml' - 'ci/rapids/' # This is a dummy project, and only really serves to encode dependencies. Any time any diff --git a/ci/test/inspect_changes/c2h_dependency.output b/ci/test/inspect_changes/c2h_dependency.output index 473ab9d4a77c..5e04c5875257 100644 --- a/ci/test/inspect_changes/c2h_dependency.output +++ b/ci/test/inspect_changes/c2h_dependency.output @@ -1,3 +1,2 @@ FULL_BUILD=tidy LITE_BUILD=libcudacxx cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 cccl_c_stf python packaging -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/core_dirty.output b/ci/test/inspect_changes/core_dirty.output index de5d5572c6db..ddcb4682dd7a 100644 --- a/ci/test/inspect_changes/core_dirty.output +++ b/ci/test/inspect_changes/core_dirty.output @@ -1,3 +1,2 @@ -FULL_BUILD=libcudacxx cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper nvrtcc tidy +FULL_BUILD=libcudacxx cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper nvrtcc matx pytorch rapids tidy LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/cub_public_only.dirty_files b/ci/test/inspect_changes/cub_public_only.dirty_files new file mode 100644 index 000000000000..687c40ca6324 --- /dev/null +++ b/ci/test/inspect_changes/cub_public_only.dirty_files @@ -0,0 +1 @@ +cub/cub/block/block_reduce.cuh diff --git a/ci/test/inspect_changes/cub_public_only.output b/ci/test/inspect_changes/cub_public_only.output new file mode 100644 index 000000000000..d7ecf302cbee --- /dev/null +++ b/ci/test/inspect_changes/cub_public_only.output @@ -0,0 +1,2 @@ +FULL_BUILD=cub tidy +LITE_BUILD=libcudacxx thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/cub_thrust_internal_only.dirty_files b/ci/test/inspect_changes/cub_thrust_internal_only.dirty_files new file mode 100644 index 000000000000..d73c758340f6 --- /dev/null +++ b/ci/test/inspect_changes/cub_thrust_internal_only.dirty_files @@ -0,0 +1,2 @@ +cub/test/catch2_test_block_reduce.cu +thrust/testing/reduce.cu diff --git a/ci/test/inspect_changes/cub_thrust_internal_only.output b/ci/test/inspect_changes/cub_thrust_internal_only.output new file mode 100644 index 000000000000..29cc69e3c648 --- /dev/null +++ b/ci/test/inspect_changes/cub_thrust_internal_only.output @@ -0,0 +1,2 @@ +FULL_BUILD=cub thrust tidy +LITE_BUILD=packaging diff --git a/ci/test/inspect_changes/cudax_public_only.dirty_files b/ci/test/inspect_changes/cudax_public_only.dirty_files new file mode 100644 index 000000000000..58adcda6e0b3 --- /dev/null +++ b/ci/test/inspect_changes/cudax_public_only.dirty_files @@ -0,0 +1 @@ +cudax/include/cuda/experimental/stf.cuh diff --git a/ci/test/inspect_changes/cudax_public_only.output b/ci/test/inspect_changes/cudax_public_only.output new file mode 100644 index 000000000000..bd358baf03b2 --- /dev/null +++ b/ci/test/inspect_changes/cudax_public_only.output @@ -0,0 +1,2 @@ +FULL_BUILD=cudax tidy +LITE_BUILD=cccl_c_stf python packaging diff --git a/ci/test/inspect_changes/ignored_only.output b/ci/test/inspect_changes/ignored_only.output index c1be9e6a9c26..4e9e2ba72280 100644 --- a/ci/test/inspect_changes/ignored_only.output +++ b/ci/test/inspect_changes/ignored_only.output @@ -1,3 +1,2 @@ FULL_BUILD= LITE_BUILD= -HAS_NON_IGNORED_CHANGES=false diff --git a/ci/test/inspect_changes/libcudacxx_both.output b/ci/test/inspect_changes/libcudacxx_both.output index 51fdf3ade726..893859e0c444 100644 --- a/ci/test/inspect_changes/libcudacxx_both.output +++ b/ci/test/inspect_changes/libcudacxx_both.output @@ -1,3 +1,2 @@ FULL_BUILD=libcudacxx tidy -LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper -HAS_NON_IGNORED_CHANGES=true +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/libcudacxx_internal_only.output b/ci/test/inspect_changes/libcudacxx_internal_only.output index 905962e3755a..8e8a2194ab5e 100644 --- a/ci/test/inspect_changes/libcudacxx_internal_only.output +++ b/ci/test/inspect_changes/libcudacxx_internal_only.output @@ -1,3 +1,2 @@ FULL_BUILD=libcudacxx tidy LITE_BUILD=packaging -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/libcudacxx_public_only.output b/ci/test/inspect_changes/libcudacxx_public_only.output index 51fdf3ade726..893859e0c444 100644 --- a/ci/test/inspect_changes/libcudacxx_public_only.output +++ b/ci/test/inspect_changes/libcudacxx_public_only.output @@ -1,3 +1,2 @@ FULL_BUILD=libcudacxx tidy -LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper -HAS_NON_IGNORED_CHANGES=true +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/libcudacxx_thrust.output b/ci/test/inspect_changes/libcudacxx_thrust.output index 2de3f0b57e32..9db4c32989f8 100644 --- a/ci/test/inspect_changes/libcudacxx_thrust.output +++ b/ci/test/inspect_changes/libcudacxx_thrust.output @@ -1,3 +1,2 @@ FULL_BUILD=libcudacxx thrust tidy -LITE_BUILD=cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper -HAS_NON_IGNORED_CHANGES=true +LITE_BUILD=cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/mixed_ignored_and_header.output b/ci/test/inspect_changes/mixed_ignored_and_header.output index 51fdf3ade726..893859e0c444 100644 --- a/ci/test/inspect_changes/mixed_ignored_and_header.output +++ b/ci/test/inspect_changes/mixed_ignored_and_header.output @@ -1,3 +1,2 @@ FULL_BUILD=libcudacxx tidy -LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper -HAS_NON_IGNORED_CHANGES=true +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/multiple_projects.output b/ci/test/inspect_changes/multiple_projects.output index 72f6f1018428..9395cf0aeb6c 100644 --- a/ci/test/inspect_changes/multiple_projects.output +++ b/ci/test/inspect_changes/multiple_projects.output @@ -1,3 +1,2 @@ FULL_BUILD=python_v2 python_tsan python packaging LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/no_changes.output b/ci/test/inspect_changes/no_changes.output index c1be9e6a9c26..4e9e2ba72280 100644 --- a/ci/test/inspect_changes/no_changes.output +++ b/ci/test/inspect_changes/no_changes.output @@ -1,3 +1,2 @@ FULL_BUILD= LITE_BUILD= -HAS_NON_IGNORED_CHANGES=false diff --git a/ci/test/inspect_changes/packaging_only.output b/ci/test/inspect_changes/packaging_only.output index f736032ac8fd..a23e2374a4a6 100644 --- a/ci/test/inspect_changes/packaging_only.output +++ b/ci/test/inspect_changes/packaging_only.output @@ -1,3 +1,2 @@ FULL_BUILD=packaging LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/regenerate_outputs.sh b/ci/test/inspect_changes/regenerate_outputs.sh index 21abd9600f93..464d09bab334 100755 --- a/ci/test/inspect_changes/regenerate_outputs.sh +++ b/ci/test/inspect_changes/regenerate_outputs.sh @@ -17,5 +17,5 @@ for dirty_file in *.dirty_files; do output_file="${test_name}.output" echo "Regenerating ${output_file}" python "${inspect_changes}" --file "${dirty_file}" \ - | awk '/^FULL_BUILD=/{print}/^LITE_BUILD=/{print}/^HAS_NON_IGNORED_CHANGES=/{print}' > "${output_file}" + | awk '/^FULL_BUILD=/{print}/^LITE_BUILD=/{print}' > "${output_file}" done diff --git a/ci/test/inspect_changes/third_party_matx_script.output b/ci/test/inspect_changes/third_party_matx_script.output index bab5a4987878..66f3c34a0c33 100644 --- a/ci/test/inspect_changes/third_party_matx_script.output +++ b/ci/test/inspect_changes/third_party_matx_script.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=matx LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_matx_workflow.output b/ci/test/inspect_changes/third_party_matx_workflow.output index bab5a4987878..66f3c34a0c33 100644 --- a/ci/test/inspect_changes/third_party_matx_workflow.output +++ b/ci/test/inspect_changes/third_party_matx_workflow.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=matx LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_pytorch_script.output b/ci/test/inspect_changes/third_party_pytorch_script.output index bab5a4987878..8451d9f710f9 100644 --- a/ci/test/inspect_changes/third_party_pytorch_script.output +++ b/ci/test/inspect_changes/third_party_pytorch_script.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=pytorch LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_pytorch_workflow.output b/ci/test/inspect_changes/third_party_pytorch_workflow.output index bab5a4987878..8451d9f710f9 100644 --- a/ci/test/inspect_changes/third_party_pytorch_workflow.output +++ b/ci/test/inspect_changes/third_party_pytorch_workflow.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=pytorch LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_rapids_script.output b/ci/test/inspect_changes/third_party_rapids_script.output index bab5a4987878..d42d7870c80c 100644 --- a/ci/test/inspect_changes/third_party_rapids_script.output +++ b/ci/test/inspect_changes/third_party_rapids_script.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=rapids LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/third_party_rapids_workflow.output b/ci/test/inspect_changes/third_party_rapids_workflow.output index bab5a4987878..d42d7870c80c 100644 --- a/ci/test/inspect_changes/third_party_rapids_workflow.output +++ b/ci/test/inspect_changes/third_party_rapids_workflow.output @@ -1,3 +1,2 @@ -FULL_BUILD= +FULL_BUILD=rapids LITE_BUILD= -HAS_NON_IGNORED_CHANGES=true diff --git a/ci/test/inspect_changes/thrust_public_only.dirty_files b/ci/test/inspect_changes/thrust_public_only.dirty_files new file mode 100644 index 000000000000..1451e9ca7c1c --- /dev/null +++ b/ci/test/inspect_changes/thrust_public_only.dirty_files @@ -0,0 +1 @@ +thrust/thrust/reduce.h diff --git a/ci/test/inspect_changes/thrust_public_only.output b/ci/test/inspect_changes/thrust_public_only.output new file mode 100644 index 000000000000..5e061071964f --- /dev/null +++ b/ci/test/inspect_changes/thrust_public_only.output @@ -0,0 +1,2 @@ +FULL_BUILD=thrust tidy +LITE_BUILD=libcudacxx cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/docs/infrastructure/ci/references/change_detection.rst b/docs/infrastructure/ci/references/change_detection.rst index e0a330ca0b0b..0c3429e134d4 100644 --- a/docs/infrastructure/ci/references/change_detection.rst +++ b/docs/infrastructure/ci/references/change_detection.rst @@ -44,8 +44,9 @@ map to it and how rebuilds propagate from it: Projects whose changes trigger a reduced rebuild of this project. ``matrix_project`` - The name this project uses in ``ci/matrix.yaml``. A project without one is - internal to change detection and never appears in the output lists. + The name this project uses in the output lists. Matrix jobs in ``ci/matrix.yaml`` + and separate third-party jobs use these names to select what runs. A project + without one is internal to change detection and never appears in the output lists. The ``core`` project is a catch-all. It declares no ``include_regexes``. Any dirty file that no other project claims lands in ``core`` — a new top-level @@ -107,13 +108,15 @@ whose project is in ``FULL_BUILD``, then reads the ``pull_request_lite`` section and keeps only entries whose project is in ``LITE_BUILD``, then concatenates the two. A project absent from both lists contributes no jobs. -The additional ``HAS_NON_IGNORED_CHANGES`` output is ``true`` if any changed file -survives the global ignore filter, or ``false`` otherwise. The pull-request workflow -uses this when exporting its existing ``matx_enabled``, ``pytorch_enabled``, and -``rapids_enabled`` flags to skip optional builds for documentation-only and other -ignored changes. Their own workflows and build scripts belong to the internal -``third_party`` project, so changes to those files still run third-party tests without -adding CCCL matrix jobs. The existing third-party skip tags continue to apply. +The pull-request workflow also uses these lists when exporting its existing +``matx_enabled``, ``pytorch_enabled``, and ``rapids_enabled`` flags. Each third-party +project depends on the public libcu++, CUB, and Thrust headers, so changes limited +to documentation, tests, or library infrastructure skip these builds. Changes to a +third-party project's own workflow or build scripts run that project; shared CCCL +infrastructure changes run all three. These projects have no entries in +``ci/matrix.yaml``, so their presence in the output lists adds no CCCL matrix jobs. +The existing third-party skip tags continue to apply, and change detection still +runs when the main matrix is disabled with ``[skip-matrix]``. To see the exact lists for any change, run ``inspect_changes.py`` locally: From 72ca424cb312a697a8d71c1c6883fd25ce4d7c8b Mon Sep 17 00:00:00 2001 From: Jake Wang Date: Tue, 20 Oct 2026 21:09:01 -0400 Subject: [PATCH 4/4] ci: include downstream CMake entry points in public changes Cover each public CMake entry path independently and keep internal-only coverage on an actual test file. Remove the unnecessary documentation and configuration commentary requested in review. Assisted-by: OpenAI Codex --- ci/project_files_and_dependencies.yaml | 18 +++++++++++++----- .../cmake_near_misses.dirty_files | 6 ++++++ .../inspect_changes/cmake_near_misses.output | 2 ++ .../cub_cmake_add_subdir.dirty_files | 1 + .../cub_cmake_add_subdir.output | 2 ++ .../cub_cmake_lists.dirty_files | 1 + .../inspect_changes/cub_cmake_lists.output | 2 ++ .../libcudacxx_cmake_add_subdir.dirty_files | 1 + .../libcudacxx_cmake_add_subdir.output | 2 ++ .../libcudacxx_cmake_lists.dirty_files | 1 + .../libcudacxx_cmake_lists.output | 2 ++ .../libcudacxx_internal_only.dirty_files | 2 +- .../thrust_cmake_add_subdir.dirty_files | 1 + .../thrust_cmake_add_subdir.output | 2 ++ .../thrust_cmake_lists.dirty_files | 1 + .../inspect_changes/thrust_cmake_lists.output | 2 ++ .../ci/references/change_detection.rst | 19 ++++--------------- 17 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 ci/test/inspect_changes/cmake_near_misses.dirty_files create mode 100644 ci/test/inspect_changes/cmake_near_misses.output create mode 100644 ci/test/inspect_changes/cub_cmake_add_subdir.dirty_files create mode 100644 ci/test/inspect_changes/cub_cmake_add_subdir.output create mode 100644 ci/test/inspect_changes/cub_cmake_lists.dirty_files create mode 100644 ci/test/inspect_changes/cub_cmake_lists.output create mode 100644 ci/test/inspect_changes/libcudacxx_cmake_add_subdir.dirty_files create mode 100644 ci/test/inspect_changes/libcudacxx_cmake_add_subdir.output create mode 100644 ci/test/inspect_changes/libcudacxx_cmake_lists.dirty_files create mode 100644 ci/test/inspect_changes/libcudacxx_cmake_lists.output create mode 100644 ci/test/inspect_changes/thrust_cmake_add_subdir.dirty_files create mode 100644 ci/test/inspect_changes/thrust_cmake_add_subdir.output create mode 100644 ci/test/inspect_changes/thrust_cmake_lists.dirty_files create mode 100644 ci/test/inspect_changes/thrust_cmake_lists.output diff --git a/ci/project_files_and_dependencies.yaml b/ci/project_files_and_dependencies.yaml index 8d62eec2f8c9..c0e613b1e159 100644 --- a/ci/project_files_and_dependencies.yaml +++ b/ci/project_files_and_dependencies.yaml @@ -23,7 +23,7 @@ # Layout: # project_key: mapping from project key to configuration # name: display name used in logs/reports -# matrix_project: project name to use in the output lists. If not provided, +# matrix_project: project name to use for matrix generation. If not provided, # the project is considered internal-only and will not be listed # in the FULL_BUILD or LITE_BUILD outputs. # lite_dependencies: Add the current project to the `lite` matrix if any of these @@ -46,7 +46,10 @@ projects: name: "libcu++ Public API" lite_dependencies: ['thrust_public', 'cub_public'] full_dependencies: [] - include_regexes: ["libcudacxx/include/"] + include_regexes: + - "libcudacxx/include/" + - "libcudacxx/CMakeLists\\.txt$" + - "libcudacxx/cmake/libcudacxxAddSubdir\\.cmake$" libcudacxx_internal: name: "libcu++ Tests/Infra" @@ -61,7 +64,10 @@ projects: name: "CUB Public API" lite_dependencies: [libcudacxx_public, thrust_public] full_dependencies: [] - include_regexes: ["cub/cub/"] + include_regexes: + - "cub/cub/" + - "cub/CMakeLists\\.txt$" + - "cub/cmake/CubAddSubdir\\.cmake$" cub_internal: name: "CUB Tests/Infra" @@ -76,7 +82,10 @@ projects: name: "Thrust Public API" lite_dependencies: [libcudacxx_public, cub_public] full_dependencies: [] - include_regexes: ["thrust/thrust/"] + include_regexes: + - "thrust/thrust/" + - "thrust/CMakeLists\\.txt$" + - "thrust/cmake/ThrustAddSubdir\\.cmake$" thrust_internal: name: "Thrust Tests/Infra" @@ -248,7 +257,6 @@ projects: full_dependencies: [] include_regexes: ["nvrtcc/"] - # Third-party jobs consume these output names directly; they have no matrix jobs. matx: name: "MatX" matrix_project: "matx" diff --git a/ci/test/inspect_changes/cmake_near_misses.dirty_files b/ci/test/inspect_changes/cmake_near_misses.dirty_files new file mode 100644 index 000000000000..ad746b571e6b --- /dev/null +++ b/ci/test/inspect_changes/cmake_near_misses.dirty_files @@ -0,0 +1,6 @@ +libcudacxx/CMakeLists.txt.bak +libcudacxx/cmake/libcudacxxAddSubdir.cmake.bak +cub/CMakeLists.txt.bak +cub/cmake/CubAddSubdir.cmake.bak +thrust/CMakeLists.txt.bak +thrust/cmake/ThrustAddSubdir.cmake.bak diff --git a/ci/test/inspect_changes/cmake_near_misses.output b/ci/test/inspect_changes/cmake_near_misses.output new file mode 100644 index 000000000000..dbcfd12b278b --- /dev/null +++ b/ci/test/inspect_changes/cmake_near_misses.output @@ -0,0 +1,2 @@ +FULL_BUILD=libcudacxx cub thrust tidy +LITE_BUILD=packaging diff --git a/ci/test/inspect_changes/cub_cmake_add_subdir.dirty_files b/ci/test/inspect_changes/cub_cmake_add_subdir.dirty_files new file mode 100644 index 000000000000..647e98f7b465 --- /dev/null +++ b/ci/test/inspect_changes/cub_cmake_add_subdir.dirty_files @@ -0,0 +1 @@ +cub/cmake/CubAddSubdir.cmake diff --git a/ci/test/inspect_changes/cub_cmake_add_subdir.output b/ci/test/inspect_changes/cub_cmake_add_subdir.output new file mode 100644 index 000000000000..515db679057c --- /dev/null +++ b/ci/test/inspect_changes/cub_cmake_add_subdir.output @@ -0,0 +1,2 @@ +FULL_BUILD=cub tidy +LITE_BUILD=libcudacxx thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/cub_cmake_lists.dirty_files b/ci/test/inspect_changes/cub_cmake_lists.dirty_files new file mode 100644 index 000000000000..99f7919b36a1 --- /dev/null +++ b/ci/test/inspect_changes/cub_cmake_lists.dirty_files @@ -0,0 +1 @@ +cub/CMakeLists.txt diff --git a/ci/test/inspect_changes/cub_cmake_lists.output b/ci/test/inspect_changes/cub_cmake_lists.output new file mode 100644 index 000000000000..515db679057c --- /dev/null +++ b/ci/test/inspect_changes/cub_cmake_lists.output @@ -0,0 +1,2 @@ +FULL_BUILD=cub tidy +LITE_BUILD=libcudacxx thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.dirty_files b/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.dirty_files new file mode 100644 index 000000000000..0a8043e8a8ba --- /dev/null +++ b/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.dirty_files @@ -0,0 +1 @@ +libcudacxx/cmake/libcudacxxAddSubdir.cmake diff --git a/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.output b/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.output new file mode 100644 index 000000000000..adf18b895104 --- /dev/null +++ b/ci/test/inspect_changes/libcudacxx_cmake_add_subdir.output @@ -0,0 +1,2 @@ +FULL_BUILD=libcudacxx tidy +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/libcudacxx_cmake_lists.dirty_files b/ci/test/inspect_changes/libcudacxx_cmake_lists.dirty_files new file mode 100644 index 000000000000..879d2d5f0fd5 --- /dev/null +++ b/ci/test/inspect_changes/libcudacxx_cmake_lists.dirty_files @@ -0,0 +1 @@ +libcudacxx/CMakeLists.txt diff --git a/ci/test/inspect_changes/libcudacxx_cmake_lists.output b/ci/test/inspect_changes/libcudacxx_cmake_lists.output new file mode 100644 index 000000000000..adf18b895104 --- /dev/null +++ b/ci/test/inspect_changes/libcudacxx_cmake_lists.output @@ -0,0 +1,2 @@ +FULL_BUILD=libcudacxx tidy +LITE_BUILD=cub thrust cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/libcudacxx_internal_only.dirty_files b/ci/test/inspect_changes/libcudacxx_internal_only.dirty_files index 879d2d5f0fd5..f346c289bb63 100644 --- a/ci/test/inspect_changes/libcudacxx_internal_only.dirty_files +++ b/ci/test/inspect_changes/libcudacxx_internal_only.dirty_files @@ -1 +1 @@ -libcudacxx/CMakeLists.txt +libcudacxx/test/support/test_macros.h diff --git a/ci/test/inspect_changes/thrust_cmake_add_subdir.dirty_files b/ci/test/inspect_changes/thrust_cmake_add_subdir.dirty_files new file mode 100644 index 000000000000..be98580659f1 --- /dev/null +++ b/ci/test/inspect_changes/thrust_cmake_add_subdir.dirty_files @@ -0,0 +1 @@ +thrust/cmake/ThrustAddSubdir.cmake diff --git a/ci/test/inspect_changes/thrust_cmake_add_subdir.output b/ci/test/inspect_changes/thrust_cmake_add_subdir.output new file mode 100644 index 000000000000..7ebd5d9da2ea --- /dev/null +++ b/ci/test/inspect_changes/thrust_cmake_add_subdir.output @@ -0,0 +1,2 @@ +FULL_BUILD=thrust tidy +LITE_BUILD=libcudacxx cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/ci/test/inspect_changes/thrust_cmake_lists.dirty_files b/ci/test/inspect_changes/thrust_cmake_lists.dirty_files new file mode 100644 index 000000000000..f7aeff640356 --- /dev/null +++ b/ci/test/inspect_changes/thrust_cmake_lists.dirty_files @@ -0,0 +1 @@ +thrust/CMakeLists.txt diff --git a/ci/test/inspect_changes/thrust_cmake_lists.output b/ci/test/inspect_changes/thrust_cmake_lists.output new file mode 100644 index 000000000000..7ebd5d9da2ea --- /dev/null +++ b/ci/test/inspect_changes/thrust_cmake_lists.output @@ -0,0 +1,2 @@ +FULL_BUILD=thrust tidy +LITE_BUILD=libcudacxx cub cudax cccl_c_parallel cccl_c_parallel_v2 python_v2 python_tsan cccl_c_stf python cuda_coop_python packaging stdpar nvbench_helper matx pytorch rapids diff --git a/docs/infrastructure/ci/references/change_detection.rst b/docs/infrastructure/ci/references/change_detection.rst index 0c3429e134d4..197f64b3a8db 100644 --- a/docs/infrastructure/ci/references/change_detection.rst +++ b/docs/infrastructure/ci/references/change_detection.rst @@ -44,9 +44,8 @@ map to it and how rebuilds propagate from it: Projects whose changes trigger a reduced rebuild of this project. ``matrix_project`` - The name this project uses in the output lists. Matrix jobs in ``ci/matrix.yaml`` - and separate third-party jobs use these names to select what runs. A project - without one is internal to change detection and never appears in the output lists. + The name this project uses in ``ci/matrix.yaml``. A project without one is + internal to change detection and never appears in the output lists. The ``core`` project is a catch-all. It declares no ``include_regexes``. Any dirty file that no other project claims lands in ``core`` — a new top-level @@ -93,8 +92,8 @@ from any project in ``FULL_BUILD`` is added to ``LITE_BUILD``. Output ------ -``inspect_changes.py`` emits two GitHub Actions outputs containing space-separated -lists of ``matrix_project`` values: +``inspect_changes.py`` emits two GitHub Actions outputs, each a space-separated +list of ``matrix_project`` values: ``FULL_BUILD`` Projects that build and test their full job set. @@ -108,16 +107,6 @@ whose project is in ``FULL_BUILD``, then reads the ``pull_request_lite`` section and keeps only entries whose project is in ``LITE_BUILD``, then concatenates the two. A project absent from both lists contributes no jobs. -The pull-request workflow also uses these lists when exporting its existing -``matx_enabled``, ``pytorch_enabled``, and ``rapids_enabled`` flags. Each third-party -project depends on the public libcu++, CUB, and Thrust headers, so changes limited -to documentation, tests, or library infrastructure skip these builds. Changes to a -third-party project's own workflow or build scripts run that project; shared CCCL -infrastructure changes run all three. These projects have no entries in -``ci/matrix.yaml``, so their presence in the output lists adds no CCCL matrix jobs. -The existing third-party skip tags continue to apply, and change detection still -runs when the main matrix is disabled with ``[skip-matrix]``. - To see the exact lists for any change, run ``inspect_changes.py`` locally: .. code-block:: bash