From bdb8152eb4a3785af0e7d6278ea292b329809a3f Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Wed, 20 May 2026 15:38:45 -0400 Subject: [PATCH 1/3] ci(e2e): add scenario run-all workflow --- .github/workflows/e2e-scenarios-all.yaml | 73 ++++++++++++++++++++++++ .github/workflows/e2e-scenarios.yaml | 52 +++++++++++------ 2 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/e2e-scenarios-all.yaml diff --git a/.github/workflows/e2e-scenarios-all.yaml b/.github/workflows/e2e-scenarios-all.yaml new file mode 100644 index 0000000000..b56ebfb9fd --- /dev/null +++ b/.github/workflows/e2e-scenarios-all.yaml @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Scenario-based E2E fan-out. Runs every setup scenario from the current +# migration catalog by calling the single-scenario runner workflow. + +name: E2E / Scenario Runner / All + +on: + workflow_dispatch: + inputs: + suite_filter: + description: "Comma-separated suite ids to run for every scenario (optional; defaults to each scenario's full suite list)" + required: false + default: "" + type: string + +permissions: + contents: read + +concurrency: + group: e2e-scenarios-all-${{ github.ref }} + cancel-in-progress: false + +jobs: + ubuntu-repo-cloud-openclaw: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: ubuntu-repo-cloud-openclaw + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + ubuntu-repo-cloud-hermes: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: ubuntu-repo-cloud-hermes + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + gpu-repo-local-ollama-openclaw: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: gpu-repo-local-ollama-openclaw + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + macos-repo-cloud-openclaw: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: macos-repo-cloud-openclaw + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + wsl-repo-cloud-openclaw: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: wsl-repo-cloud-openclaw + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + brev-launchable-cloud-openclaw: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: brev-launchable-cloud-openclaw + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit + + ubuntu-no-docker-preflight-negative: + uses: ./.github/workflows/e2e-scenarios.yaml + with: + scenario: ubuntu-no-docker-preflight-negative + suite_filter: ${{ inputs.suite_filter }} + secrets: inherit diff --git a/.github/workflows/e2e-scenarios.yaml b/.github/workflows/e2e-scenarios.yaml index 5fd1e0cf7a..4136e54914 100644 --- a/.github/workflows/e2e-scenarios.yaml +++ b/.github/workflows/e2e-scenarios.yaml @@ -10,6 +10,20 @@ name: E2E / Scenario Runner on: + workflow_call: + inputs: + scenario: + description: "Scenario id (e.g. ubuntu-repo-cloud-openclaw)" + required: true + type: string + suite_filter: + description: "Comma-separated suite ids to run (optional; defaults to the scenario's full suite list)" + required: false + default: "" + type: string + secrets: + NVIDIA_API_KEY: + required: false workflow_dispatch: inputs: scenario: @@ -26,7 +40,7 @@ permissions: contents: read concurrency: - group: e2e-scenarios-${{ github.event.inputs.scenario }} + group: e2e-scenarios-${{ inputs.scenario }} cancel-in-progress: false jobs: @@ -44,7 +58,7 @@ jobs: steps: - id: pick env: - SCENARIO: ${{ github.event.inputs.scenario }} + SCENARIO: ${{ inputs.scenario }} run: | case "${SCENARIO}" in macos-*) echo "runner=macos-26" >> "$GITHUB_OUTPUT" ;; @@ -66,25 +80,25 @@ jobs: NEMOCLAW_RECREATE_SANDBOX: "1" steps: - name: Force LF line endings for WSL checkout - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: git config --global core.autocrlf false - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Node - if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} + if: ${{ !startsWith(inputs.scenario, 'wsl-') }} uses: actions/setup-node@v6 with: node-version: 22 cache: npm - name: Install root dependencies - if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} + if: ${{ !startsWith(inputs.scenario, 'wsl-') }} run: npm ci --ignore-scripts - name: Render coverage report - if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} + if: ${{ !startsWith(inputs.scenario, 'wsl-') }} run: | mkdir -p .e2e bash test/e2e/runtime/coverage-report.sh > .e2e/coverage.md @@ -92,15 +106,15 @@ jobs: cat .e2e/coverage.md >> "$GITHUB_STEP_SUMMARY" - name: Run scenario - if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} + if: ${{ !startsWith(inputs.scenario, 'wsl-') }} env: NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} - E2E_SUITE_FILTER: ${{ github.event.inputs.suite_filter }} + E2E_SUITE_FILTER: ${{ inputs.suite_filter }} run: | - bash test/e2e/runtime/run-scenario.sh "${{ github.event.inputs.scenario }}" + bash test/e2e/runtime/run-scenario.sh "${{ inputs.scenario }}" - name: Resolve workspace paths for WSL - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $winPath = "${{ github.workspace }}" @@ -112,7 +126,7 @@ jobs: "WSL_WORKDIR=$wslWorkdir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Ensure Ubuntu WSL exists - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | wsl --list --verbose 2>&1 | Out-Default @@ -124,7 +138,7 @@ jobs: wsl --set-default $env:WSL_DISTRO - name: Install WSL dependencies - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $script = @' @@ -151,7 +165,7 @@ jobs: wsl -d $env:WSL_DISTRO -- bash -l $wslTmp - name: Copy checkout into WSL ext4 workspace - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $script = @" @@ -169,7 +183,7 @@ jobs: wsl -d $env:WSL_DISTRO -- bash -l $wslTmp - name: Install root dependencies in WSL - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $script = @" @@ -185,11 +199,11 @@ jobs: wsl -d $env:WSL_DISTRO -- bash -l $wslTmp - name: Run scenario in WSL - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell env: NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} - E2E_SUITE_FILTER: ${{ github.event.inputs.suite_filter }} + E2E_SUITE_FILTER: ${{ inputs.suite_filter }} run: | $script = @" set -euo pipefail @@ -197,7 +211,7 @@ jobs: export NVIDIA_API_KEY='$env:NVIDIA_API_KEY' export E2E_SUITE_FILTER='$env:E2E_SUITE_FILTER' export NEMOCLAW_RECREATE_SANDBOX='$env:NEMOCLAW_RECREATE_SANDBOX' - bash test/e2e/runtime/run-scenario.sh '${{ github.event.inputs.scenario }}' + bash test/e2e/runtime/run-scenario.sh '${{ inputs.scenario }}' "@ $tmp = "$env:RUNNER_TEMP\wsl-step.sh" [IO.File]::WriteAllText($tmp, ($script -replace "`r",""), (New-Object System.Text.UTF8Encoding $false)) @@ -205,7 +219,7 @@ jobs: wsl -d $env:WSL_DISTRO -- bash -l $wslTmp - name: Copy WSL artifacts back to checkout - if: always() && startsWith(github.event.inputs.scenario, 'wsl-') + if: always() && startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $script = @" @@ -223,7 +237,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: e2e-scenario-${{ github.event.inputs.scenario }} + name: e2e-scenario-${{ inputs.scenario }} path: | .e2e/ test/e2e/logs/ From b23062d6b4481de970542d7d0637b07d2ef80324 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Wed, 20 May 2026 16:21:52 -0400 Subject: [PATCH 2/3] fix(e2e): align artifact expectation with reusable input --- .../e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts b/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts index 43f90afa60..bc79327d70 100644 --- a/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts +++ b/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts @@ -80,7 +80,7 @@ describe("e2e-scenarios workflow", () => { it("e2e_scenarios_workflow_should_upload_artifacts", () => { const wf = loadWorkflow(); const upload = uploadArtifactStep(wf, "run-scenario", "Upload scenario artifacts"); - expect(upload.with?.name).toBe("e2e-scenario-${{ github.event.inputs.scenario }}"); + expect(upload.with?.name).toBe("e2e-scenario-${{ inputs.scenario }}"); expect(upload.with?.path).toContain(".e2e/"); expect(upload.with?.["include-hidden-files"]).toBe(true); }); From ba321522fb0781100dfe848a34a6769cefa57a11 Mon Sep 17 00:00:00 2001 From: Julie Yaunches Date: Wed, 20 May 2026 16:31:41 -0400 Subject: [PATCH 3/3] fix(ci): limit scenario workflow secrets --- .github/workflows/e2e-scenarios-all.yaml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e-scenarios-all.yaml b/.github/workflows/e2e-scenarios-all.yaml index b56ebfb9fd..88c9d58e4e 100644 --- a/.github/workflows/e2e-scenarios-all.yaml +++ b/.github/workflows/e2e-scenarios-all.yaml @@ -28,46 +28,53 @@ jobs: with: scenario: ubuntu-repo-cloud-openclaw suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} ubuntu-repo-cloud-hermes: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: ubuntu-repo-cloud-hermes suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} gpu-repo-local-ollama-openclaw: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: gpu-repo-local-ollama-openclaw suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} macos-repo-cloud-openclaw: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: macos-repo-cloud-openclaw suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} wsl-repo-cloud-openclaw: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: wsl-repo-cloud-openclaw suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} brev-launchable-cloud-openclaw: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: brev-launchable-cloud-openclaw suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} ubuntu-no-docker-preflight-negative: uses: ./.github/workflows/e2e-scenarios.yaml with: scenario: ubuntu-no-docker-preflight-negative suite_filter: ${{ inputs.suite_filter }} - secrets: inherit + secrets: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}