-
Notifications
You must be signed in to change notification settings - Fork 140
[FEA] Add selective test execution for PR builds #931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| #!/bin/bash | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| # Helper script to detect which test components should run based on changed files. | ||
| # Source this script to set the CUOPT_TEST_COMPONENTS variable. | ||
| # | ||
| # Usage: source ci/detect_test_components.sh | ||
| # | ||
| # Sets CUOPT_TEST_COMPONENTS to a comma-separated list of components (routing,lp,mip) | ||
| # or "all" if broad/shared changes are detected or if not in a pull-request build. | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| detect_test_components() { | ||
| # If CUOPT_TEST_COMPONENTS is already set externally, respect it | ||
| if [[ -n "${CUOPT_TEST_COMPONENTS:-}" ]]; then | ||
| export CUOPT_TEST_COMPONENTS | ||
| return | ||
| fi | ||
|
|
||
| # Only apply selective testing for pull-request builds | ||
| if [[ "${RAPIDS_BUILD_TYPE:-}" != "pull-request" ]]; then | ||
| export CUOPT_TEST_COMPONENTS="all" | ||
| return | ||
| fi | ||
|
|
||
| # In RAPIDS CI pull-request builds, the branch is a merge commit so | ||
| # HEAD~1..HEAD gives the full PR diff. If the parent isn't reachable | ||
| # (e.g. shallow clone or non-merge workflow), fall back to running all. | ||
| local changed_files | ||
| if ! git rev-parse --verify HEAD~1 &>/dev/null; then | ||
| export CUOPT_TEST_COMPONENTS="all" | ||
| return | ||
| fi | ||
| if ! changed_files=$(git diff --name-only HEAD~1..HEAD 2>/dev/null); then | ||
|
Comment on lines
+28
to
+36
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not true. It isn't like in other open-source projects on GitHub where HEAD is a merge commit created by GitHub that merges the PR branch into the target branch. That is why in the RAPIDS I think this check You may want to look into something like
It produces an output listing all the files that changed: https://github.com/step-security/changed-files?tab=readme-ov-file#outputs- |
||
| # If git diff fails, run all tests to be safe | ||
|
Comment on lines
+28
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's look at the full script context to understand the code better
cd /tmp && git ls-files | head -20Repository: NVIDIA/cuopt Length of output: 124 🏁 Script executed: # Find and examine the script
find . -name "detect_test_components.sh" -type f 2>/dev/nullRepository: NVIDIA/cuopt Length of output: 86 🏁 Script executed: # Check GitHub Actions workflows
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -20Repository: NVIDIA/cuopt Length of output: 505 🏁 Script executed: # Read the full detect_test_components.sh script
cat -n ci/detect_test_components.shRepository: NVIDIA/cuopt Length of output: 6237 🏁 Script executed: # Check the PR workflow configuration
cat -n .github/workflows/pr.yamlRepository: NVIDIA/cuopt Length of output: 20632 🏁 Script executed: # Also check test.yaml
cat -n .github/workflows/test.yamlRepository: NVIDIA/cuopt Length of output: 4785 🏁 Script executed: # Look for any documentation about how RAPIDS CI handles PR checkouts
find . -name "*.md" -o -name "*.txt" | xargs grep -l "RAPIDS_BUILD_TYPE\|pull-request" 2>/dev/null | head -5Repository: NVIDIA/cuopt Length of output: 73 🏁 Script executed: # Check if there are any comments/docs in the script about the merge commit assumption
grep -n "merge\|parent\|HEAD~1" ci/detect_test_components.shRepository: NVIDIA/cuopt Length of output: 427 🏁 Script executed: # Search for any references to the merge commit handling in other CI scripts
grep -r "HEAD~1\|merge.*commit" ci/ --include="*.sh" 2>/dev/null | head -10Repository: NVIDIA/cuopt Length of output: 452 Add a merge-commit check before using The current check at line 32 only verifies that Proposed fix if ! git rev-parse --verify HEAD~1 &>/dev/null; then
export CUOPT_TEST_COMPONENTS="all"
return
fi
+ # Require merge-commit context for HEAD~1..HEAD PR diff assumption.
+ # `git rev-list --parents -n 1 HEAD` returns: <sha> <parent1> [parent2...]
+ if [[ $(git rev-list --parents -n 1 HEAD | awk '{print NF}') -lt 3 ]]; then
+ export CUOPT_TEST_COMPONENTS="all"
+ return
+ fi
if ! changed_files=$(git diff --name-only HEAD~1..HEAD 2>/dev/null); then🤖 Prompt for AI Agents |
||
| export CUOPT_TEST_COMPONENTS="all" | ||
| return | ||
| fi | ||
|
|
||
| if [[ -z "${changed_files}" ]]; then | ||
| export CUOPT_TEST_COMPONENTS="all" | ||
| return | ||
| fi | ||
|
|
||
| local components="" | ||
| local run_all=false | ||
|
|
||
| # Check for shared/infrastructure changes that should trigger all tests | ||
| while IFS= read -r file; do | ||
| case "${file}" in | ||
| cpp/include/*|cpp/cmake/*|cpp/CMakeLists.txt|cpp/src/utilities/*) | ||
| run_all=true | ||
| break | ||
| ;; | ||
| # Changes to test infrastructure | ||
| cpp/tests/CMakeLists.txt|cpp/tests/utilities/*) | ||
| run_all=true | ||
| break | ||
| ;; | ||
| # Changes to CI infrastructure | ||
| ci/test_cpp.sh|ci/test_python.sh|ci/test_wheel_cuopt.sh|ci/run_ctests.sh|ci/run_cuopt_pytests.sh|ci/detect_test_components.sh) | ||
| run_all=true | ||
| break | ||
| ;; | ||
| # Changes to conda/build config | ||
| conda/*|dependencies.yaml) | ||
| run_all=true | ||
| break | ||
| ;; | ||
| esac | ||
| done <<< "${changed_files}" | ||
|
|
||
| if ${run_all}; then | ||
| export CUOPT_TEST_COMPONENTS="all" | ||
| return | ||
| fi | ||
|
|
||
| # Detect individual components | ||
| local has_routing=false | ||
| local has_lp=false | ||
| local has_mip=false | ||
|
|
||
| while IFS= read -r file; do | ||
| case "${file}" in | ||
| # Routing component | ||
| cpp/src/routing/*|cpp/src/distance/*|cpp/tests/routing/*|cpp/tests/distance_engine/*|cpp/tests/examples/routing/*) | ||
| has_routing=true | ||
| ;; | ||
| python/cuopt/cuopt/routing/*|python/cuopt/cuopt/tests/routing/*) | ||
| has_routing=true | ||
| ;; | ||
| regression/routing*) | ||
| has_routing=true | ||
| ;; | ||
| # LP component | ||
| cpp/src/dual_simplex/*|cpp/src/barrier/*|cpp/src/pdlp/*|cpp/src/math_optimization/*) | ||
| has_lp=true | ||
| ;; | ||
| cpp/tests/linear_programming/*|cpp/tests/dual_simplex/*|cpp/tests/qp/*) | ||
| has_lp=true | ||
| ;; | ||
| python/cuopt/cuopt/tests/linear_programming/*|python/cuopt/cuopt/tests/quadratic_programming/*) | ||
| has_lp=true | ||
| ;; | ||
| # LP regression | ||
| regression/lp*) | ||
| has_lp=true | ||
| ;; | ||
| # MIP component | ||
| cpp/src/branch_and_bound/*|cpp/src/cuts/*|cpp/src/mip_heuristics/*) | ||
| has_mip=true | ||
| ;; | ||
| cpp/tests/mip/*) | ||
| has_mip=true | ||
| ;; | ||
| regression/mip*) | ||
| has_mip=true | ||
| ;; | ||
| # Python source changes that could affect any component | ||
| python/cuopt/cuopt/*.py|python/cuopt/cuopt/distance_engine/*|python/cuopt/cuopt/utils/*) | ||
| has_routing=true | ||
| has_lp=true | ||
| ;; | ||
| python/libcuopt/*) | ||
| has_routing=true | ||
| has_lp=true | ||
| has_mip=true | ||
| ;; | ||
| esac | ||
| done <<< "${changed_files}" | ||
|
|
||
| # Build the components string | ||
| if ${has_routing}; then | ||
| components="${components:+${components},}routing" | ||
| fi | ||
| if ${has_lp}; then | ||
| components="${components:+${components},}lp" | ||
| fi | ||
| if ${has_mip}; then | ||
| components="${components:+${components},}mip" | ||
| fi | ||
|
|
||
| # If no specific component was detected, default to all | ||
| if [[ -z "${components}" ]]; then | ||
| components="all" | ||
| fi | ||
|
|
||
| export CUOPT_TEST_COMPONENTS="${components}" | ||
| } | ||
|
|
||
| detect_test_components | ||
| echo "CUOPT_TEST_COMPONENTS=${CUOPT_TEST_COMPONENTS}" | ||
Uh oh!
There was an error while loading. Please reload this page.