Skip to content

fix(security): log egress endpoints before applying policy presets #1755

fix(security): log egress endpoints before applying policy presets

fix(security): log egress endpoints before applying policy presets #1755

Workflow file for this run

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
name: pr
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: npm
- name: Install hadolint
run: |
HADOLINT_URL="https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64"
curl -fsSL -o /usr/local/bin/hadolint "$HADOLINT_URL"
EXPECTED=$(curl -fsSL "${HADOLINT_URL}.sha256" | awk '{print $1}')
ACTUAL=$(sha256sum /usr/local/bin/hadolint | awk '{print $1}')
[ "$EXPECTED" = "$ACTUAL" ] || { echo "::error::hadolint checksum mismatch"; exit 1; }
chmod +x /usr/local/bin/hadolint
- name: Install dependencies
run: |
npm install --ignore-scripts
cd nemoclaw && npm install
- name: Build TypeScript plugin
run: cd nemoclaw && npm run build
- name: Run all hooks (pre-commit + pre-push)
run: npx prek run --all-files --stage pre-push
test-unit:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "22"
cache: npm
- name: Install dependencies
run: |
npm install --ignore-scripts
cd nemoclaw && npm install
- name: Build TypeScript plugin
run: cd nemoclaw && npm run build
- name: Run all unit tests with coverage
run: npx vitest run --coverage
- name: Check coverage ratchet
run: bash scripts/check-coverage-ratchet.sh
build-sandbox-images:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@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: Build production image
run: docker build --build-arg BASE_IMAGE=${{ env.BASE_IMAGE }} -t nemoclaw-production .
- name: Build sandbox test image (fixtures layered on production)
run: docker build -f test/Dockerfile.sandbox --build-arg BASE_IMAGE=nemoclaw-production -t nemoclaw-sandbox-test .
- name: Save images to tarballs
run: |
docker save nemoclaw-sandbox-test | gzip > /tmp/sandbox-test-image.tar.gz
docker save nemoclaw-production | gzip > /tmp/isolation-image.tar.gz
- name: Upload sandbox test image
uses: actions/upload-artifact@v4
with:
name: sandbox-test-image
path: /tmp/sandbox-test-image.tar.gz
retention-days: 1
- name: Upload isolation image
uses: actions/upload-artifact@v4
with:
name: isolation-image
path: /tmp/isolation-image.tar.gz
retention-days: 1
build-sandbox-images-arm64:
runs-on: ubuntu-24.04-arm
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@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: Build production image on arm64
run: docker build --build-arg BASE_IMAGE=${{ env.BASE_IMAGE }} -t nemoclaw-production-arm64 .
- name: Build sandbox test image on arm64
run: docker build -f test/Dockerfile.sandbox --build-arg BASE_IMAGE=nemoclaw-production-arm64 -t nemoclaw-sandbox-test-arm64 .
test-e2e-sandbox:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: build-sandbox-images
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download image artifact
uses: actions/download-artifact@v4
with:
name: sandbox-test-image
path: /tmp
- name: Load image
run: gunzip -c /tmp/sandbox-test-image.tar.gz | docker load
- name: Run sandbox E2E tests
run: docker run --rm -v "${{ github.workspace }}/test:/opt/test" nemoclaw-sandbox-test /opt/test/e2e-test.sh
test-e2e-gateway-isolation:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: build-sandbox-images
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Download image artifact
uses: actions/download-artifact@v4
with:
name: isolation-image
path: /tmp
- name: Load image
run: gunzip -c /tmp/isolation-image.tar.gz | docker load
- name: Run gateway isolation E2E tests
run: NEMOCLAW_TEST_IMAGE=nemoclaw-production bash test/e2e-gateway-isolation.sh