diff --git a/.github/workflows/e2e-scenarios-all.yaml b/.github/workflows/e2e-scenarios-all.yaml new file mode 100644 index 0000000000..88c9d58e4e --- /dev/null +++ b/.github/workflows/e2e-scenarios-all.yaml @@ -0,0 +1,80 @@ +# 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: + 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: + 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: + 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: + 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: + 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: + 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: + NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} diff --git a/.github/workflows/e2e-scenarios.yaml b/.github/workflows/e2e-scenarios.yaml index 1cc20b4171..ff345b8aac 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,27 +80,27 @@ 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # 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-') }} env: - SCENARIO: ${{ github.event.inputs.scenario }} + SCENARIO: ${{ inputs.scenario }} run: | mkdir -p .e2e bash test/e2e/runtime/coverage-report.sh > .e2e/coverage.md @@ -101,13 +115,13 @@ jobs: } | tee -a "$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 }} - SCENARIO: ${{ github.event.inputs.scenario }} + E2E_SUITE_FILTER: ${{ inputs.suite_filter }} + SCENARIO: ${{ inputs.scenario }} run: | - # Keep workflow_dispatch input in an env var so untrusted scenario text + # Keep workflow inputs in env vars so untrusted scenario text # is data, not YAML-interpolated shell source. set +e bash test/e2e/runtime/run-scenario.sh "$SCENARIO" @@ -132,7 +146,7 @@ jobs: exit "$rc" - name: Resolve workspace paths for WSL - if: startsWith(github.event.inputs.scenario, 'wsl-') + if: startsWith(inputs.scenario, 'wsl-') shell: powershell run: | $winPath = "${{ github.workspace }}" @@ -144,7 +158,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 @@ -156,7 +170,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 = @' @@ -183,7 +197,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 = @" @@ -201,7 +215,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 = @" @@ -217,12 +231,12 @@ 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 }} - SCENARIO: ${{ github.event.inputs.scenario }} + E2E_SUITE_FILTER: ${{ inputs.suite_filter }} + SCENARIO: ${{ inputs.scenario }} run: | $env:WSLENV = "NVIDIA_API_KEY:E2E_SUITE_FILTER:NEMOCLAW_RECREATE_SANDBOX:SCENARIO:WSL_WORKDIR" $script = @' @@ -239,7 +253,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 = @" @@ -257,7 +271,7 @@ jobs: if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: - name: e2e-scenario-${{ github.event.inputs.scenario }} + name: e2e-scenario-${{ inputs.scenario }} path: | .e2e/ test/e2e/logs/ 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); });