-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(e2e): scenario-based setup matrix + Phase 1 migration infrastructure #3363
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
Merged
Merged
Changes from all commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
0fde46e
feat(e2e): introduce scenario-based setup matrix and runner
jyaunches e34826e
fix(e2e): make run-suites.sh summary loops safe under bash 3.2 (macOS)
jyaunches a52bcce
refactor(e2e): reorganize lib/ and suites/ by scenario concern; addre…
jyaunches a3215e7
docs(e2e): add MIGRATION.md tracking legacy-to-scenario mapping
jyaunches 7ee5675
test(e2e): add failing tests for Phase 1 infrastructure
jyaunches 711aaef
feat(e2e): Phase 1 \u2014 pre-flight infrastructure for migration
jyaunches 387767d
docs(e2e): expand MIGRATION.md with reuse-absorption table
jyaunches 77d1d38
docs(e2e): consolidate READMEs into one concise top-level guide
jyaunches dc6cb9e
docs(e2e): move top-level README.md and MIGRATION.md under docs/
jyaunches 6fbaed0
refactor(e2e): relocate runners, resolver, and cross-cutting lib to r…
jyaunches 0e02caa
refactor(e2e): move declarative YAML inputs to domain buckets
jyaunches 2b0c7d6
refactor(e2e): relocate install dispatch + helpers under nemoclaw_sce…
jyaunches d77dc1a
refactor(e2e): split onboard.sh into per-path files
jyaunches 674a96d
refactor(e2e): move fixtures under nemoclaw_scenarios/fixtures/
jyaunches 820daa7
refactor(e2e): consolidate assert helpers, sandbox-exec, and suites u…
jyaunches 4e8abe2
refactor(e2e): update external callers for restructured paths
jyaunches 853dcd6
refactor(e2e): point legacy test-*.sh scripts at relocated install-pa…
jyaunches 45c895d
docs(e2e): restore 'how to add' heading for metadata-hygiene test
jyaunches cdf6018
chore(e2e): add parity-map placeholders for 3 legacy scripts that lan…
jyaunches 19dff69
chore(e2e): isolate scenario framework tests
jyaunches 1cc4b82
test: sanitize scenario helper environments
jyaunches cf99b16
test: avoid shell command strings in helpers
jyaunches 0e59b1a
test(e2e): seed parity entries for new legacy scripts
jyaunches 107bb92
fix(e2e): tighten convention lint edge cases
jyaunches 6ab5062
fix(e2e): address assertion helper feedback
jyaunches 1750996
fix(e2e): harden fixture helper validation
jyaunches 70f5674
fix(e2e): address scenario workflow feedback
jyaunches 9c65ac1
fix(e2e): harden runtime helper edge cases
jyaunches 9b7fcdf
fix(e2e): harden assertion pattern checks
jyaunches 2666711
fix(e2e): preserve parity YAML parse errors
jyaunches f0e4b16
fix(e2e): match sandbox names literally
jyaunches 5d111f7
fix(e2e): mark scenario scripts executable
jyaunches 7b2f0ac
style(e2e): apply pre-push formatting
jyaunches 80c7852
docs(e2e): align scenario matrix paths
jyaunches 023742b
chore(e2e): restore script executable bits
jyaunches 361df8d
fix(e2e): restore helper hardening
jyaunches 147ba3b
fix(e2e): harden scenario validation
jyaunches 3b38323
Merge remote-tracking branch 'origin/main' into feat/e2e-scenario-mat…
jyaunches 4e04f12
fix(e2e): seed new legacy parity entries
jyaunches 6f865d9
docs(spec): simplify e2e parity plan
jyaunches 47ac12f
docs(spec): add e2e parity test plan
jyaunches eaca286
docs(spec): add e2e parity validation plan
jyaunches 385d86a
fix(e2e): dedupe parity map entries
jyaunches abefc0d
fix(e2e): untrack ignored parity spec
jyaunches 492c30d
docs(spec): apply e2e parity design review
jyaunches f614360
docs(spec): apply e2e parity implementation review
jyaunches 9cf738a
test: Add failing tests for Phase 1
jyaunches 7920672
feat: Implement Phase 1 - Inventory Legacy Assertions
jyaunches 618d8cc
Mark Phase 1 as completed [7920672b0]
jyaunches 089015c
test: Add failing tests for Phase 2
jyaunches 3f24605
feat: Implement Phase 2 - Enforce Parity Map Schema
jyaunches 2f07256
Mark Phase 2 as completed [3f24605c2]
jyaunches 26ad7b7
test(cli): relax installer version timeout
jyaunches 0dc6950
fix(e2e): satisfy parity script hooks
jyaunches 97958fb
style(e2e): format parity scripts
jyaunches 5c84816
fix(e2e): untrack parity spec again
jyaunches dec8b36
style(e2e): format convention lint
jyaunches c223fa6
Merge remote-tracking branch 'origin/main' into feat/e2e-scenario-mat…
jyaunches 830bd05
fix(e2e): seed gateway drift parity entry
jyaunches 3528aa0
test(e2e): complete parity validation mapping
jyaunches fd8ac54
style(e2e): format retired wrapper lint
jyaunches 893c126
Merge branch 'main' into feat/e2e-scenario-matrix-phase1
cv e175d18
Potential fix for pull request finding 'CodeQL / Unused variable, imp…
cv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # E2E parity compare. | ||
| # | ||
| # Runs a legacy `test/e2e/test-*.sh` script AND its migrated scenario on | ||
| # the same runner, collects PASS/FAIL per assertion from both, and fails | ||
| # the job if any mapped assertion in test/e2e/docs/parity-map.yaml diverges. | ||
| # | ||
| # Manual-only (workflow_dispatch). Each migration phase dispatches this | ||
| # workflow for every scenario it introduces and records zero-divergence | ||
| # before marking the phase complete. | ||
|
|
||
| name: e2e-parity-compare | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| legacy_script: | ||
| description: "Legacy script filename under test/e2e/ (e.g. test-full-e2e.sh). Empty = no legacy run, empty-diff only." | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| scenario: | ||
| description: "Migrated scenario id (e.g. ubuntu-repo-cloud-openclaw). Empty = use script map/default bucket scenarios." | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| bucket: | ||
| description: "Parity bucket to run (onboarding-baseline, lifecycle, rebuild-runtime, providers-messaging, final-security-policy-platform-misc)." | ||
| required: false | ||
| default: "" | ||
| type: string | ||
| all_migrated: | ||
| description: "Run all migrated buckets from parity-map.yaml." | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
| strict: | ||
| description: "Pass --strict to compare-parity.sh and fail on missing mapped log assertions." | ||
| required: false | ||
| default: true | ||
| type: boolean | ||
| deferred_handling: | ||
| description: "How deferred/retired assertions are handled by reporting." | ||
| required: false | ||
| default: "skip" | ||
| type: choice | ||
| options: | ||
| - skip | ||
| - report | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: e2e-parity-compare-${{ github.event.inputs.legacy_script }}-${{ github.event.inputs.scenario }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| resolve-runner: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| runner: ${{ steps.pick.outputs.runner }} | ||
| steps: | ||
| - id: pick | ||
| env: | ||
| SCENARIO: ${{ github.event.inputs.scenario }} | ||
| run: | | ||
| case "${SCENARIO}" in | ||
| macos-*) echo "runner=macos-latest" >> "$GITHUB_OUTPUT" ;; | ||
| wsl-*) echo "runner=windows-latest" >> "$GITHUB_OUTPUT" ;; | ||
| gpu-*) echo "runner=self-hosted" >> "$GITHUB_OUTPUT" ;; | ||
| ubuntu-*|brev-*|"") echo "runner=ubuntu-latest" >> "$GITHUB_OUTPUT" ;; | ||
| *) | ||
| echo "::error::Unknown scenario prefix for runner selection: ${SCENARIO}" >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| compare: | ||
| needs: resolve-runner | ||
| runs-on: ${{ needs.resolve-runner.outputs.runner }} | ||
| timeout-minutes: 60 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: npm | ||
|
|
||
| - name: Install root dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Run legacy script | ||
| id: legacy | ||
| if: ${{ github.event.inputs.legacy_script != '' }} | ||
| env: | ||
| NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} | ||
| run: | | ||
| mkdir -p .e2e/parity | ||
| LOG=".e2e/parity/legacy.log" | ||
| if [ ! -x "test/e2e/${{ github.event.inputs.legacy_script }}" ]; then | ||
| echo "::error::legacy script not found: test/e2e/${{ github.event.inputs.legacy_script }}" | ||
| exit 1 | ||
| fi | ||
| bash "test/e2e/${{ github.event.inputs.legacy_script }}" 2>&1 | tee "$LOG" || true | ||
|
|
||
| - name: Run migrated scenario | ||
| id: scenario | ||
| if: ${{ github.event.inputs.scenario != '' }} | ||
| env: | ||
| NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} | ||
| run: | | ||
| mkdir -p .e2e/parity | ||
| LOG=".e2e/parity/scenario.log" | ||
| bash test/e2e/runtime/run-scenario.sh "${{ github.event.inputs.scenario }}" 2>&1 | tee "$LOG" || true | ||
|
|
||
| - name: Compare parity | ||
| env: | ||
| LEGACY_SCRIPT: ${{ github.event.inputs.legacy_script }} | ||
| run: | | ||
| mkdir -p .e2e/parity | ||
| LEGACY_LOG=".e2e/parity/legacy.log" | ||
| SCENARIO_LOG=".e2e/parity/scenario.log" | ||
| [ -f "$LEGACY_LOG" ] || : > "$LEGACY_LOG" | ||
| [ -f "$SCENARIO_LOG" ] || : > "$SCENARIO_LOG" | ||
| SCRIPT_ARG="${LEGACY_SCRIPT:-none.sh}" | ||
| REPORT=".e2e/parity/parity-report.json" | ||
| STRICT_ARGS=() | ||
| if [ "${{ github.event.inputs.strict }}" = "true" ]; then | ||
| STRICT_ARGS+=(--strict) | ||
| fi | ||
| bash scripts/e2e/compare-parity.sh \ | ||
| --script "$SCRIPT_ARG" \ | ||
| --legacy "$LEGACY_LOG" \ | ||
| --scenario "$SCENARIO_LOG" \ | ||
| --map test/e2e/docs/parity-map.yaml \ | ||
| --bucket "${{ github.event.inputs.bucket }}" \ | ||
| --all-migrated "${{ github.event.inputs.all_migrated }}" \ | ||
| --deferred-handling "${{ github.event.inputs.deferred_handling }}" \ | ||
| --report "$REPORT" \ | ||
| "${STRICT_ARGS[@]}" | ||
|
|
||
| - name: Render coverage report | ||
| if: always() | ||
| run: | | ||
| mkdir -p .e2e/parity | ||
| bash test/e2e/runtime/coverage-report.sh > .e2e/parity/coverage-report.md | ||
|
|
||
| - name: Upload parity artifacts | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: e2e-parity-${{ github.event.inputs.scenario }}-${{ github.event.inputs.legacy_script }} | ||
| path: | | ||
| .e2e/ | ||
| if-no-files-found: warn | ||
| retention-days: 14 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Scenario-based E2E. Runs a single setup scenario by id against the | ||
| # matching runner; can also validate resolution / coverage via --plan-only. | ||
| # | ||
| # Manual-only (workflow_dispatch) while scenario-based coverage migrates. | ||
| # Existing nightly-e2e / macos-e2e / wsl-e2e workflows remain unchanged. | ||
|
|
||
| name: e2e-scenarios | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| scenario: | ||
| description: "Scenario id (e.g. ubuntu-repo-cloud-openclaw)" | ||
| required: true | ||
| type: string | ||
| plan_only: | ||
| description: "Resolve and print plan only (no install/onboard/suites)" | ||
| required: false | ||
| default: "false" | ||
| type: choice | ||
| options: | ||
| - "true" | ||
| - "false" | ||
| suite_filter: | ||
| description: "Comma-separated suite ids to run (optional; defaults to the scenario's full suite list)" | ||
| required: false | ||
| default: "" | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: e2e-scenarios-${{ github.event.inputs.scenario }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| # Route the scenario to the correct runner. | ||
| # | ||
| # Scenario ids encode their target platform as the first segment | ||
| # (e.g. `macos-repo-cloud-openclaw`, `wsl-repo-cloud-openclaw`, | ||
| # `gpu-repo-local-ollama-openclaw`). The workflow previously pinned | ||
| # `runs-on: ubuntu-latest` for every scenario, which caused non-Ubuntu | ||
| # scenarios to fail on the wrong runner (CodeRabbit review item #1). | ||
| resolve-runner: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| runner: ${{ steps.pick.outputs.runner }} | ||
| steps: | ||
| - id: pick | ||
| env: | ||
| SCENARIO: ${{ github.event.inputs.scenario }} | ||
| run: | | ||
| case "${SCENARIO}" in | ||
| macos-*) echo "runner=macos-latest" >> "$GITHUB_OUTPUT" ;; | ||
| wsl-*) echo "runner=windows-latest" >> "$GITHUB_OUTPUT" ;; | ||
| gpu-*) echo "runner=self-hosted" >> "$GITHUB_OUTPUT" ;; | ||
| ubuntu-*|brev-*) echo "runner=ubuntu-latest" >> "$GITHUB_OUTPUT" ;; | ||
| *) | ||
| echo "::error::Unknown scenario prefix for runner selection: ${SCENARIO}" >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| run-scenario: | ||
| needs: resolve-runner | ||
| runs-on: ${{ needs.resolve-runner.outputs.runner }} | ||
| timeout-minutes: 45 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: npm | ||
|
|
||
| - name: Install root dependencies | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: Render coverage report | ||
| run: | | ||
| mkdir -p .e2e | ||
| bash test/e2e/runtime/coverage-report.sh > .e2e/coverage.md | ||
| echo '## E2E scenario coverage' >> "$GITHUB_STEP_SUMMARY" | ||
| cat .e2e/coverage.md >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: Show resolved plan | ||
| run: | | ||
| bash test/e2e/runtime/run-scenario.sh "${{ github.event.inputs.scenario }}" --plan-only | ||
|
|
||
| - name: Run scenario | ||
| if: github.event.inputs.plan_only != 'true' | ||
| env: | ||
| NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} | ||
| E2E_SUITE_FILTER: ${{ github.event.inputs.suite_filter }} | ||
| run: | | ||
| bash test/e2e/runtime/run-scenario.sh "${{ github.event.inputs.scenario }}" | ||
|
|
||
| - name: Upload scenario artifacts | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: e2e-scenario-${{ github.event.inputs.scenario }} | ||
| path: | | ||
| .e2e/ | ||
| test/e2e/logs/ | ||
| if-no-files-found: warn | ||
| retention-days: 14 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,3 +46,4 @@ secrets.json | |
| secrets.yaml | ||
| service-account*.json | ||
| token.json | ||
| .e2e/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.