Skip to content

[FEA] Add selective test execution for PR builds#931

Open
bala-bhargav wants to merge 3 commits intoNVIDIA:release/26.04from
bala-bhargav:feat/ci-selective-test-execution-861
Open

[FEA] Add selective test execution for PR builds#931
bala-bhargav wants to merge 3 commits intoNVIDIA:release/26.04from
bala-bhargav:feat/ci-selective-test-execution-861

Conversation

@bala-bhargav
Copy link

@bala-bhargav bala-bhargav commented Mar 4, 2026

Implements component-level selective test execution for pull request CI builds. When a PR only touches routing code, only routing tests and datasets are downloaded/run. Same for LP and MIP. Nightly builds continue running everything unchanged.
#861

@bala-bhargav bala-bhargav requested a review from a team as a code owner March 4, 2026 17:41
@bala-bhargav bala-bhargav requested a review from jameslamb March 4, 2026 17:41
@copy-pr-bot
Copy link

copy-pr-bot bot commented Mar 4, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds component-aware CI: GitHub workflow detects routing/LP/MIP changes and sets flags; new script derives CUOPT_TEST_COMPONENTS; CI shell scripts conditionally run C++/Python tests and download datasets based on selected components.

Changes

Cohort / File(s) Summary
C++ test runner & filters
ci/run_ctests.sh, ci/test_cpp.sh
Adds should_run_test() to filter gtest binaries by CUOPT_TEST_COMPONENTS; test loop skips non-matching gtests with updated messaging. ci/test_cpp.sh now conditionally downloads LP/MIP/routing datasets (sets/exports RAPIDS_DATASET_ROOT_DIR) and logs component-aware run message.
Python test runner & wheel CI
ci/run_cuopt_pytests.sh, ci/test_python.sh, ci/test_wheel_cuopt.sh
Selects pytest directories based on CUOPT_TEST_COMPONENTS (e.g., routing → tests/routing, lp → tests/linear_programming, tests/quadratic_programming); conditionally downloads datasets and echoes component context before running pytests; preserves CLI test execution.
Component derivation script
ci/derive_test_components.sh
New script that computes CUOPT_TEST_COMPONENTS from CUOPT_ROUTING_CHANGED, CUOPT_LP_CHANGED, and CUOPT_MIP_CHANGED; defaults to all when none match; echoes the result.
Workflow changes
.github/workflows/pr.yaml
Adds changed-file groups test_routing, test_lp, test_mip and exports CUOPT_ROUTING_CHANGED, CUOPT_LP_CHANGED, CUOPT_MIP_CHANGED into CI jobs before invoking test scripts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding selective test execution capability for PR builds, which is the core focus of all the modifications.
Description check ✅ Passed The description accurately relates to the changeset, explaining how component-level selective test execution works for PR builds while nightly builds remain unchanged.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can scan for known vulnerabilities in your dependencies using OSV Scanner.

OSV Scanner will automatically detect and report security vulnerabilities in your project's dependencies. No additional configuration is required.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ci/run_ctests.sh`:
- Around line 28-34: The UNIT_TEST and PRESOLVE_TEST blocks currently only allow
running when components contains "mip", which skips them for LP-only runs;
update the conditional in both the UNIT_TEST and PRESOLVE_TEST cases (refer to
the UNIT_TEST and PRESOLVE_TEST labels and the components variable) to also
accept "lp" (e.g., check for "mip" or "lp" inside components) so those tests run
for LP-selected PRs as well.
- Line 25: The case pattern contains a redundant subpattern "MIP_TERMINATION_*"
because the earlier "MIP_*" already matches it; update the case arm that
currently reads 'MIP_*|PROBLEM_*|...|MIP_TERMINATION_*|...' by removing the
"MIP_TERMINATION_*" token so the pattern list no longer contains the unreachable
subpattern (keep all other alternatives unchanged).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9450e103-1ed3-4907-9d70-8f2b748e6975

📥 Commits

Reviewing files that changed from the base of the PR and between 0aa1b31 and f9cf547.

📒 Files selected for processing (6)
  • ci/detect_test_components.sh
  • ci/run_ctests.sh
  • ci/run_cuopt_pytests.sh
  • ci/test_cpp.sh
  • ci/test_python.sh
  • ci/test_wheel_cuopt.sh

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ci/detect_test_components.sh`:
- Around line 17-19: The script's early-return branch checks
CUOPT_TEST_COMPONENTS but doesn't export it, so child processes may not see a
non-exported shell variable; update the conditional in detect_test_components.sh
to export the variable before returning (e.g., call export CUOPT_TEST_COMPONENTS
inside the if [[ -n "${CUOPT_TEST_COMPONENTS:-}" ]]; then block) so the existing
value is preserved for child scripts without changing the branch logic.

In `@ci/test_python.sh`:
- Around line 45-50: The current conditional uses a combined check that causes
both ./datasets/linear_programming/download_pdlp_test_dataset.sh and
./datasets/mip/download_miplib_test_dataset.sh to run when CUOPT_TEST_COMPONENTS
contains either "lp" or "mip"; change the logic to perform separate checks so
each dataset script runs only when its component is requested. Replace the
single if-block that references CUOPT_TEST_COMPONENTS with two conditional
checks: one that runs download_pdlp_test_dataset.sh only when
CUOPT_TEST_COMPONENTS equals "all" or contains "lp", and another that runs
download_miplib_test_dataset.sh only when CUOPT_TEST_COMPONENTS equals "all" or
contains "mip"; keep the rapids-logger fallback message for when neither dataset
is needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 34c2f55c-352a-4220-9b3d-41df53cfc3f1

📥 Commits

Reviewing files that changed from the base of the PR and between f9cf547 and e7be4f5.

📒 Files selected for processing (6)
  • ci/detect_test_components.sh
  • ci/run_ctests.sh
  • ci/run_cuopt_pytests.sh
  • ci/test_cpp.sh
  • ci/test_python.sh
  • ci/test_wheel_cuopt.sh
🚧 Files skipped from review as they are similar to previous changes (3)
  • ci/test_cpp.sh
  • ci/run_ctests.sh
  • ci/test_wheel_cuopt.sh

@anandhkb anandhkb added this to the 26.04 milestone Mar 4, 2026
Add component-level test filtering to CI scripts so that pull requests
only run tests relevant to the changed files (routing, LP, or MIP).
Nightly builds continue to run all tests.

- New: ci/detect_test_components.sh — detects changed components from
  the PR diff and exports CUOPT_TEST_COMPONENTS
- Modified: run_ctests.sh — added should_run_test() to filter gtests
  by component
- Modified: run_cuopt_pytests.sh — select pytest directories by component
- Modified: test_cpp.sh, test_python.sh, test_wheel_cuopt.sh — conditional
  dataset downloads based on detected components

Closes NVIDIA#861
@bala-bhargav bala-bhargav force-pushed the feat/ci-selective-test-execution-861 branch from e7be4f5 to b93bd54 Compare March 5, 2026 01:06
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ci/detect_test_components.sh`:
- Around line 28-37: The script currently only verifies HEAD~1 exists before
using git diff HEAD~1..HEAD, which can under-select tests on non-merge commits;
update the pre-check to also verify that HEAD is a merge commit (has at least
two parents) before using HEAD~1..HEAD. In the block that checks git rev-parse
--verify HEAD~1 and before running git diff, add a check (e.g., test for HEAD^2
via git rev-parse --verify HEAD^2 or inspect parents) and if that check fails
set CUOPT_TEST_COMPONENTS="all" and return; keep the existing changed_files
variable and subsequent git diff HEAD~1..HEAD logic unchanged otherwise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 334b8f94-22a6-4673-8238-9c35f0b7294f

📥 Commits

Reviewing files that changed from the base of the PR and between e7be4f5 and b93bd54.

📒 Files selected for processing (6)
  • ci/detect_test_components.sh
  • ci/run_ctests.sh
  • ci/run_cuopt_pytests.sh
  • ci/test_cpp.sh
  • ci/test_python.sh
  • ci/test_wheel_cuopt.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • ci/test_wheel_cuopt.sh

Comment on lines +28 to +37
# 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
# If git diff fails, run all tests to be safe
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the full script context to understand the code better
cd /tmp && git ls-files | head -20

Repository: NVIDIA/cuopt

Length of output: 124


🏁 Script executed:

# Find and examine the script
find . -name "detect_test_components.sh" -type f 2>/dev/null

Repository: NVIDIA/cuopt

Length of output: 86


🏁 Script executed:

# Check GitHub Actions workflows
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -20

Repository: NVIDIA/cuopt

Length of output: 505


🏁 Script executed:

# Read the full detect_test_components.sh script
cat -n ci/detect_test_components.sh

Repository: NVIDIA/cuopt

Length of output: 6237


🏁 Script executed:

# Check the PR workflow configuration
cat -n .github/workflows/pr.yaml

Repository: NVIDIA/cuopt

Length of output: 20632


🏁 Script executed:

# Also check test.yaml
cat -n .github/workflows/test.yaml

Repository: 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 -5

Repository: 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.sh

Repository: 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 -10

Repository: NVIDIA/cuopt

Length of output: 452


Add a merge-commit check before using HEAD~1..HEAD for PR diff.

The current check at line 32 only verifies that HEAD~1 exists, but doesn't guarantee HEAD is a merge commit. On a single-parent commit, HEAD~1..HEAD shows only that commit, not the full PR diff—potentially under-selecting tests. The code comment already acknowledges non-merge workflows as a fallback case, so add the verification:

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
Verify each finding against the current code and only fix it if needed.

In `@ci/detect_test_components.sh` around lines 28 - 37, The script currently only
verifies HEAD~1 exists before using git diff HEAD~1..HEAD, which can
under-select tests on non-merge commits; update the pre-check to also verify
that HEAD is a merge commit (has at least two parents) before using
HEAD~1..HEAD. In the block that checks git rev-parse --verify HEAD~1 and before
running git diff, add a check (e.g., test for HEAD^2 via git rev-parse --verify
HEAD^2 or inspect parents) and if that check fails set
CUOPT_TEST_COMPONENTS="all" and return; keep the existing changed_files variable
and subsequent git diff HEAD~1..HEAD logic unchanged otherwise.

Copy link
Member

@jameslamb jameslamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being done in shell scripts?

We already have a GitHub Action that runs on PR CI to do exactly this, and would prefer to not have multiple competing implementations of the same behavior.

changed-files:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/changed-files.yaml@main

@rgsl888prabhu
Copy link
Collaborator

Why is this being done in shell scripts?

We already have a GitHub Action that runs on PR CI to do exactly this, and would prefer to not have multiple competing implementations of the same behavior.

changed-files:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/changed-files.yaml@main

Hi @jameslamb,

The issue stems from multiple solvers under same library, currently routing is in good state and we don't change anything related to it often, so we wanted to reduce routing test overhead. Currently we are are using your approach a whole for the complete test, but here we need to selectively not run part of the tests.

Can you please suggest a better approach where we can use existing method to disable the tests? Should we separate these tests into different workflow or is there a way we can pass env variable to enable or disable these tests based on the files ?

Copy link
Member

@jameslamb jameslamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please suggest a better approach where we can use existing method to disable the tests? Should we separate these tests into different workflow or is there a way we can pass env variable to enable or disable these tests based on the files ?

Yes, definitely!

Looking at this more closely and with the benefit of your description, I do understand how this is a bit different than the top-level "run / don't run an entire workflow" changed-files gate.

I think you could re-use the output of the changed-files workflow for this purpose though. Each of the changed-files groups holds a boolean saying whether or not a group of file patterns was matched.

if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp

I think you could re-use those to pass environment variables to the code (doing what ci/detect_test_components.sh is attempting to do).

Something like this:

conda-python-tests:
  needs: [conda-python-build, changed-files, compute-matrix-filters]
  uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@main
  if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python_conda
  with:
    script: |
        CUOPT_ROUTING_FILES_CHANGED="${{ fromJSON(needs.changed-files.outputs.changed_file_groups).test_routing }}"
        export CUOPT_ROUTING_FILES_CHANGED
        ci/test_python.sh

And then handle those variables in test scripts however you want.

Untested, but in theory I think multi-line scripts like this should work: https://github.com/rapidsai/shared-workflows/blob/52b43724e7c9edba0acf675aaf6f526a22b3111f/.github/workflows/conda-python-tests.yaml#L304

If not, you can combine everything together with ;.

Benefits of this approach:

  • no need to re-implement the "figure out which files changed in the PR" logic (it is not trivial!)
  • less shell code to maintain
  • allows the groups to be re-used and combined for other jobs
  • puts all of the "which files affect which workflows" logic in one place (changed-files: configuration in pr.yaml) instead

And whether or not you do that, please do consider how these things will work when the tests scripts are run in workflow NOT triggered by a PR.

Comment on lines +28 to +36
# 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not true. copy-pr-bot copies commits from the PR branch to a branch on the repo called pull-request/{pr-number} and there HEAD is exactly HEAD of the PR branch.

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 changed-files action, we do some work to figure out what the target branch of the PR was:

https://github.com/rapidsai/shared-actions/blob/f722a09c99e883ccca580bbb7135945d8efb90e0/changed-files/action.yml#L40-L45

I think this check HEAD~1..HEAD is only going to compare between the difference between the latest and previous-to-that commit on the PR branch, which is not what you want.

You may want to look into something like step-security/changed-files, which the existing RAPIDS changed-files action uses:

It produces an output listing all the files that changed: https://github.com/step-security/changed-files?tab=readme-ov-file#outputs-

@rgsl888prabhu
Copy link
Collaborator

@bala-bhargav Can you follow-up with the review requests ?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/pr.yaml (1)

336-340: Consider deduplicating the repeated component-export block.

The same 3-line export logic appears in three jobs; extracting it into one helper script/composite action would reduce drift risk when component definitions evolve.

Also applies to: 364-368, 429-433

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr.yaml around lines 336 - 340, The repeated three-line
export block setting CUOPT_ROUTING_CHANGED, CUOPT_LP_CHANGED, and
CUOPT_MIP_CHANGED should be extracted into a single reusable helper (script or
composite action) called, for example, export_changed_components.sh (or
export-changed-components action); create that helper to evaluate
fromJSON(needs.changed-files.outputs.changed_file_groups) and export the three
variables, then replace each repeated block in the workflow jobs with a single
call to that helper so all occurrences (including the blocks currently around
CUOPT_* and the other two identical blocks) stay in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/pr.yaml:
- Around line 336-340: The repeated three-line export block setting
CUOPT_ROUTING_CHANGED, CUOPT_LP_CHANGED, and CUOPT_MIP_CHANGED should be
extracted into a single reusable helper (script or composite action) called, for
example, export_changed_components.sh (or export-changed-components action);
create that helper to evaluate
fromJSON(needs.changed-files.outputs.changed_file_groups) and export the three
variables, then replace each repeated block in the workflow jobs with a single
call to that helper so all occurrences (including the blocks currently around
CUOPT_* and the other two identical blocks) stay in sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3f49e996-36c3-430e-88df-b912cb4f0509

📥 Commits

Reviewing files that changed from the base of the PR and between b93bd54 and 09489bf.

📒 Files selected for processing (5)
  • .github/workflows/pr.yaml
  • ci/derive_test_components.sh
  • ci/test_cpp.sh
  • ci/test_python.sh
  • ci/test_wheel_cuopt.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • ci/test_cpp.sh

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/pr.yaml (1)

288-289: Regression path globs should include nested files explicitly.

Line 288, Line 311, and Line 331 use regression/<component>*, which can miss files inside nested directories. That weakens selective execution and can silently degrade to broader test runs.

Suggested patch
         test_routing:
-          - 'regression/routing*'
+          - 'regression/routing*'
+          - 'regression/routing*/**'
@@
         test_lp:
-          - 'regression/lp*'
+          - 'regression/lp*'
+          - 'regression/lp*/**'
@@
         test_mip:
-          - 'regression/mip*'
+          - 'regression/mip*'
+          - 'regression/mip*/**'

Also applies to: 311-312, 331-332

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr.yaml around lines 288 - 289, Replace the shallow glob
patterns like 'regression/routing*' (and the similar 'regression/<component>*'
occurrences) with explicit recursive globs to include nested files, e.g. use
'regression/routing/**' (and likewise 'regression/<component>/**' for the other
components); if you still need to match top-level files alongside directories,
include both 'regression/<component>*' and 'regression/<component>/**' for each
occurrence (update the three occurrences flagged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr.yaml:
- Around line 325-327: The CI currently sets CUOPT_TEST_COMPONENTS="mip" when
CUOPT_MIP_CHANGED is true but CUOPT_LP_CHANGED is unset, and
run_cuopt_pytests.sh has no mapping for the "mip" component, causing LP python
tests to be skipped; update the component derivation logic so that whenever
CUOPT_MIP_CHANGED is true you also set CUOPT_LP_CHANGED or append "lp" to
CUOPT_TEST_COMPONENTS (or alternatively add a "mip" -> LP test-directory mapping
inside run_cuopt_pytests.sh), ensuring CUOPT_MIP_CHANGED, CUOPT_LP_CHANGED,
CUOPT_TEST_COMPONENTS and the script run_cuopt_pytests.sh are modified
consistently so MIP-only file changes still trigger LP python tests.

---

Nitpick comments:
In @.github/workflows/pr.yaml:
- Around line 288-289: Replace the shallow glob patterns like
'regression/routing*' (and the similar 'regression/<component>*' occurrences)
with explicit recursive globs to include nested files, e.g. use
'regression/routing/**' (and likewise 'regression/<component>/**' for the other
components); if you still need to match top-level files alongside directories,
include both 'regression/<component>*' and 'regression/<component>/**' for each
occurrence (update the three occurrences flagged).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e91b54f6-facb-429f-8d58-fa5499386b42

📥 Commits

Reviewing files that changed from the base of the PR and between 09489bf and 60af7c6.

📒 Files selected for processing (3)
  • .github/workflows/pr.yaml
  • ci/run_ctests.sh
  • ci/test_python.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • ci/run_ctests.sh
  • ci/test_python.sh

Comment on lines +325 to +327
# Note: MIP has no separate Python tests (tested through LP tests).
# If MIP-specific Python tests are added, include their paths here.
- 'cpp/src/branch_and_bound/**'
Copy link

@coderabbitai coderabbitai bot Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Inspecting component-derivation and python test selection logic..."
fd -t f 'derive_test_components.sh|run_cuopt_pytests.sh|test_python.sh|test_wheel_cuopt.sh|test_cpp.sh|run_ctests.sh' ci

echo
echo "Key logic around component mapping:"
for f in $(fd -t f 'derive_test_components.sh|run_cuopt_pytests.sh|test_python.sh|test_wheel_cuopt.sh' ci); do
  echo "---- $f ----"
  rg -n -C3 'CUOPT_TEST_COMPONENTS|CUOPT_MIP_CHANGED|CUOPT_LP_CHANGED|mip|lp' "$f" || true
done

echo
echo "Expected verification outcome:"
echo "For MIP-only changes, either LP python test paths are selected, or rationale is explicit and intentional."

Repository: NVIDIA/cuopt

Length of output: 5920


🏁 Script executed:

sed -n '320,330p' .github/workflows/pr.yaml
echo "---"
sed -n '385,395p' .github/workflows/pr.yaml
echo "---"
sed -n '450,460p' .github/workflows/pr.yaml

Repository: NVIDIA/cuopt

Length of output: 1753


MIP-only changes will skip LP Python tests due to component mapping gap.

The pr.yaml comment at line 325 states MIP is validated through LP tests, but the current CI logic creates a separate test_mip component that doesn't cascade to LP tests. When only MIP files change (e.g., cpp/src/branch_and_bound/**), the workflow exports CUOPT_MIP_CHANGED=true and CUOPT_LP_CHANGED unset, causing CUOPT_TEST_COMPONENTS="mip". The run_cuopt_pytests.sh script has no test-directory mapping for the mip component (line 25 confirms "MIP does not have separate Python tests"), so the script exits early without running any tests.

Either (1) update the component derivation logic to include lp whenever mip changes, (2) add explicit Python test directories for MIP validation, or (3) update the file trigger paths to map MIP changes to test_lp instead. The current state contradicts the documented test strategy.

Also applies to: 389–392, 453–457

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr.yaml around lines 325 - 327, The CI currently sets
CUOPT_TEST_COMPONENTS="mip" when CUOPT_MIP_CHANGED is true but CUOPT_LP_CHANGED
is unset, and run_cuopt_pytests.sh has no mapping for the "mip" component,
causing LP python tests to be skipped; update the component derivation logic so
that whenever CUOPT_MIP_CHANGED is true you also set CUOPT_LP_CHANGED or append
"lp" to CUOPT_TEST_COMPONENTS (or alternatively add a "mip" -> LP test-directory
mapping inside run_cuopt_pytests.sh), ensuring CUOPT_MIP_CHANGED,
CUOPT_LP_CHANGED, CUOPT_TEST_COMPONENTS and the script run_cuopt_pytests.sh are
modified consistently so MIP-only file changes still trigger LP python tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bala-bhargav this is a good suggestion.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Collaborator

@rgsl888prabhu rgsl888prabhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bala-bhargav Awesome work, I have few suggestions, please let me know if you have any questions


# Map test binary names to components
case "${test_name}" in
ROUTING_*|WAYPOINT_*|VEHICLE_*|OBJECTIVE_*|RETAIL_*)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a suggestion, please explore if you can come across better approach.

I am trying to see how to make it easier to manage, if we can have these tests installed per module, like routing, lp, milp, it would be easier to just add those directory instead of adding each new test to this list.

We may have to update cpp/test/CmakeLists.txt

    install(
        TARGETS ${CMAKE_TEST_NAME}
        COMPONENT testing
        DESTINATION bin/gtests/libcuopt
        EXCLUDE_FROM_ALL
    )

to keep the lower folders intact so we can use them

Image

Comment on lines +325 to +327
# Note: MIP has no separate Python tests (tested through LP tests).
# If MIP-specific Python tests are added, include their paths here.
- 'cpp/src/branch_and_bound/**'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bala-bhargav this is a good suggestion.

- 'cpp/src/mip_heuristics/**'
- 'cpp/tests/mip/**'
- 'regression/mip*'
- 'cpp/include/**'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 'cpp/include/**'
- 'cpp/include/cuopt/error.hpp'
- 'cpp/include/cuopt/linear_programming/**'
- 'cpp/inlcude/cuopt/utilities/**'

- 'python/cuopt/cuopt/tests/linear_programming/**'
- 'python/cuopt/cuopt/tests/quadratic_programming/**'
- 'regression/lp*'
- 'cpp/include/**'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 'cpp/include/**'
- 'cpp/include/cuopt/error.hpp'
- 'cpp/include/cuopt/linear_programming/**'
- 'cpp/inlcude/cuopt/utilities/**'

- 'python/cuopt/cuopt/routing/**'
- 'python/cuopt/cuopt/tests/routing/**'
- 'regression/routing*'
- 'cpp/include/**'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 'cpp/include/**'
- 'cpp/include/cuopt/error.hpp'
- 'cpp/include/cuopt/routing/**'
- 'cpp/inlcude/cuopt/utilities/**'

@rgsl888prabhu
Copy link
Collaborator

@bala-bhargav Please let me know if you have any questions on the reviews.

@rgsl888prabhu rgsl888prabhu changed the base branch from main to release/26.04 March 19, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants