Skip to content

feat(ci): coderabbit E2E recommendations + selective nightly dispatch - #2615

Merged
jyaunches merged 4 commits into
mainfrom
issue-2564-coderabbit-e2e-recommendations-selective-dispatch
Apr 28, 2026
Merged

feat(ci): coderabbit E2E recommendations + selective nightly dispatch#2615
jyaunches merged 4 commits into
mainfrom
issue-2564-coderabbit-e2e-recommendations-selective-dispatch

Conversation

@jyaunches

@jyaunches jyaunches commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Add automated E2E test recommendations to PR reviews and selective job dispatch to the nightly E2E workflow.

Closes #2564 (Phases 1–3).

What changed

1. CodeRabbit path_instructions for E2E recommendations (.coderabbit.yaml)

15 new path_instructions entries map sensitive file paths to the nightly E2E jobs that exercise them. When a PR touches a mapped path, CodeRabbit posts a review comment recommending specific jobs and a copy-pasteable gh workflow run command.

Path Pattern Recommended Jobs
scripts/nemoclaw-start.sh, scripts/lib/sandbox-init.sh sandbox-survival-e2e, sandbox-operations-e2e, cloud-e2e
Dockerfile, Dockerfile.base cloud-e2e, sandbox-survival-e2e, hermes-e2e, rebuild-openclaw-e2e
nemoclaw-blueprint/scripts/http-proxy-fix.js cloud-e2e, inference-routing-e2e
src/lib/onboard.ts cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e
src/nemoclaw.ts sandbox-survival-e2e, sandbox-operations-e2e, skip-permissions-e2e
src/lib/cluster-image-patch.ts, src/lib/preflight.ts overlayfs-autofix-e2e
src/lib/deploy.ts deployment-services-e2e
src/lib/sandbox-state.ts snapshot-commands-e2e, rebuild-openclaw-e2e
src/lib/shields*.ts shields-config-e2e
agents/hermes/** hermes-e2e, rebuild-hermes-e2e
nemoclaw-blueprint/policies/** network-policy-e2e, skip-permissions-e2e
.github/workflows/nightly-e2e.yaml Reminds to add CodeRabbit coverage for new jobs

2. Selective job dispatch (nightly-e2e.yaml)

Added a jobs input to workflow_dispatch so maintainers can run a subset of nightly jobs on any branch:

gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=sandbox-survival-e2e,sandbox-operations-e2e
  • All 18 E2E jobs get a conditional guard: unselected jobs are skipped
  • Empty jobs input (or scheduled runs) still runs everything
  • notify-on-failure is unaffected: skipped jobs produce result: 'skipped', not 'failure'

3. Cross-validation test (test/validate-e2e-coverage.test.ts)

Keeps the mapping up to date as files and jobs evolve:

Assertion What it catches
Job names in CodeRabbit match nightly-e2e.yaml Renamed/removed jobs
Path globs match at least one file on disk Renamed/deleted source files
Every nightly job has selective dispatch guard New jobs added without the if: pattern
Advisory: nightly jobs with no CodeRabbit coverage New jobs added without path_instructions

Validation

  • All 4 cross-validation tests pass locally
  • Existing validate-config-schemas tests still pass
  • Selective dispatch validated: run 25052625486 — triggered with -f jobs=diagnostics-e2e, 17/18 jobs correctly skipped
  • notify-on-failure does not false-alarm on selective run — run 25052625486 confirmed: notify-on-failure was skipped (not triggered)
  • CodeRabbit posts recommendations on a PR touching a mapped file (post-merge validation)

Context

Summary by CodeRabbit

  • Chores

    • Expanded review automation to map sensitive paths to targeted nightly E2E jobs and inject instructions for running relevant subsets.
    • Added manual workflow dispatch allowing selective E2E job execution via a jobs input.
  • New Features

    • Added a reporting step that, on manual runs, posts a PR comment summarizing passed/failed/skipped E2E jobs.
  • Tests

    • Added a validation suite that cross-checks review-to-workflow mappings and dispatch guards, warning on uncovered jobs.

4. Substring match fix (nightly-e2e.yaml)

CodeRabbit review correctly identified that contains(inputs.jobs, 'cloud-e2e') performs substring matching — e.g., passing jobs=e2e would match every job. All 18 job guards now use delimiter-wrapping:

contains(format(',{0},', inputs.jobs), ',<job-name>,')

This ensures exact token matching within the comma-separated input. The cross-validation test was updated to enforce the new pattern.

…#2564)

Add path_instructions to .coderabbit.yaml that map sensitive file changes
to recommended nightly E2E jobs. CodeRabbit surfaces these as review
comments on PRs touching entrypoint scripts, Dockerfile, proxy rewrite,
onboard logic, deploy, shields, Hermes, and network policies.

Add a `jobs` input to the nightly-e2e.yaml workflow_dispatch trigger so
maintainers can run a subset of nightly jobs on any branch:

  gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=sandbox-survival-e2e,sandbox-operations-e2e

Each of the 18 E2E jobs gets a conditional that checks the input, so
unselected jobs are skipped. Scheduled runs and empty `jobs` input
still run everything. The notify-on-failure job is unaffected (skipped
jobs produce result 'skipped', not 'failure').

Add test/validate-e2e-coverage.test.ts to cross-validate:
- Every job name in CodeRabbit instructions exists in nightly-e2e.yaml
- Every path glob in CodeRabbit instructions matches at least one file
- Every nightly job has the selective dispatch guard in its if: condition
- Advisory warning for nightly jobs with no CodeRabbit coverage

Closes #2564 (Phases 1-3)
@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds CodeRabbit path-to-job review instructions, a workflow_dispatch jobs input for selective nightly E2E runs, and a Vitest cross-validation test that verifies alignment between CodeRabbit recommendations and the nightly E2E workflow definitions.

Changes

Cohort / File(s) Summary
CodeRabbit path instructions
\.coderabbit\.yaml
Added reviews.path_instructions entries mapping sensitive file globs to nightly *-e2e job names; reuses shared instruction anchors and embeds gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=... command templates.
Selective workflow dispatch
.github/workflows/nightly-e2e.yaml
Added workflow_dispatch.inputs.jobs (comma-separated) and updated each E2E job if: to preserve scheduled behavior while enabling manual runs only when inputs.jobs is empty or contains the job (GPU gating preserved). Added report-to-pr job to aggregate results and post a PR comment for manual dispatches.
E2E coverage validation tests
test/validate-e2e-coverage.test.ts
New Vitest suite that loads .coderabbit.yaml and nightly-e2e.yaml, extracts referenced *-e2e job names and path globs, asserts referenced jobs exist in the workflow, ensures each referenced path glob matches at least one repo path (simple glob rules), warns for nightly jobs with no mapped paths, and verifies each job's if: includes the inputs.jobs selective-dispatch guard.

Sequence Diagram(s)

sequenceDiagram
    participant PR as "Contributor (PR)"
    participant CodeRabbit as "CodeRabbit"
    participant Maintainer as "Maintainer"
    participant GH as "GitHub Actions"
    participant Jobs as "Nightly E2E jobs"

    PR->>CodeRabbit: Pushes changes touching mapped paths
    CodeRabbit-->>PR: Posts review with recommended `*-e2e` jobs and `gh workflow run ... -f jobs=...`
    Maintainer->>GH: Runs `gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=jobA,jobB`
    GH->>GH: Evaluate workflow_dispatch.inputs.jobs and per-job `if:` guards
    GH-->>Jobs: Execute only matching E2E jobs (or all if inputs.jobs empty)
    Jobs-->>GH: Return results
    GH-->>Maintainer: report-to-pr posts summary comment on PR (for workflow_dispatch)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I mapped the paths with whiskers bright,

Suggested tests to run through day and night.
Pick just the jobs with a tap and a hop,
Results bounce back — the checks never stop.
I nibble a carrot and stamp the PR "pop!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed All PR changes align with and fulfill the objectives from issue #2564 (Phases 1–3): path_instructions mapping, selective dispatch with conditional guards, and cross-validation tests.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: CodeRabbit path mappings, nightly-e2e selective dispatch, and E2E coverage validation tests. The added report-to-pr job is a supporting enhancement for workflow_dispatch execution results.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly and specifically describes the main changes: adding CodeRabbit E2E recommendations and enabling selective dispatch for nightly E2E workflows, which directly aligns with the core objectives of the PR.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-2564-coderabbit-e2e-recommendations-selective-dispatch

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 @.github/workflows/nightly-e2e.yaml:
- Around line 62-66: Update each E2E job guard to prevent substring matches by
wrapping inputs.jobs with delimiters and checking for the delimited job token;
replace occurrences like contains(inputs.jobs, 'cloud-e2e') with
contains(concat(',', inputs.jobs, ','), ',cloud-e2e,') for all listed jobs
(cloud-e2e, messaging-providers-e2e, token-rotation-e2e, sandbox-survival-e2e,
hermes-e2e, skip-permissions-e2e, sandbox-operations-e2e, inference-routing-e2e,
network-policy-e2e, deployment-services-e2e, diagnostics-e2e,
snapshot-commands-e2e, shields-config-e2e, rebuild-openclaw-e2e,
upgrade-stale-sandbox-e2e, rebuild-hermes-e2e, overlayfs-autofix-e2e, gpu-e2e)
so each if condition uses contains(concat(',', inputs.jobs, ','),
',<job-name>,') instead of the plain contains(...) check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7e3e56bd-8997-480b-9601-fcea3fecb78e

📥 Commits

Reviewing files that changed from the base of the PR and between 0b49851 and e7ac285.

📒 Files selected for processing (3)
  • .coderabbit.yaml
  • .github/workflows/nightly-e2e.yaml
  • test/validate-e2e-coverage.test.ts

Comment thread .github/workflows/nightly-e2e.yaml Outdated
…positives

CodeRabbit correctly identified that contains(inputs.jobs, 'cloud-e2e')
performs substring matching, so passing 'e2e' would match every job.

Replace all 18 job guards with:
  contains(format(',{0},', inputs.jobs), ',<job-name>,')

This wraps the comma-separated input in delimiters so each job name
must match exactly between commas.

Update the cross-validation test to check for the new pattern.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
test/validate-e2e-coverage.test.ts (1)

74-75: Consider widening job-name regex to include digits.

Line 74-75 currently only matches lowercase letters/hyphens. If a future job name includes digits (for example foo2-e2e), it will be silently missed by the cross-validation.

Optional hardening
-  const backtickPattern = /`([a-z][-a-z]*-e2e)`/g;
-  const jobsArgPattern = /-f jobs=([a-z][-a-z,]*-e2e)/g;
+  const backtickPattern = /`([a-z][a-z0-9-]*-e2e)`/g;
+  const jobsArgPattern = /-f jobs=([a-z][a-z0-9,-]*-e2e)/g;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/validate-e2e-coverage.test.ts` around lines 74 - 75, The current regexes
backtickPattern and jobsArgPattern only allow lowercase letters and hyphens, so
job names with digits (e.g., foo2-e2e) are missed; update both patterns to
include digits in the character classes (e.g., change /`([a-z][-a-z]*-e2e)`/g to
/`([a-z0-9][-a-z0-9]*-e2e)`/g and /-f jobs=([a-z][-a-z,]*-e2e)/g to /-f
jobs=([a-z0-9][-a-z0-9,]*-e2e)/g) so digits are accepted anywhere after the
first character.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/validate-e2e-coverage.test.ts`:
- Around line 214-217: The current validation for selective-dispatch guards only
checks that the condition string contains "inputs.jobs" and the
contains(format(...), ',${name},') fragment (variables `condition` and `name`),
which allows conditions that omit the required checks for dispatch vs
scheduled/default behavior; update the test in validate-e2e-coverage.test.ts so
the assertion also requires the condition to include the guard
"github.event_name != 'workflow_dispatch'" and the default/scheduled branch
check "inputs.jobs == ''" (or equivalent exact substrings used in your
workflows), so the test enforces presence of all four pieces: "inputs.jobs", the
contains(...) fragment, "github.event_name != 'workflow_dispatch'", and
"inputs.jobs == ''".

---

Nitpick comments:
In `@test/validate-e2e-coverage.test.ts`:
- Around line 74-75: The current regexes backtickPattern and jobsArgPattern only
allow lowercase letters and hyphens, so job names with digits (e.g., foo2-e2e)
are missed; update both patterns to include digits in the character classes
(e.g., change /`([a-z][-a-z]*-e2e)`/g to /`([a-z0-9][-a-z0-9]*-e2e)`/g and /-f
jobs=([a-z][-a-z,]*-e2e)/g to /-f jobs=([a-z0-9][-a-z0-9,]*-e2e)/g) so digits
are accepted anywhere after the first character.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d8106263-8c48-421b-b036-99d0e7d79028

📥 Commits

Reviewing files that changed from the base of the PR and between e7ac285 and faa04c6.

📒 Files selected for processing (2)
  • .github/workflows/nightly-e2e.yaml
  • test/validate-e2e-coverage.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/nightly-e2e.yaml

Comment thread test/validate-e2e-coverage.test.ts Outdated
Comment on lines +214 to +217
if (
!condition.includes("inputs.jobs") ||
!condition.includes(`contains(format(',{0},', inputs.jobs), ',${name},')`)
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Selective-dispatch guard validation is incomplete.

On Line 214-217, the check only requires inputs.jobs + contains(...). A job condition could still pass this test while breaking scheduled/default behavior if it omits github.event_name != 'workflow_dispatch' or inputs.jobs == ''.

Proposed tightening
-      if (
-        !condition.includes("inputs.jobs") ||
-        !condition.includes(`contains(format(',{0},', inputs.jobs), ',${name},')`)
-      ) {
+      const hasDispatchBypass = condition.includes(
+        "github.event_name != 'workflow_dispatch'",
+      );
+      const hasEmptySelectionBypass = condition.includes("inputs.jobs == ''");
+      const hasExactJobMatch = condition.includes(
+        `contains(format(',{0},', inputs.jobs), ',${name},')`,
+      );
+      if (!(hasDispatchBypass && hasEmptySelectionBypass && hasExactJobMatch)) {
         missing.push(name);
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (
!condition.includes("inputs.jobs") ||
!condition.includes(`contains(format(',{0},', inputs.jobs), ',${name},')`)
) {
const hasDispatchBypass = condition.includes(
"github.event_name != 'workflow_dispatch'",
);
const hasEmptySelectionBypass = condition.includes("inputs.jobs == ''");
const hasExactJobMatch = condition.includes(
`contains(format(',{0},', inputs.jobs), ',${name},')`,
);
if (!(hasDispatchBypass && hasEmptySelectionBypass && hasExactJobMatch)) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/validate-e2e-coverage.test.ts` around lines 214 - 217, The current
validation for selective-dispatch guards only checks that the condition string
contains "inputs.jobs" and the contains(format(...), ',${name},') fragment
(variables `condition` and `name`), which allows conditions that omit the
required checks for dispatch vs scheduled/default behavior; update the test in
validate-e2e-coverage.test.ts so the assertion also requires the condition to
include the guard "github.event_name != 'workflow_dispatch'" and the
default/scheduled branch check "inputs.jobs == ''" (or equivalent exact
substrings used in your workflows), so the test enforces presence of all four
pieces: "inputs.jobs", the contains(...) fragment, "github.event_name !=
'workflow_dispatch'", and "inputs.jobs == ''".

Add report-to-pr job to nightly-e2e.yaml. When the workflow is
triggered via workflow_dispatch on a branch with an open PR, the
job posts a comment with:

- Which jobs were requested
- A results table (pass/fail/skipped for every job)
- Direct link to the Actions run
- Failed job callout with artifacts link

Only runs on workflow_dispatch (not nightly schedule). Silently
skips if no open PR exists for the branch.

Exclude report-to-pr from the cross-validation test's E2E job list
(same as notify-on-failure — infrastructure, not a test job).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
test/validate-e2e-coverage.test.ts (1)

216-219: ⚠️ Potential issue | 🟠 Major

Selective-dispatch guard validation is still incomplete.

This check can pass even if a job drops required dispatch/default guard clauses. Require all key fragments, not just inputs.jobs + exact-token contains(...).

Suggested fix
-      if (
-        !condition.includes("inputs.jobs") ||
-        !condition.includes(`contains(format(',{0},', inputs.jobs), ',${name},')`)
-      ) {
+      const hasDispatchBypass = condition.includes(
+        "github.event_name != 'workflow_dispatch'",
+      );
+      const hasEmptySelectionBypass = condition.includes("inputs.jobs == ''");
+      const hasInputsRef = condition.includes("inputs.jobs");
+      const hasExactJobMatch = condition.includes(
+        `contains(format(',{0},', inputs.jobs), ',${name},')`,
+      );
+      if (
+        !(
+          hasDispatchBypass &&
+          hasEmptySelectionBypass &&
+          hasInputsRef &&
+          hasExactJobMatch
+        )
+      ) {
         missing.push(name);
       }

As per coding guidelines: for selective nightly dispatch, each E2E job guard must preserve scheduled/empty-input behavior and exact-token matching.

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

In `@test/validate-e2e-coverage.test.ts` around lines 216 - 219, The current guard
check on the condition string only ensures presence of "inputs.jobs" and the
contains(...) token, which can miss other required fragments; update the
validation in validate-e2e-coverage.test.ts to assert that the condition string
contains all required guard fragments (e.g., "github.event_name == 'schedule'"
or equivalent scheduled check, the exact-token contains(format(',{0},',
inputs.jobs), ',${name},') match, and the empty-input/default-dispatch clause
that preserves scheduled/empty-input behavior) rather than just two fragments.
Locate the variable/logic using condition (the if that checks
condition.includes(...)) and add explicit assertions for each fragment/token
required for selective-dispatch guards so any job that drops required clauses
will fail the test.
🧹 Nitpick comments (1)
test/validate-e2e-coverage.test.ts (1)

186-200: Make uncovered nightly-job coverage an enforceable assertion (not warning-only).

This currently always passes, so new nightly jobs can drift without required .coderabbit.yaml mapping. Consider asserting on uncovered jobs (with an explicit allowlist for intentional exceptions).

Suggested tightening
-    const uncovered = nightlyJobs.filter((name) => !referencedJobs.has(name));
-    // This is a warning-level check: some jobs (e.g., diagnostics-e2e,
-    // upgrade-stale-sandbox-e2e) may intentionally lack path-based
-    // recommendations. We still flag them so maintainers can decide.
-    if (uncovered.length > 0) {
-      console.warn(
-        `⚠️  Nightly E2E jobs with no CodeRabbit path_instructions coverage: ` +
-          `${uncovered.join(", ")}. ` +
-          `Consider adding path_instructions entries in .coderabbit.yaml ` +
-          `for the source files these jobs exercise.`,
-      );
-    }
-    // Intentionally does not fail — this is advisory.
-    expect(true).toBe(true);
+    const allowedUncovered = new Set<string>([
+      "diagnostics-e2e",
+      "upgrade-stale-sandbox-e2e",
+    ]);
+    const uncovered = nightlyJobs.filter(
+      (name) => !referencedJobs.has(name) && !allowedUncovered.has(name),
+    );
+    expect(
+      uncovered,
+      `Nightly E2E jobs missing CodeRabbit path_instructions coverage: ` +
+        `${uncovered.join(", ")}.`,
+    ).toEqual([]);

As per coding guidelines: “If a new E2E job is added, verify a corresponding path_instructions entry exists in .coderabbit.yaml … The cross-validation test … checks this automatically.”

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

In `@test/validate-e2e-coverage.test.ts` around lines 186 - 200, The test
currently treats uncovered nightlyJobs as a warning; change it to fail unless
jobs are explicitly allowlisted: compute uncovered = nightlyJobs.filter(name =>
!referencedJobs.has(name) && !allowedMissing.has(name)) (introduce an
allowlist/Set like allowedMissing for intentional exceptions), then replace the
no-op expect with an assertion such as expect(uncovered).toHaveLength(0) or
expect(uncovered).toEqual([]) and include a clear failure message listing
uncovered so CI enforces adding path_instructions entries for new nightly jobs;
update the test block titled "every nightly E2E job has at least one CodeRabbit
path_instructions entry" accordingly.
🤖 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/nightly-e2e.yaml:
- Line 785: The workflow currently injects inputs.jobs directly into a JS string
(const requestedJobs = '${{ inputs.jobs }}'), which can break if the input
contains quotes; change this to use JSON-safe interpolation so the runtime
receives a valid JS literal—replace the assignment with: const requestedJobs =
${{ toJson(inputs.jobs) }}; (update the github-script step that defines
requestedJobs) so inputs.jobs is safely serialized into JavaScript.

---

Duplicate comments:
In `@test/validate-e2e-coverage.test.ts`:
- Around line 216-219: The current guard check on the condition string only
ensures presence of "inputs.jobs" and the contains(...) token, which can miss
other required fragments; update the validation in validate-e2e-coverage.test.ts
to assert that the condition string contains all required guard fragments (e.g.,
"github.event_name == 'schedule'" or equivalent scheduled check, the exact-token
contains(format(',{0},', inputs.jobs), ',${name},') match, and the
empty-input/default-dispatch clause that preserves scheduled/empty-input
behavior) rather than just two fragments. Locate the variable/logic using
condition (the if that checks condition.includes(...)) and add explicit
assertions for each fragment/token required for selective-dispatch guards so any
job that drops required clauses will fail the test.

---

Nitpick comments:
In `@test/validate-e2e-coverage.test.ts`:
- Around line 186-200: The test currently treats uncovered nightlyJobs as a
warning; change it to fail unless jobs are explicitly allowlisted: compute
uncovered = nightlyJobs.filter(name => !referencedJobs.has(name) &&
!allowedMissing.has(name)) (introduce an allowlist/Set like allowedMissing for
intentional exceptions), then replace the no-op expect with an assertion such as
expect(uncovered).toHaveLength(0) or expect(uncovered).toEqual([]) and include a
clear failure message listing uncovered so CI enforces adding path_instructions
entries for new nightly jobs; update the test block titled "every nightly E2E
job has at least one CodeRabbit path_instructions entry" accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8cb2a1a6-1d32-49ab-b530-bcc164f23f71

📥 Commits

Reviewing files that changed from the base of the PR and between faa04c6 and 89313c6.

📒 Files selected for processing (2)
  • .github/workflows/nightly-e2e.yaml
  • test/validate-e2e-coverage.test.ts

Comment thread .github/workflows/nightly-e2e.yaml Outdated
const needs = ${{ toJSON(needs) }};
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const branch = context.ref.replace('refs/heads/', '');
const requestedJobs = '${{ inputs.jobs }}';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use JSON-safe interpolation for inputs.jobs in github-script.

Line 785 injects the workflow input directly into a single-quoted JS string. A quote in input can break the script and skip PR reporting.

Suggested fix
-            const requestedJobs = '${{ inputs.jobs }}';
+            const requestedJobs = ${{ toJSON(inputs.jobs) }} || "";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/nightly-e2e.yaml at line 785, The workflow currently
injects inputs.jobs directly into a JS string (const requestedJobs = '${{
inputs.jobs }}'), which can break if the input contains quotes; change this to
use JSON-safe interpolation so the runtime receives a valid JS literal—replace
the assignment with: const requestedJobs = ${{ toJson(inputs.jobs) }}; (update
the github-script step that defines requestedJobs) so inputs.jobs is safely
serialized into JavaScript.

@jyaunches jyaunches changed the title feat(ci): CodeRabbit E2E recommendations + selective nightly dispatch feat(ci): coderabbit E2E recommendations + selective nightly dispatch Apr 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 25058486980
Branch: issue-2564-coderabbit-e2e-recommendations-selective-dispatch
Requested jobs: diagnostics-e2e
Summary: 1 passed, 0 failed, 17 skipped

Job Result
cloud-e2e ⏭️ skipped
deployment-services-e2e ⏭️ skipped
diagnostics-e2e ✅ success
gpu-e2e ⏭️ skipped
hermes-e2e ⏭️ skipped
inference-routing-e2e ⏭️ skipped
messaging-providers-e2e ⏭️ skipped
network-policy-e2e ⏭️ skipped
overlayfs-autofix-e2e ⏭️ skipped
rebuild-hermes-e2e ⏭️ skipped
rebuild-openclaw-e2e ⏭️ skipped
sandbox-operations-e2e ⏭️ skipped
sandbox-survival-e2e ⏭️ skipped
shields-config-e2e ⏭️ skipped
skip-permissions-e2e ⏭️ skipped
snapshot-commands-e2e ⏭️ skipped
token-rotation-e2e ⏭️ skipped
upgrade-stale-sandbox-e2e ⏭️ skipped

@wscurran wscurran added enhancement New capability or improvement request CI/CD github_actions Pull requests that update GitHub Actions code labels Apr 28, 2026
…eRabbit review

- Resolve merge conflict: keep main's runner/timeout for gpu-e2e, retain
  selective dispatch guard
- Add selective dispatch guard to new gpu-double-onboard-e2e job from main
- Tighten guard validation test to check all three clauses
- Use toJSON(inputs.jobs) for safe JS interpolation in report-to-pr
@jyaunches
jyaunches merged commit 979b0bd into main Apr 28, 2026
15 checks passed
ericksoa added a commit that referenced this pull request Apr 28, 2026
Brings in the selective nightly-e2e dispatch infrastructure from #2615
(adds workflow_dispatch.inputs.jobs filter + per-job guard) and the
test/validate-e2e-coverage.test.ts cross-check that asserts every
nightly job carries the canonical guard.

Updates the issue-2478-crash-loop-recovery-e2e job to use the same
guard pattern as every other job, and adds it to the inputs.jobs
description "Valid:" list.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
…NVIDIA#2615)

## Summary

Add automated E2E test recommendations to PR reviews and selective job
dispatch to the nightly E2E workflow.

Closes NVIDIA#2564 (Phases 1–3).

## What changed

### 1. CodeRabbit `path_instructions` for E2E recommendations
(`.coderabbit.yaml`)

15 new `path_instructions` entries map sensitive file paths to the
nightly E2E jobs that exercise them. When a PR touches a mapped path,
CodeRabbit posts a review comment recommending specific jobs and a
copy-pasteable `gh workflow run` command.

| Path Pattern | Recommended Jobs |
|-------------|-----------------|
| `scripts/nemoclaw-start.sh`, `scripts/lib/sandbox-init.sh` |
`sandbox-survival-e2e`, `sandbox-operations-e2e`, `cloud-e2e` |
| `Dockerfile`, `Dockerfile.base` | `cloud-e2e`, `sandbox-survival-e2e`,
`hermes-e2e`, `rebuild-openclaw-e2e` |
| `nemoclaw-blueprint/scripts/http-proxy-fix.js` | `cloud-e2e`,
`inference-routing-e2e` |
| `src/lib/onboard.ts` | `cloud-e2e`, `sandbox-operations-e2e`,
`rebuild-openclaw-e2e` |
| `src/nemoclaw.ts` | `sandbox-survival-e2e`, `sandbox-operations-e2e`,
`skip-permissions-e2e` |
| `src/lib/cluster-image-patch.ts`, `src/lib/preflight.ts` |
`overlayfs-autofix-e2e` |
| `src/lib/deploy.ts` | `deployment-services-e2e` |
| `src/lib/sandbox-state.ts` | `snapshot-commands-e2e`,
`rebuild-openclaw-e2e` |
| `src/lib/shields*.ts` | `shields-config-e2e` |
| `agents/hermes/**` | `hermes-e2e`, `rebuild-hermes-e2e` |
| `nemoclaw-blueprint/policies/**` | `network-policy-e2e`,
`skip-permissions-e2e` |
| `.github/workflows/nightly-e2e.yaml` | Reminds to add CodeRabbit
coverage for new jobs |

### 2. Selective job dispatch (`nightly-e2e.yaml`)

Added a `jobs` input to `workflow_dispatch` so maintainers can run a
subset of nightly jobs on any branch:

```
gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=sandbox-survival-e2e,sandbox-operations-e2e
```

- All 18 E2E jobs get a conditional guard: unselected jobs are skipped
- Empty `jobs` input (or scheduled runs) still runs everything
- `notify-on-failure` is unaffected: skipped jobs produce `result:
'skipped'`, not `'failure'`

### 3. Cross-validation test (`test/validate-e2e-coverage.test.ts`)

Keeps the mapping up to date as files and jobs evolve:

| Assertion | What it catches |
|-----------|----------------|
| Job names in CodeRabbit match `nightly-e2e.yaml` | Renamed/removed
jobs |
| Path globs match at least one file on disk | Renamed/deleted source
files |
| Every nightly job has selective dispatch guard | New jobs added
without the `if:` pattern |
| Advisory: nightly jobs with no CodeRabbit coverage | New jobs added
without `path_instructions` |

## Validation

- [x] All 4 cross-validation tests pass locally
- [x] Existing `validate-config-schemas` tests still pass
- [x] Selective dispatch validated: [run
25052625486](https://github.com/NVIDIA/NemoClaw/actions/runs/25052625486)
— triggered with `-f jobs=diagnostics-e2e`, 17/18 jobs correctly skipped
- [x] `notify-on-failure` does not false-alarm on selective run — [run
25052625486](https://github.com/NVIDIA/NemoClaw/actions/runs/25052625486)
confirmed: `notify-on-failure` was skipped (not triggered)
- [ ] CodeRabbit posts recommendations on a PR touching a mapped file
(post-merge validation)

## Context

- Issue: NVIDIA#2564
- Weekend incident: NVIDIA#2471, NVIDIA#2472, NVIDIA#2482, NVIDIA#2490
- E2E strategy: `cloud-experimental-e2e` removal in NVIDIA#2472 left a
coverage gap that would have been flagged by these recommendations


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Expanded review automation to map sensitive paths to targeted nightly
E2E jobs and inject instructions for running relevant subsets.
* Added manual workflow dispatch allowing selective E2E job execution
via a jobs input.

* **New Features**
* Added a reporting step that, on manual runs, posts a PR comment
summarizing passed/failed/skipped E2E jobs.

* **Tests**
* Added a validation suite that cross-checks review-to-workflow mappings
and dispatch guards, warning on uncovered jobs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

### 4. Substring match fix (`nightly-e2e.yaml`)

CodeRabbit review correctly identified that `contains(inputs.jobs,
'cloud-e2e')` performs substring matching — e.g., passing `jobs=e2e`
would match every job. All 18 job guards now use delimiter-wrapping:

```yaml
contains(format(',{0},', inputs.jobs), ',<job-name>,')
```

This ensures exact token matching within the comma-separated input. The
cross-validation test was updated to enforce the new pattern.
@jyaunches jyaunches mentioned this pull request May 8, 2026
7 tasks
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure chore Build, CI, dependency, or tooling maintenance feature PR adds or expands user-visible functionality and removed CI/CD enhancement New capability or improvement request github_actions Pull requests that update GitHub Actions code chore Build, CI, dependency, or tooling maintenance labels Jun 3, 2026
@jyaunches
jyaunches deleted the issue-2564-coderabbit-e2e-recommendations-selective-dispatch branch June 12, 2026 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure feature PR adds or expands user-visible functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ci): CodeRabbit E2E test recommendations + selective nightly dispatch for PRs

3 participants