Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
df4f0e8
feat(onboard): use OpenShell docker GPU sandboxes
ericksoa May 4, 2026
74fe6eb
fix(onboard): clean up docker gpu check regressions
ericksoa May 4, 2026
1e94f2e
fix(test): isolate docker-driver onboarding guards
ericksoa May 4, 2026
a639877
fix(base): move sandbox images to trixie for openshell
ericksoa May 4, 2026
dccd4c5
fix(base): include chattr runtime dependency
ericksoa May 4, 2026
6b0c902
fix(base): satisfy docker lint for runtime deps
ericksoa May 4, 2026
6bc67c8
test(wsl): remove controlling tty in installer atomicity test
ericksoa May 4, 2026
f803fbc
fix(onboard): reuse docker-driver gateway runtime
ericksoa May 4, 2026
9fd1dae
fix(shields): gate docker-driver exec discovery
ericksoa May 4, 2026
ad613cf
fix(onboard): address docker gpu review feedback
ericksoa May 4, 2026
68a8315
fix(e2e): stabilize docker-driver lifecycle tests
ericksoa May 5, 2026
ff0fbbb
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
0186100
Merge branch 'main' into codex/openshell-docker-gpu-onboard
ericksoa May 5, 2026
eca7325
Merge remote-tracking branch 'origin/main' into repair/pr3001-clean-m…
ericksoa May 5, 2026
d99923c
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
edd1173
ci: force IPv4 for WSL apt setup
ericksoa May 5, 2026
f6056d5
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
a36c62d
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
6abace5
fix(cli): preserve onboard passthrough flags
ericksoa May 5, 2026
f683111
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
471453e
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 5, 2026
23afabf
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
a9350d1
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
b07dcc5
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
57857dc
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
6fe57b7
fix(onboard): preserve sandbox GPU auto mode on resume
ericksoa May 6, 2026
78dc20c
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
f4f38a8
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
fc3dfd4
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
c25df40
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 6, 2026
0ebfe4c
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 7, 2026
fd3133e
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 7, 2026
210e9e7
fix(onboard): narrow direct GPU proc writes
ericksoa May 7, 2026
dd76410
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 7, 2026
133ab48
fix(agent): bypass base resolver for forced rebuilds
ericksoa May 7, 2026
e9bf328
fix(onboard): support openshell gateway remove
ericksoa May 7, 2026
941f3c1
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 7, 2026
fe3f377
fix(onboard): persist reused gateway during onboard
ericksoa May 7, 2026
e6f8924
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
37bd091
fix(hermes): allow current Python runtime in Slack policy
ericksoa May 8, 2026
effe9a9
fix(e2e): align double-onboard alias with docker gateway
ericksoa May 8, 2026
6751206
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
f4c9540
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
c4b608a
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
85143a3
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
dbc099c
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
130d74d
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
cd43f8d
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
a43d8f5
fix(messaging): honor OpenShell scoped provider placeholders
ericksoa May 8, 2026
2363547
fix(hermes): tolerate runtime-scoped placeholders
ericksoa May 8, 2026
782b1b7
test(messaging): quiet loopback rewriter probe
ericksoa May 8, 2026
6cd7ddb
test(messaging): retry transient Discord upstream warmup
ericksoa May 8, 2026
c1a047a
test(messaging): accept scoped Slack placeholders
ericksoa May 8, 2026
bfe1033
test(messaging): retry Discord proxy warmup responses
ericksoa May 8, 2026
28c1091
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 8, 2026
0eba09a
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 9, 2026
2bb35c1
fix(onboard): target OpenShell 0.0.37 release
ericksoa May 9, 2026
277d481
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 9, 2026
524cfae
docs(cli): include sandbox GPU onboard flags
ericksoa May 9, 2026
a88a31e
fix(onboard): restart stale OpenShell docker gateway
ericksoa May 9, 2026
ec6434b
fix(ci): keep gateway upgrade e2e dev deps
ericksoa May 9, 2026
06d942f
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 9, 2026
de2137c
test(hermes): use available python for slack probe
ericksoa May 9, 2026
9bccc08
test(e2e): cover OpenShell upgrade cleanup drift
ericksoa May 9, 2026
269a378
fix(hermes): persist proxy CA env for Slack probes
ericksoa May 9, 2026
4d2c17c
test(hermes): classify Slack Python probe errors
ericksoa May 9, 2026
5fc43f9
test(hermes): treat Slack remote close as transient
ericksoa May 9, 2026
22f871d
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 10, 2026
416837e
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 10, 2026
5bb752a
Merge remote-tracking branch 'origin/main' into codex/openshell-docke…
ericksoa May 11, 2026
7ea3e79
fix(e2e): refresh mutable config hash before command exec
ericksoa May 11, 2026
1de0193
Merge branch 'main' into codex/openshell-docker-gpu-onboard
cv May 11, 2026
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
18 changes: 17 additions & 1 deletion .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,12 @@ reviews:
- `hermes-discord-e2e` — Hermes Discord config schema + placeholder
isolation
- `hermes-slack-e2e` — Hermes Slack policy + Python placeholder egress
- `openshell-gateway-upgrade-e2e` — stale Linux Docker-driver gateway
process restart after OpenShell upgrade

To run selectively:
```
gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=cloud-e2e,sandbox-operations-e2e,rebuild-openclaw-e2e,messaging-compatible-endpoint-e2e,hermes-discord-e2e,hermes-slack-e2e
gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=cloud-e2e,sandbox-operations-e2e,rebuild-openclaw-e2e,messaging-compatible-endpoint-e2e,hermes-discord-e2e,hermes-slack-e2e,openshell-gateway-upgrade-e2e
```

- path: "src/nemoclaw.ts"
Expand Down Expand Up @@ -425,6 +427,20 @@ reviews:
- path: "nemoclaw-blueprint/openclaw-plugins/kimi-inference-compat/**"
instructions: *e2e-kimi-inference-compat

- path: "test/e2e/test-openshell-gateway-upgrade.sh"
instructions: |
This script validates the old OpenShell install upgrade guard for
Linux Docker-driver gateway processes.

**E2E test recommendation:**
- `openshell-gateway-upgrade-e2e` — stale gateway process restart after
OpenShell upgrade

To run selectively:
```
gh workflow run nightly-e2e.yaml --ref <branch> -f jobs=openshell-gateway-upgrade-e2e
```

- path: ".github/workflows/nightly-e2e.yaml"
instructions: |
This is the nightly E2E workflow definition. Changes here affect
Expand Down
55 changes: 49 additions & 6 deletions .github/actions/resolve-hermes-base-image/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,53 @@ runs:
- name: Resolve Hermes sandbox base image
shell: bash
run: |
if docker pull ghcr.io/nvidia/nemoclaw/hermes-sandbox-base:latest 2>/dev/null; then
echo "HERMES_BASE_IMAGE=ghcr.io/nvidia/nemoclaw/hermes-sandbox-base:latest" >> "$GITHUB_ENV"
else
echo "::warning::GHCR Hermes base image not available, building locally"
docker build -f agents/hermes/Dockerfile.base -t nemoclaw-hermes-base-local .
echo "HERMES_BASE_IMAGE=nemoclaw-hermes-base-local" >> "$GITHUB_ENV"
set -euo pipefail

image="ghcr.io/nvidia/nemoclaw/hermes-sandbox-base"
min_glibc="2.39"

glibc_version() {
docker run --rm --entrypoint /usr/bin/ldd "$1" --version 2>/dev/null \
| sed -nE 's/.*GLIBC ([0-9]+\.[0-9]+).*/\1/p; s/.* ([0-9]+\.[0-9]+)$/\1/p' \
| head -n 1
}

glibc_ok() {
local have="$1"
[[ -n "$have" ]] && [[ "$(printf '%s\n%s\n' "$min_glibc" "$have" | sort -V | head -n 1)" == "$min_glibc" ]]
}

try_image() {
local ref="$1" version
if ! docker pull "$ref" >/dev/null 2>&1; then
return 1
fi
version="$(glibc_version "$ref" || true)"
if ! glibc_ok "$version"; then
echo "::warning::Hermes sandbox base image ${ref} has glibc ${version:-unknown}; need >= ${min_glibc}"
return 1
fi
echo "HERMES_BASE_IMAGE=${ref}" >> "$GITHUB_ENV"
return 0
Comment on lines +39 to +40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Code references =="
rg -n 'HERMES_BASE_IMAGE|NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF' .github src test

echo
echo "== Workflow env wiring =="
rg -n 'HERMES_BASE_IMAGE|NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF|env:' .github/workflows

Repository: NVIDIA/NemoClaw

Length of output: 8361


🏁 Script executed:

find . -type f -name "*agent*onboard*" 2>/dev/null | head -20

Repository: NVIDIA/NemoClaw

Length of output: 145


🏁 Script executed:

# Search for NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF explicitly
rg -i 'NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF' --type yaml --type ts --type js --type py

Repository: NVIDIA/NemoClaw

Length of output: 41


🏁 Script executed:

# Check if agent-onboard exists and what env vars it references
fd -e ts -e py 'onboard' | head -10

Repository: NVIDIA/NemoClaw

Length of output: 369


🏁 Script executed:

wc -l src/lib/agent-onboard.ts

Repository: NVIDIA/NemoClaw

Length of output: 88


🏁 Script executed:

rg -n 'HERMES|hermes|BASE_IMAGE|SANDBOX' src/lib/agent-onboard.ts -i

Repository: NVIDIA/NemoClaw

Length of output: 3670


🏁 Script executed:

# Look for process.env or getenv calls
rg -n 'process\.env|getenv' src/lib/agent-onboard.ts

Repository: NVIDIA/NemoClaw

Length of output: 41


🏁 Script executed:

cat src/lib/sandbox-base-image.ts

Repository: NVIDIA/NemoClaw

Length of output: 8515


🏁 Script executed:

# Check the workflow that calls resolve-hermes-base-image
rg -A 20 'resolve-hermes-base-image' .github/workflows/

Repository: NVIDIA/NemoClaw

Length of output: 2051


🏁 Script executed:

# Check if HERMES_BASE_IMAGE is ever remapped or reassigned to NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF
rg -B 5 -A 5 'NEMOCLAW_HERMES|HERMES_BASE_IMAGE' .github/workflows/ | head -100

Repository: NVIDIA/NemoClaw

Length of output: 1017


🏁 Script executed:

# Check the resolve-hermes-base-image action file completely to see all exports
cat .github/actions/resolve-hermes-base-image/action.yaml

Repository: NVIDIA/NemoClaw

Length of output: 2275


🏁 Script executed:

# Search for any step that sets NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF
rg -n 'NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF' .

Repository: NVIDIA/NemoClaw

Length of output: 41


Export the environment variable name that the onboarding code reads.

The action exports HERMES_BASE_IMAGE, but agent-onboard.ts resolves pinned base images from NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF. Unless a workflow remaps the value, the resolved image is never used and the onboarding process falls back to tag discovery or local build.

Suggested fix
-          echo "HERMES_BASE_IMAGE=${ref}" >> "$GITHUB_ENV"
+          echo "HERMES_BASE_IMAGE=${ref}" >> "$GITHUB_ENV"
+          echo "NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF=${ref}" >> "$GITHUB_ENV"
@@
-        echo "HERMES_BASE_IMAGE=nemoclaw-hermes-base-local" >> "$GITHUB_ENV"
+        echo "HERMES_BASE_IMAGE=nemoclaw-hermes-base-local" >> "$GITHUB_ENV"
+        echo "NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF=nemoclaw-hermes-base-local" >> "$GITHUB_ENV"

Also applies to: 62-62

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/actions/resolve-hermes-base-image/action.yaml around lines 39 - 40,
The action currently writes HERMES_BASE_IMAGE to GITHUB_ENV but the onboarding
code (agent-onboard.ts) reads NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF, so the
resolved pinned image is never consumed; update the action to export
NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF (or export both HERMES_BASE_IMAGE and
NEMOCLAW_HERMES_SANDBOX_BASE_IMAGE_REF) instead of only HERMES_BASE_IMAGE where
the file writes the env (the echo "HERMES_BASE_IMAGE=${ref}" >> "$GITHUB_ENV"
occurrences, including the other similar occurrence around the later echo),
ensuring the onboarding code will receive the pinned base image value.

}

candidates=()
if [[ -n "${GITHUB_SHA:-}" ]]; then
candidates+=("${image}:${GITHUB_SHA:0:8}" "${image}:${GITHUB_SHA:0:7}")
fi
candidates+=("${image}:latest")

for ref in "${candidates[@]}"; do
if try_image "$ref"; then
exit 0
fi
done

echo "::warning::No compatible GHCR Hermes sandbox base image found, building locally"
docker build -f agents/hermes/Dockerfile.base -t nemoclaw-hermes-base-local .
version="$(glibc_version nemoclaw-hermes-base-local || true)"
if ! glibc_ok "$version"; then
echo "::error::Local Hermes sandbox base image has glibc ${version:-unknown}; need >= ${min_glibc}"
exit 1
fi
echo "HERMES_BASE_IMAGE=nemoclaw-hermes-base-local" >> "$GITHUB_ENV"
55 changes: 49 additions & 6 deletions .github/actions/resolve-sandbox-base-image/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,53 @@ runs:
- name: Resolve sandbox base image
shell: bash
run: |
if docker pull ghcr.io/nvidia/nemoclaw/sandbox-base:latest 2>/dev/null; then
echo "BASE_IMAGE=ghcr.io/nvidia/nemoclaw/sandbox-base:latest" >> "$GITHUB_ENV"
else
echo "::warning::GHCR base image not available, building locally"
docker build -f Dockerfile.base -t nemoclaw-sandbox-base-local .
echo "BASE_IMAGE=nemoclaw-sandbox-base-local" >> "$GITHUB_ENV"
set -euo pipefail

image="ghcr.io/nvidia/nemoclaw/sandbox-base"
min_glibc="2.39"

glibc_version() {
docker run --rm --entrypoint /usr/bin/ldd "$1" --version 2>/dev/null \
| sed -nE 's/.*GLIBC ([0-9]+\.[0-9]+).*/\1/p; s/.* ([0-9]+\.[0-9]+)$/\1/p' \
| head -n 1
}

glibc_ok() {
local have="$1"
[[ -n "$have" ]] && [[ "$(printf '%s\n%s\n' "$min_glibc" "$have" | sort -V | head -n 1)" == "$min_glibc" ]]
}

try_image() {
local ref="$1" version
if ! docker pull "$ref" >/dev/null 2>&1; then
return 1
fi
version="$(glibc_version "$ref" || true)"
if ! glibc_ok "$version"; then
echo "::warning::Sandbox base image ${ref} has glibc ${version:-unknown}; need >= ${min_glibc}"
return 1
fi
echo "BASE_IMAGE=${ref}" >> "$GITHUB_ENV"
return 0
}

candidates=()
if [[ -n "${GITHUB_SHA:-}" ]]; then
candidates+=("${image}:${GITHUB_SHA:0:8}" "${image}:${GITHUB_SHA:0:7}")
fi
candidates+=("${image}:latest")

for ref in "${candidates[@]}"; do
if try_image "$ref"; then
exit 0
fi
done

echo "::warning::No compatible GHCR sandbox base image found, building locally"
docker build -f Dockerfile.base -t nemoclaw-sandbox-base-local .
version="$(glibc_version nemoclaw-sandbox-base-local || true)"
if ! glibc_ok "$version"; then
echo "::error::Local sandbox base image has glibc ${version:-unknown}; need >= ${min_glibc}"
exit 1
fi
echo "BASE_IMAGE=nemoclaw-sandbox-base-local" >> "$GITHUB_ENV"
Comment thread
ericksoa marked this conversation as resolved.
8 changes: 6 additions & 2 deletions .github/workflows/base-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ jobs:
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
env:
DOCKER_METADATA_SHORT_SHA_LENGTH: 8
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
type=sha,prefix=,format=short

- name: Validate OpenClaw version input
Expand Down Expand Up @@ -113,10 +115,12 @@ jobs:
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
env:
DOCKER_METADATA_SHORT_SHA_LENGTH: 8
with:
images: ${{ env.REGISTRY }}/nvidia/nemoclaw/hermes-sandbox-base
tags: |
type=raw,value=latest
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
type=sha,prefix=,format=short

- name: Build and push
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/docker-pin-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
#
# Weekly check that the pinned Dockerfile base-image digest is still current.
# Fails with an actionable message when a newer node:22-slim is available.
# Fails with an actionable message when a newer node:22-trixie-slim is available.

name: docker-pin-check

Expand All @@ -28,3 +28,4 @@ jobs:
run: |
bash scripts/update-docker-pin.sh --check
DOCKERFILE=Dockerfile.base bash scripts/update-docker-pin.sh --check
DOCKERFILE=agents/hermes/Dockerfile.base bash scripts/update-docker-pin.sh --check
50 changes: 50 additions & 0 deletions .github/workflows/nightly-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
# Discord + Slack coverage with cross-talk assertions. See issue #1903.
# sandbox-survival-e2e Sandbox survival across gateway restarts (onboard, inference,
# gateway stop/start, verify sandbox + workspace + inference).
# openshell-gateway-upgrade-e2e
# Validates stale Linux Docker-driver OpenShell gateway
# processes are restarted after an OpenShell upgrade.
# hermes-e2e Hermes Agent E2E — install → onboard --agent hermes → health
# probe → live inference. Validates the multi-agent architecture.
# hermes-discord-e2e Hermes Discord onboarding — validates the top-level Hermes
Expand Down Expand Up @@ -58,6 +61,7 @@ on:
messaging-compatible-endpoint-e2e,
kimi-inference-compat-e2e,
token-rotation-e2e, sandbox-survival-e2e,
openshell-gateway-upgrade-e2e,
issue-2478-crash-loop-recovery-e2e, hermes-e2e, hermes-discord-e2e,
hermes-slack-e2e, sandbox-operations-e2e, inference-routing-e2e,
network-policy-e2e, deployment-services-e2e, diagnostics-e2e,
Expand Down Expand Up @@ -1126,6 +1130,45 @@ jobs:
/tmp/nemoclaw-e2e-upgrade-install.log
if-no-files-found: ignore

# ── OpenShell gateway upgrade E2E ────────────────────────────
# Reproduces the old-install upgrade edge case for Linux Docker-driver
# gateways: a healthy gateway process with stale supervisor/runtime env must
# be restarted rather than reused after the current OpenShell install.
openshell-gateway-upgrade-e2e:
if: >-
github.repository == 'NVIDIA/NemoClaw' &&
(github.event_name != 'workflow_dispatch' ||
inputs.jobs == '' ||
contains(format(',{0},', inputs.jobs), ',openshell-gateway-upgrade-e2e,'))
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: "22"

- name: Run OpenShell gateway upgrade E2E test
env:
GITHUB_TOKEN: ${{ github.token }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
run: bash test/e2e/test-openshell-gateway-upgrade.sh

- name: Upload gateway upgrade logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: openshell-gateway-upgrade-logs
path: |
/tmp/nemoclaw-e2e-openshell-gateway-upgrade.log
/tmp/nemoclaw-e2e-openshell-gateway-start.log
/tmp/nemoclaw-e2e-openshell-gateway-process.log
if-no-files-found: ignore

# ── Hermes rebuild upgrade E2E ──────────────────────────────
# Same upgrade scenario as OpenClaw but for Hermes Agent.
rebuild-hermes-e2e:
Expand Down Expand Up @@ -1209,12 +1252,14 @@ jobs:
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
NEMOCLAW_SANDBOX_NAME: "e2e-double-install"
run: bash install.sh --non-interactive --yes-i-accept-third-party-software
- name: Run double onboard E2E test
env:
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
NEMOCLAW_E2E_INSTALL_SANDBOX_NAME: "e2e-double-install"
run: |
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc" 2>/dev/null || true
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
Expand Down Expand Up @@ -1246,12 +1291,14 @@ jobs:
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
NEMOCLAW_SANDBOX_NAME: "e2e-repair-install"
run: bash install.sh --non-interactive --yes-i-accept-third-party-software
- name: Run onboard repair E2E test
env:
NVIDIA_API_KEY: ${{ secrets.NVIDIA_API_KEY }}
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE: "1"
NEMOCLAW_E2E_INSTALL_SANDBOX_NAME: "e2e-repair-install"
run: |
[ -f "$HOME/.bashrc" ] && source "$HOME/.bashrc" 2>/dev/null || true
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
Expand Down Expand Up @@ -1689,6 +1736,7 @@ jobs:
shields-config-e2e,
rebuild-openclaw-e2e,
upgrade-stale-sandbox-e2e,
openshell-gateway-upgrade-e2e,
rebuild-hermes-e2e,
rebuild-hermes-stale-base-e2e,
double-onboard-e2e,
Expand Down Expand Up @@ -1776,6 +1824,7 @@ jobs:
shields-config-e2e,
rebuild-openclaw-e2e,
upgrade-stale-sandbox-e2e,
openshell-gateway-upgrade-e2e,
rebuild-hermes-e2e,
rebuild-hermes-stale-base-e2e,
double-onboard-e2e,
Expand Down Expand Up @@ -1911,6 +1960,7 @@ jobs:
shields-config-e2e,
rebuild-openclaw-e2e,
upgrade-stale-sandbox-e2e,
openshell-gateway-upgrade-e2e,
rebuild-hermes-e2e,
rebuild-hermes-stale-base-e2e,
double-onboard-e2e,
Expand Down
22 changes: 4 additions & 18 deletions .github/workflows/pr-self-hosted.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,8 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Pull base image from GHCR (fall back to local build)
run: |
if docker pull ghcr.io/nvidia/nemoclaw/sandbox-base:latest 2>/dev/null; then
echo "BASE_IMAGE=ghcr.io/nvidia/nemoclaw/sandbox-base:latest" >> "$GITHUB_ENV"
else
echo "::warning::GHCR base image not available, building locally"
docker build -f Dockerfile.base -t nemoclaw-sandbox-base-local .
echo "BASE_IMAGE=nemoclaw-sandbox-base-local" >> "$GITHUB_ENV"
fi
- name: Resolve sandbox base image
uses: ./.github/actions/resolve-sandbox-base-image

- name: Build production image
run: docker build --build-arg BASE_IMAGE=${{ env.BASE_IMAGE }} -t nemoclaw-production .
Expand Down Expand Up @@ -85,15 +78,8 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Pull base image from GHCR (fall back to local build)
run: |
if docker pull ghcr.io/nvidia/nemoclaw/sandbox-base:latest 2>/dev/null; then
echo "BASE_IMAGE=ghcr.io/nvidia/nemoclaw/sandbox-base:latest" >> "$GITHUB_ENV"
else
echo "::warning::GHCR base image not available, building locally"
docker build -f Dockerfile.base -t nemoclaw-sandbox-base-local .
echo "BASE_IMAGE=nemoclaw-sandbox-base-local" >> "$GITHUB_ENV"
fi
- name: Resolve sandbox base image
uses: ./.github/actions/resolve-sandbox-base-image

- name: Build production image on arm64
run: docker build --build-arg BASE_IMAGE=${{ env.BASE_IMAGE }} -t nemoclaw-production-arm64 .
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/wsl-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ jobs:
$script = @'
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
printf '%s\n' \
'Acquire::ForceIPv4 "true";' \
'Acquire::Retries "5";' \
>/etc/apt/apt.conf.d/99github-actions-network
apt-get update
apt-get install -y bash ca-certificates curl git jq lsb-release make python3 python3-pip rsync tar unzip xz-utils
'@
Expand Down
Loading
Loading