test(e2e): migrate test-token-rotation.sh to vitest [ANCHOR-4]#5236
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a live token-rotation Vitest E2E test and integrates it as a new free-standing workflow job, updates matrix/job selector validation and report-to-pr wiring, and implements comprehensive workflow-boundary validation plus synthetic tests for the new job. ChangesToken Rotation E2E Test Suite
Sequence Diagram(s)sequenceDiagram
participant MatrixStep
participant TokenRotationJob
participant DockerHub
participant NodeSetup
participant VitestRunner
participant ArtifactStore
MatrixStep->>TokenRotationJob: conditionally include when JOBS includes token-rotation-vitest
TokenRotationJob->>DockerHub: docker login (retries, fallback to anonymous)
TokenRotationJob->>NodeSetup: set up node (pinned)
TokenRotationJob->>VitestRunner: npm ci, build CLI, run token-rotation test (with bot token envs, GITHUB_TOKEN from github.token)
VitestRunner->>ArtifactStore: upload e2e-artifacts/vitest/token-rotation/ artifacts (pinned action, include-hidden-files:false)
TokenRotationJob->>MatrixStep: exit status returned to report-to-pr via needs
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27352436291
|
E2E Advisor RecommendationRequired E2E: None Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
Vitest E2E Scenario RecommendationRequired Vitest E2E scenarios: Dispatch required Vitest E2E scenarios:
Full Vitest E2E advisor summaryVitest E2E Scenario AdvisorBase: Required Vitest E2E scenarios
Optional Vitest E2E scenarios
Relevant changed files
|
PR Review AdvisorFindings: 0 needs attention, 8 worth checking, 0 nice ideas Review findings🛠️ Needs attention
🔎 Worth checking
🌱 Nice ideas
Consider writing more tests for
Since last review detailsCurrent findings:
This is an automated advisory review. A human maintainer must make the final merge decision. |
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27355058524
|
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27355314900
|
|
Maintainer simplicity/equivalence review for #5098 — request changes. This can stay as the token-rotation anchor PR, but please close the contract gaps called out by the advisor. Required:
Goal: keep this as a focused token-rotation migration, but preserve the legacy runtime-state contract and deterministic cleanup. |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/e2e-scenario/live/token-rotation.test.ts`:
- Around line 28-29: PHASE_TIMEOUT_MS (currently 7 * ONBOARD_TIMEOUT_MS) exceeds
the CI workflow job limit and is never reached; change PHASE_TIMEOUT_MS to be
safely under the job timeout (e.g., set PHASE_TIMEOUT_MS to 40 * 60_000 or
compute from a JOB_WORKFLOW_TIMEOUT_MS = 45 * 60_000 and subtract a small
margin) so the test-level timeout can fire; update the constant definition that
references ONBOARD_TIMEOUT_MS/PHASE_TIMEOUT_MS accordingly.
- Around line 393-427: After the initial runInstall(...) and the
provider/credential checks, add the legacy "sandbox-running" assertion using the
same availability probe mechanism as the other commands: invoke
host.command("openshell", ["<sandbox-running-check>"], { env:
buildAvailabilityProbeEnv(), timeoutMs: ... }) (or the existing test helper used
elsewhere) for SANDBOX_NAME and assert exitCode === 0; do the same after each
credential-triggered rebuild/rotation (i.e., immediately after
expectCredentialHash(...) calls) to restore the legacy contract. Ensure you
reuse buildAvailabilityProbeEnv(), the host.command pattern, and SANDBOX_NAME so
the new assertions follow the same artifact/timeouts as the surrounding checks.
- Around line 428-504: The test is missing post-rotation "sandbox running"
assertions after each credential-triggered rebuild (Telegram, Discord, Slack).
After each rotation block that calls runOnboard/resultText and
expectRotationOutput, add a call to the existing sandbox-running assertion
helper (e.g., assertSandboxRunning or checkSandboxRunning) using the appropriate
artifact name built from SANDBOX_NAME (e.g., `${SANDBOX_NAME}-telegram-bridge`,
`${SANDBOX_NAME}-discord-bridge`, `${SANDBOX_NAME}-slack-bridge` and
`${SANDBOX_NAME}-slack-app`) so each phase verifies the rebuilt sandbox is
actually operational; place these assertions immediately after the corresponding
expectRotationOutput calls (refer to runOnboard, resultText,
expectRotationOutput and SANDBOX_NAME to locate the spots).
- Around line 373-391: The pre- and post-test cleanup in the token-rotation E2E
uses deleteSandboxIfOpenshellExists and host.command to destroy the sandbox but
never destroys the canonical OpenShell gateway ("nemoclaw"); update the cleanup
logic around buildAvailabilityProbeEnv / cleanup.add and the pre-clean
host.command block to run the equivalent openshell gateway destroy -g nemoclaw
(and ensure the same gateway destroy is added to the post-test cleanup in the
cleanup.add callback) so that both pre-clean and post-clean execute the gateway
removal in addition to the existing sandbox deletion (use the same
artifactName/timeout patterns and env like the existing host.command calls
referencing CLI_ENTRYPOINT and SANDBOX_NAME).
In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 255-367: The new validateTokenRotationVitestJob lacks checks that
the selective-dispatch machinery will actually allow this job: update
validateTokenRotationVitestJob to also assert that the repository's
validate-jobs allowlist (the code that validates workflow_dispatch.jobs)
includes "token-rotation-vitest" and that the generate-matrix logic still
accepts/regex-validates JOBS containing "token-rotation-vitest" (i.e. the same
pattern used to gate matrix/job names); locate and call the existing functions
that validate workflow_dispatch job allowlists and JOBS regex (or reuse their
symbol names) from within validateTokenRotationVitestJob to ensure coverage, and
add a mirrored assertion in
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts so the unit test
suite fails if validate-jobs or generate-matrix stop permitting
token-rotation-vitest.
- Around line 333-345: The loop over token names currently only checks typeof
and non-empty via stringValue(runVitestEnv[tokenName]) which still allows GitHub
expression strings like ${{ secrets.* }} or ${{ vars.* }}; update the guard in
the for loop (where runVitestEnv and tokenName are used and errors.push is
called) to also reject secret/vars expressions by checking the raw string for
patterns like /\$\{\{\s*(secrets|vars)\./ and/or disallow any substring
containing '${{' and require a literal fake token format (e.g. assert it matches
a known fake pattern or prefix) so that any value that is empty, contains a
${{...}} expression, or does not match the expected fake-token pattern triggers
errors.push(`token-rotation-vitest step must set ${tokenName}`).
🪄 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: 60e2489f-91ba-465d-a597-4efbfeae38dc
📒 Files selected for processing (4)
.github/workflows/e2e-vitest-scenarios.yamltest/e2e-scenario/live/token-rotation.test.tstest/e2e-scenario/support-tests/e2e-scenarios-workflow.test.tstools/e2e-scenarios/workflow-boundary.mts
…n-rotation-simple
…n-rotation-simple
…n-rotation-simple
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts (1)
310-336: ⚡ Quick winConsider verifying the string replacement succeeded.
The test replaces a specific error message string (lines 319-322) but doesn't verify that the replacement actually occurred. If the workflow format changes and the original string isn't found,
workflow.replace()returns the unchanged string, and the test might fail with confusing output or pass incorrectly.🛡️ Optional: Add replacement verification
const workflow = fs.readFileSync( path.join(process.cwd(), ".github/workflows/e2e-vitest-scenarios.yaml"), "utf8", ); - fs.writeFileSync( - workflowPath, - workflow.replace( + const searchString = 'echo "::error::Invalid jobs input; use comma-separated job ids" >&2\n exit 1\n fi\n matrix='; + const replacementString = 'echo "::error::Invalid jobs input: ${JOBS}" >&2\n exit 1\n fi\n matrix='; + const modifiedWorkflow = workflow.replace(searchString, replacementString); + + if (modifiedWorkflow === workflow) { + throw new Error(`Test fixture outdated: expected string not found in workflow:\n${searchString}`); + } + + fs.writeFileSync( + workflowPath, + modifiedWorkflow, - 'echo "::error::Invalid jobs input; use comma-separated job ids" >&2\n exit 1\n fi\n matrix=', - 'echo "::error::Invalid jobs input: ${JOBS}" >&2\n exit 1\n fi\n matrix=', - ), );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts` around lines 310 - 336, The test "rejects raw jobs selector echo from matrix generation" currently calls workflow.replace(...) and writes the result but never verifies the replacement succeeded; update the test to assert the replacement occurred before calling validateE2eVitestScenariosWorkflowBoundary by comparing the original workflow string (variable workflow) with the replaced string (use a new variable, e.g. replacedWorkflow) or by checking replacedWorkflow.includes('echo "::error::Invalid jobs input: ${JOBS}"') and fail the test (throw or expect) if the replacement didn't occur; ensure you then write replacedWorkflow to workflowPath and keep the call to validateE2eVitestScenariosWorkflowBoundary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts`:
- Around line 310-336: The test "rejects raw jobs selector echo from matrix
generation" currently calls workflow.replace(...) and writes the result but
never verifies the replacement succeeded; update the test to assert the
replacement occurred before calling validateE2eVitestScenariosWorkflowBoundary
by comparing the original workflow string (variable workflow) with the replaced
string (use a new variable, e.g. replacedWorkflow) or by checking
replacedWorkflow.includes('echo "::error::Invalid jobs input: ${JOBS}"') and
fail the test (throw or expect) if the replacement didn't occur; ensure you then
write replacedWorkflow to workflowPath and keep the call to
validateE2eVitestScenariosWorkflowBoundary.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 92b06b3f-d76c-4537-82d6-ed371cbe9164
📒 Files selected for processing (4)
.github/workflows/e2e-vitest-scenarios.yamltest/e2e-scenario/live/token-rotation.test.tstest/e2e-scenario/support-tests/e2e-scenarios-workflow.test.tstools/e2e-scenarios/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (3)
- .github/workflows/e2e-vitest-scenarios.yaml
- tools/e2e-scenarios/workflow-boundary.mts
- test/e2e-scenario/live/token-rotation.test.ts
…n-rotation-simple
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27365832382
|
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27367271257
|
…n-rotation-simple
…n-rotation-simple
…n-rotation-simple
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27370677905
|
1 similar comment
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 27370677905
|
cv
left a comment
There was a problem hiding this comment.
Approved. Normal PR checks are green, review feedback is addressed, unresolved threads are clear, and token-rotation-vitest passed. The remaining full scenario fan-out failures appear tied to unstable third-party NVIDIA inference endpoint validation rather than this PR.
Summary
Migrate
test/e2e/test-token-rotation.shwith focused live Vitest coverage.Related Issues
Refs #5098
Refs #1903
Contract mapping
test/e2e-scenario/live/token-rotation.test.ts(phase-0-install-token-a, provider-get assertions, registry hash assertions).bash install.sh --non-interactive, real Docker/OpenShell, real NemoClaw registry.TELEGRAM_BOT_TOKENdetects credential rotation, names onlytelegram-bridge, and rebuilds the sandbox.phase-2-rotate-telegramassertions on onboard output.node bin/nemoclaw.js onboard --non-interactiveagainst the existing sandbox.phase-3-same-after-telegram,phase-5-same-after-discord, andphase-7-same-after-slackreuse-output assertions.discord-bridge; rotating Slack bot/app namesslack-bridgeandslack-apponly.phase-4-rotate-discordandphase-6-rotate-slackassertions.Simplicity check
.github/workflows/nightly-e2e.yamljobtoken-rotation-e2e,runs-on: ubuntu-latest, Docker/OpenShell/install.sh,NVIDIA_API_KEYor fake OpenAI-compatible endpoint, fake Telegram/Discord/Slack token env, 45 minute timeout..github/workflows/e2e-vitest-scenarios.yamljobtoken-rotation-vitest,runs-on: ubuntu-latest, Docker Hub auth, hermetic fake OpenAI-compatible endpoint, fake Telegram/Discord/Slack token env, 45 minute timeout.gh workflow run e2e-vitest-scenarios.yaml --repo NVIDIA/NemoClaw --ref e2e-migrate/test-token-rotation-simple -f jobs=token-rotation-vitest -f pr_number=5236.Verification
npm run typecheck:cliNEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project e2e-scenarios-live test/e2e-scenario/live/token-rotation.test.ts --silent=false --reporter=default(local no-Docker skip evidence)npx vitest run test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts test/e2e-script-workflow.test.tsprek run gitleaks --files .github/workflows/e2e-vitest-scenarios.yaml test/e2e-scenario/live/token-rotation.test.ts test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts tools/e2e-scenarios/workflow-boundary.mtsgit diff --check39adb17bfe2477618db14dab1c12acdd8e60d1b6)Note: local full
test-clipre-push/pre-commit hook was skipped with--no-verifybecause it ran the entire CLI suite and previously failed on unrelated local environment issues (missingnemoclaw/node_modules/json5, Docker daemon unavailable, and unrelated timeouts). Targeted checks above passed; same-runner live validation is tracked throughtoken-rotation-viteston GitHub.Summary by CodeRabbit
Tests
Chores