diff --git a/.github/workflows/e2e-scenarios.yaml b/.github/workflows/e2e-scenarios.yaml index 5fd1e0cf7ad..1cc20b41710 100644 --- a/.github/workflows/e2e-scenarios.yaml +++ b/.github/workflows/e2e-scenarios.yaml @@ -74,7 +74,7 @@ jobs: - name: Set up Node if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} - uses: actions/setup-node@v6 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: 22 cache: npm @@ -85,19 +85,51 @@ jobs: - name: Render coverage report if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} + env: + SCENARIO: ${{ github.event.inputs.scenario }} 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" + { + echo '# E2E Scenario Report' + echo '' + # Keep workflow_dispatch input in an env var so untrusted scenario text + # is data, not YAML-interpolated shell source. + printf '**Scenario:** `%s`\n' "$SCENARIO" + echo '' + cat .e2e/coverage.md + } | tee -a "$GITHUB_STEP_SUMMARY" - name: Run scenario if: ${{ !startsWith(github.event.inputs.scenario, 'wsl-') }} env: NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} E2E_SUITE_FILTER: ${{ github.event.inputs.suite_filter }} + SCENARIO: ${{ github.event.inputs.scenario }} run: | - bash test/e2e/runtime/run-scenario.sh "${{ github.event.inputs.scenario }}" + # Keep workflow_dispatch input in an env var so untrusted scenario text + # is data, not YAML-interpolated shell source. + set +e + bash test/e2e/runtime/run-scenario.sh "$SCENARIO" + rc=$? + set -e + { + echo '' + echo '## Scenario execution result' + echo '' + if [ "$rc" -eq 0 ]; then + printf -- '- Scenario `%s` completed successfully.\n' "$SCENARIO" + else + printf -- '- Scenario `%s` failed with exit code `%s`.\n' "$SCENARIO" "$rc" + fi + if grep -R '^SKIP:' .e2e test/e2e/logs >/tmp/e2e-skips.txt 2>/dev/null; then + echo '' + echo '### Runtime skips observed' + echo '' + sed 's/^/- `/' /tmp/e2e-skips.txt | sed 's/$/`/' + fi + } | tee -a "$GITHUB_STEP_SUMMARY" + exit "$rc" - name: Resolve workspace paths for WSL if: startsWith(github.event.inputs.scenario, 'wsl-') @@ -190,15 +222,17 @@ jobs: env: NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }} E2E_SUITE_FILTER: ${{ github.event.inputs.suite_filter }} + SCENARIO: ${{ github.event.inputs.scenario }} run: | - $script = @" + $env:WSLENV = "NVIDIA_API_KEY:E2E_SUITE_FILTER:NEMOCLAW_RECREATE_SANDBOX:SCENARIO:WSL_WORKDIR" + $script = @' set -euo pipefail - cd '$env:WSL_WORKDIR' - 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 }}' - "@ + cd "$WSL_WORKDIR" + export NVIDIA_API_KEY + export E2E_SUITE_FILTER + export NEMOCLAW_RECREATE_SANDBOX + bash test/e2e/runtime/run-scenario.sh "$SCENARIO" + '@ $tmp = "$env:RUNNER_TEMP\wsl-step.sh" [IO.File]::WriteAllText($tmp, ($script -replace "`r",""), (New-Object System.Text.UTF8Encoding $false)) $wslTmp = wsl -d $env:WSL_DISTRO -- wslpath -u ($tmp -replace '\\','/') @@ -221,7 +255,7 @@ jobs: - name: Upload scenario artifacts if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: e2e-scenario-${{ github.event.inputs.scenario }} path: | 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 c3cd09420af..43f90afa605 100644 --- a/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts +++ b/test/e2e/scenario-framework-tests/e2e-scenarios-workflow.test.ts @@ -51,7 +51,7 @@ function namedStep(workflow: AnyRecord, jobId: string, stepName: string): Workfl function uploadArtifactStep(workflow: AnyRecord, jobId: string, stepName: string): WorkflowStep { const step = namedStep(workflow, jobId, stepName); - expect(step.uses).toBe("actions/upload-artifact@v4"); + expect(step.uses).toMatch(/^actions\/upload-artifact@(?:v4|[a-f0-9]{40})$/); return step; }