Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 11 additions & 178 deletions .github/workflows/regression-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: E2E / Regression Runner

# Regression E2E holding pen.
#
# Jobs here are intentionally NOT part of the scheduled E2E workflow. They are
# Jobs here are intentionally not part of the main-push E2E workflow. They are
# failing-test-first coverage guards or high-signal regressions that should be
# easy to dispatch while the owning fix is in flight. Periodically review this
# workflow and promote stable/high-value jobs into .github/workflows/e2e.yaml.
Expand All @@ -21,7 +21,7 @@ on:
jobs:
description: >-
Comma-separated regression job names to run (empty = all).
Valid: model-router-provider-routed-inference-e2e,openclaw-plugin-runtime-exdev-e2e,whatsapp-qr-compact-e2e
Valid: whatsapp-qr-compact-e2e
required: false
type: string
default: ""
Expand All @@ -39,9 +39,8 @@ concurrency:
jobs:
select_regression_jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
model_router_provider_routed_inference: ${{ steps.select.outputs.model_router_provider_routed_inference }}
openclaw_plugin_runtime_exdev: ${{ steps.select.outputs.openclaw_plugin_runtime_exdev }}
whatsapp_qr_compact: ${{ steps.select.outputs.whatsapp_qr_compact }}
steps:
- id: select
Expand All @@ -50,180 +49,14 @@ jobs:
run: |
set -euo pipefail
normalized="$(printf '%s' "$JOBS" | tr -d '[:space:]')"

includes_job() {
case ",${normalized}," in
*",$1,"*) return 0 ;;
*) return 1 ;;
esac
}

if [ -z "$normalized" ] || includes_job "model-router-provider-routed-inference-e2e"; then
echo "model_router_provider_routed_inference=true" >> "$GITHUB_OUTPUT"
else
echo "model_router_provider_routed_inference=false" >> "$GITHUB_OUTPUT"
fi

if [ -z "$normalized" ] || includes_job "openclaw-plugin-runtime-exdev-e2e"; then
echo "openclaw_plugin_runtime_exdev=true" >> "$GITHUB_OUTPUT"
else
echo "openclaw_plugin_runtime_exdev=false" >> "$GITHUB_OUTPUT"
fi

if [ -z "$normalized" ] || includes_job "whatsapp-qr-compact-e2e"; then
echo "whatsapp_qr_compact=true" >> "$GITHUB_OUTPUT"
else
echo "whatsapp_qr_compact=false" >> "$GITHUB_OUTPUT"
fi

# ── Model Router provider-routed inference E2E ─────────────────
# Coverage guard for #3255. Model Router onboard must generate a routed
# provider that can answer through inference.local instead of returning
# HTTP 503 / "inference service unavailable" after a successful onboard.
model-router-provider-routed-inference-e2e:
needs: select_regression_jobs
if: >-
github.repository == 'NVIDIA/NemoClaw' &&
needs.select_regression_jobs.outputs.model_router_provider_routed_inference == 'true'
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Prepare E2E workspace
uses: NVIDIA/NemoClaw/.github/actions/prepare-e2e@f6304bc25fc35bfaa441c8c2fbfee38f72805a75

- name: Run Model Router provider-routed inference E2E test
env:
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
NEMOCLAW_RUN_LIVE_E2E: "1"
run: npx vitest run --project e2e-live test/e2e/live/model-router-provider-routed-inference.test.ts --silent=false --reporter=default

- name: Upload Model Router provider-routed inference logs on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: model-router-provider-routed-inference-logs
path: |
/tmp/nemoclaw-e2e-model-router-onboard.log
/tmp/nemoclaw-e2e-model-router-health.log
/tmp/nemoclaw-e2e-model-router-response.log
if-no-files-found: ignore

# ── OpenClaw release-baseline custom-plugin E2E ────────────────
# The exact v0.0.71 baseline runs in parallel with the current lifecycle
# contract so release provenance does not extend the EXDEV critical path.
openclaw-plugin-runtime-exdev-release-e2e:
needs: select_regression_jobs
if: >-
github.repository == 'NVIDIA/NemoClaw' &&
needs.select_regression_jobs.outputs.openclaw_plugin_runtime_exdev == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 55
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
cache: npm

- name: Install root dependencies
run: npm ci --ignore-scripts

- name: Build CLI
run: npm run build:cli

- name: Run OpenClaw custom-plugin release baseline Vitest test
env:
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/openclaw-plugin-runtime-exdev-release
E2E_TARGET_ID: openclaw-plugin-runtime-exdev-release
NEMOCLAW_RUN_LIVE_E2E: "1"
NEMOCLAW_SANDBOX_NAME: e2e-oc-exdev-rel
run: |
set -euo pipefail
npx vitest run --project e2e-live \
test/e2e/live/openclaw-plugin-runtime-exdev.test.ts \
-t release-baseline \
--silent=false --reporter=default

- name: Upload OpenClaw plugin release baseline artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: openclaw-plugin-runtime-exdev-release-artifacts
path: e2e-artifacts/live/openclaw-plugin-runtime-exdev-release/
include-hidden-files: false
if-no-files-found: ignore
retention-days: 14

# ── OpenClaw current lifecycle and runtime-deps EXDEV E2E ─────
# Coverage guard for #6108 / #3513 / #3127. On Ubuntu/OpenShell sandbox
# layouts where /tmp and /sandbox can live on different filesystems, the
# runtime dependency replacement must complete without EXDEV failures.
openclaw-plugin-runtime-exdev-e2e:
needs: select_regression_jobs
if: >-
github.repository == 'NVIDIA/NemoClaw' &&
needs.select_regression_jobs.outputs.openclaw_plugin_runtime_exdev == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
# Two bounded 25-minute onboards plus the 20-minute rebuild and 15-minute
# Vitest buffer need 85 minutes; allow 20 more for setup and teardown.
timeout-minutes: 105
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
cache: npm

- name: Install root dependencies
run: npm ci --ignore-scripts

- name: Build CLI
run: npm run build:cli

- name: Run OpenClaw custom-plugin lifecycle and runtime-deps EXDEV Vitest test
env:
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/openclaw-plugin-runtime-exdev
E2E_TARGET_ID: openclaw-plugin-runtime-exdev
NEMOCLAW_RUN_LIVE_E2E: "1"
run: |
set -euo pipefail
npx vitest run --project e2e-live \
test/e2e/live/openclaw-plugin-runtime-exdev.test.ts \
-t current-lifecycle \
--silent=false --reporter=default

- name: Upload OpenClaw plugin runtime-deps EXDEV artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: openclaw-plugin-runtime-exdev-artifacts
path: e2e-artifacts/live/openclaw-plugin-runtime-exdev/
include-hidden-files: false
if-no-files-found: ignore
retention-days: 14
case ",${normalized}," in
,|*,whatsapp-qr-compact-e2e,*)
echo "whatsapp_qr_compact=true" >> "$GITHUB_OUTPUT"
;;
*)
echo "whatsapp_qr_compact=false" >> "$GITHUB_OUTPUT"
;;
esac
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

# ── WhatsApp compact-QR reporter-workflow E2E ──────────────────
# Coverage guard for #4522. Drives the real @openclaw/whatsapp +
Expand Down
2 changes: 1 addition & 1 deletion agents/openclaw/dependency-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The reviewed audit wrapper reports lower-severity production findings and blocks
Removal condition: delete the PR #6739 bootstrap checkout, its paired conditional audit step, and the bootstrap-specific test assertions in the first follow-up after this PR merges, before the next release tag; all later PRs must use the normal base-SHA action path.
- Advisory command: `npm ci --ignore-scripts --omit=dev --legacy-peer-deps --prefix agents/openclaw/wechat-runtime && npm audit --omit=dev --audit-level=low --json --prefix agents/openclaw/wechat-runtime && npm audit signatures --prefix agents/openclaw/wechat-runtime`.
- Advisory review: `2026-07-12`; result: `0` known vulnerabilities across the resolved production graph.
- Regression tests: `test/wechat-locked-install.test.ts` keeps the manifest runtime-lock paths and installer verification dispatch synchronized; `test/verify-wechat-runtime-lock.test.ts` proves the installed graph and OpenClaw peer-range compatibility fail closed; `test/wechat-runtime-audit-workflow.test.ts` keeps the Docker cache lifecycle, base-trusted required CI gate, evidence upload, audit threshold, bounded download-only signature retry, invalid-signature denial, and real npm-pack boundary synchronized.
- Regression tests: `test/wechat-locked-install.test.ts` keeps the manifest runtime-lock paths and installer verification dispatch synchronized; `test/verify-wechat-runtime-lock.test.ts` proves the installed graph and OpenClaw peer-range compatibility fail closed; `test/wechat-runtime-audit-workflow.test.ts` keeps the Docker cache lifecycle, audit threshold, bounded download-only signature retry, invalid-signature denial, and real npm-pack boundary synchronized.

The dedicated graph intentionally omits the plugin's `openclaw` peer dependency. The image already installs and integrity-verifies the reviewed OpenClaw runtime separately; auto-installing another OpenClaw copy would create a second unreviewed runtime graph.
Disabling scripts also prevents transitive packages from executing lifecycle code during the trusted image build.
Expand Down
Loading
Loading