From c67647e1f6af8ccaa4bde8b6fd0420db1a868d52 Mon Sep 17 00:00:00 2001 From: Aaron Erickson Date: Thu, 6 Aug 2026 12:50:48 -0700 Subject: [PATCH] ci: move workflows to self-hosted runners --- .../approve-maintainer-pr-workflow-runs.yaml | 2 +- .../workflows/assign-linked-issue-author.yaml | 2 +- .github/workflows/base-image.yaml | 18 +-- .../workflows/candidate-compatibility.yaml | 8 +- .../workflows/cloudflared-update-check.yaml | 2 +- .github/workflows/code-scanning.yaml | 4 +- .../workflows/codebase-growth-guardrails.yaml | 2 +- .github/workflows/commit-lint.yaml | 2 +- .github/workflows/dco-check.yaml | 2 +- .github/workflows/docker-pin-check.yaml | 2 +- .github/workflows/docs-cli-parity-pr.yaml | 2 +- .github/workflows/docs-links-pr.yaml | 2 +- .github/workflows/docs-preview-pr.yaml | 2 +- .github/workflows/docs-publish-public.yaml | 2 +- .github/workflows/docs-publish-staging.yaml | 4 +- .github/workflows/docs-review-receipt.yaml | 2 +- .github/workflows/e2e-main-retry.yaml | 2 +- .github/workflows/e2e.yaml | 146 +++++++++--------- .github/workflows/hosted-runner-recovery.yaml | 2 +- .github/workflows/installer-hash-check.yaml | 2 +- .../label-merged-pr-release-target.yaml | 2 +- .github/workflows/llama-cpp-image-attest.yaml | 4 +- .github/workflows/llama-cpp-image.yaml | 12 +- .github/workflows/macos-e2e.yaml | 2 +- .github/workflows/main.yaml | 20 +-- .github/workflows/managed-images.yaml | 18 +-- .github/workflows/platform-vitest-main.yaml | 6 +- .github/workflows/podman-cpu-proof.yaml | 2 +- .github/workflows/portable-profile-e2e.yaml | 2 +- .github/workflows/pr-limit.yaml | 2 +- .../workflows/pr-merge-conflict-fixer.yaml | 6 +- .github/workflows/pr-review-advisor.yaml | 4 +- .github/workflows/pr-self-hosted.yaml | 2 +- .github/workflows/pr.yaml | 22 +-- .github/workflows/regression-e2e.yaml | 10 +- .github/workflows/release-latest-tag.yaml | 2 +- .github/workflows/release-lkg-brev-image.yaml | 2 +- .../workflows/require-maintainer-edits.yaml | 2 +- .github/workflows/sandbox-images-and-e2e.yaml | 20 +-- .github/workflows/wsl-e2e.yaml | 2 +- 40 files changed, 176 insertions(+), 176 deletions(-) diff --git a/.github/workflows/approve-maintainer-pr-workflow-runs.yaml b/.github/workflows/approve-maintainer-pr-workflow-runs.yaml index defab07c13c..c202cce2206 100644 --- a/.github/workflows/approve-maintainer-pr-workflow-runs.yaml +++ b/.github/workflows/approve-maintainer-pr-workflow-runs.yaml @@ -24,7 +24,7 @@ concurrency: jobs: approve: if: ${{ github.repository == 'NVIDIA/NemoClaw' }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 2 steps: - name: Approve exact-head maintainer workflow runs diff --git a/.github/workflows/assign-linked-issue-author.yaml b/.github/workflows/assign-linked-issue-author.yaml index fb7d6df386b..ae07362e88f 100644 --- a/.github/workflows/assign-linked-issue-author.yaml +++ b/.github/workflows/assign-linked-issue-author.yaml @@ -20,7 +20,7 @@ permissions: jobs: assign-linked-issue-author: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Assign linked issues to PR authors diff --git a/.github/workflows/base-image.yaml b/.github/workflows/base-image.yaml index 247dc6c9ac4..39d2ea982ab 100644 --- a/.github/workflows/base-image.yaml +++ b/.github/workflows/base-image.yaml @@ -103,13 +103,13 @@ jobs: - agent: openclaw arch: amd64 platform: linux/amd64 - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 dockerfile: Dockerfile.base image: nvidia/nemoclaw/sandbox-base - agent: openclaw arch: arm64 platform: linux/arm64 - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 dockerfile: Dockerfile.base image: nvidia/nemoclaw/sandbox-base steps: @@ -222,14 +222,14 @@ jobs: display_name: Hermes arch: amd64 platform: linux/amd64 - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 dockerfile: agents/hermes/Dockerfile.base image: nvidia/nemoclaw/hermes-sandbox-base - agent: hermes display_name: Hermes arch: arm64 platform: linux/arm64 - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 dockerfile: agents/hermes/Dockerfile.base image: nvidia/nemoclaw/hermes-sandbox-base steps: @@ -335,14 +335,14 @@ jobs: display_name: Deep Agents Code arch: amd64 platform: linux/amd64 - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 dockerfile: agents/langchain-deepagents-code/Dockerfile.base image: nvidia/nemoclaw/langchain-deepagents-code-sandbox-base - agent: langchain-deepagents-code display_name: Deep Agents Code arch: arm64 platform: linux/arm64 - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 dockerfile: agents/langchain-deepagents-code/Dockerfile.base image: nvidia/nemoclaw/langchain-deepagents-code-sandbox-base steps: @@ -439,7 +439,7 @@ jobs: name: Build and push Hermes base image if: github.repository == 'NVIDIA/NemoClaw' needs: build-hermes-platforms - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -606,7 +606,7 @@ jobs: name: Build and push Deep Agents Code base image if: github.repository == 'NVIDIA/NemoClaw' needs: build-dcode-platforms - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -775,7 +775,7 @@ jobs: name: Build and push OpenClaw base image if: github.repository == 'NVIDIA/NemoClaw' needs: build-openclaw-platforms - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/candidate-compatibility.yaml b/.github/workflows/candidate-compatibility.yaml index ac1b438de35..305f35cdd3b 100644 --- a/.github/workflows/candidate-compatibility.yaml +++ b/.github/workflows/candidate-compatibility.yaml @@ -31,7 +31,7 @@ concurrency: jobs: resolve: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 outputs: matrix: ${{ steps.plan.outputs.matrix }} @@ -109,7 +109,7 @@ jobs: deterministic: needs: resolve - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 strategy: fail-fast: false @@ -248,7 +248,7 @@ jobs: live: needs: resolve - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 25 steps: - name: Check out trusted compatibility controller @@ -377,7 +377,7 @@ jobs: - resolve - deterministic - live - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 permissions: actions: read diff --git a/.github/workflows/cloudflared-update-check.yaml b/.github/workflows/cloudflared-update-check.yaml index cbb6fbaf1c2..d0898b6977a 100644 --- a/.github/workflows/cloudflared-update-check.yaml +++ b/.github/workflows/cloudflared-update-check.yaml @@ -18,7 +18,7 @@ concurrency: jobs: check-cloudflared: name: Check cloudflared release pin - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/code-scanning.yaml b/.github/workflows/code-scanning.yaml index 9e6770bbe93..2a7168a0d5a 100644 --- a/.github/workflows/code-scanning.yaml +++ b/.github/workflows/code-scanning.yaml @@ -23,7 +23,7 @@ permissions: jobs: codeql: name: CodeQL (${{ matrix.language }}) - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 strategy: fail-fast: false @@ -45,7 +45,7 @@ jobs: shellcheck: name: ShellCheck SARIF - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/codebase-growth-guardrails.yaml b/.github/workflows/codebase-growth-guardrails.yaml index 21fc0ea7df1..2bd71b0c1d2 100644 --- a/.github/workflows/codebase-growth-guardrails.yaml +++ b/.github/workflows/codebase-growth-guardrails.yaml @@ -18,7 +18,7 @@ permissions: jobs: codebase-growth-guardrails: name: codebase-growth-guardrails - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Block newly added JavaScript files diff --git a/.github/workflows/commit-lint.yaml b/.github/workflows/commit-lint.yaml index b7a5d2c483b..92ac1720df5 100644 --- a/.github/workflows/commit-lint.yaml +++ b/.github/workflows/commit-lint.yaml @@ -16,7 +16,7 @@ concurrency: jobs: commit-lint: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Checkout diff --git a/.github/workflows/dco-check.yaml b/.github/workflows/dco-check.yaml index 7eebff250e2..f176f598c36 100644 --- a/.github/workflows/dco-check.yaml +++ b/.github/workflows/dco-check.yaml @@ -16,7 +16,7 @@ concurrency: jobs: dco-check: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 permissions: contents: read diff --git a/.github/workflows/docker-pin-check.yaml b/.github/workflows/docker-pin-check.yaml index e38cf59cbe9..3e42ab46a10 100644 --- a/.github/workflows/docker-pin-check.yaml +++ b/.github/workflows/docker-pin-check.yaml @@ -18,7 +18,7 @@ permissions: jobs: check-pin: if: github.repository == 'NVIDIA/NemoClaw' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Checkout diff --git a/.github/workflows/docs-cli-parity-pr.yaml b/.github/workflows/docs-cli-parity-pr.yaml index 7954e6b8953..9bcd9eecc81 100644 --- a/.github/workflows/docs-cli-parity-pr.yaml +++ b/.github/workflows/docs-cli-parity-pr.yaml @@ -32,7 +32,7 @@ concurrency: jobs: cli-parity: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/docs-links-pr.yaml b/.github/workflows/docs-links-pr.yaml index 3233847fde3..507711a26c0 100644 --- a/.github/workflows/docs-links-pr.yaml +++ b/.github/workflows/docs-links-pr.yaml @@ -17,7 +17,7 @@ permissions: jobs: markdown-links: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Checkout diff --git a/.github/workflows/docs-preview-pr.yaml b/.github/workflows/docs-preview-pr.yaml index e850d9fff56..ff4b50bbfc9 100644 --- a/.github/workflows/docs-preview-pr.yaml +++ b/.github/workflows/docs-preview-pr.yaml @@ -30,7 +30,7 @@ env: jobs: preview: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout repository diff --git a/.github/workflows/docs-publish-public.yaml b/.github/workflows/docs-publish-public.yaml index 1939c11a1da..10374de5ffd 100644 --- a/.github/workflows/docs-publish-public.yaml +++ b/.github/workflows/docs-publish-public.yaml @@ -20,7 +20,7 @@ env: jobs: publish: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 environment: docs-public steps: diff --git a/.github/workflows/docs-publish-staging.yaml b/.github/workflows/docs-publish-staging.yaml index f63a1ce9050..fd74d2669ae 100644 --- a/.github/workflows/docs-publish-staging.yaml +++ b/.github/workflows/docs-publish-staging.yaml @@ -27,7 +27,7 @@ env: jobs: publish: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 environment: docs-staging steps: @@ -58,7 +58,7 @@ jobs: npx --yes "fern-api@${FERN_VERSION}" generate --docs --instance "$FERN_STAGING_INSTANCE" delete-preview: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 needs: publish timeout-minutes: 5 permissions: diff --git a/.github/workflows/docs-review-receipt.yaml b/.github/workflows/docs-review-receipt.yaml index 3f103ea375a..b9a2fcc7732 100644 --- a/.github/workflows/docs-review-receipt.yaml +++ b/.github/workflows/docs-review-receipt.yaml @@ -16,7 +16,7 @@ concurrency: jobs: docs-review-receipt: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 3 steps: - name: Checkout diff --git a/.github/workflows/e2e-main-retry.yaml b/.github/workflows/e2e-main-retry.yaml index a9eaef56f6b..194564b030a 100644 --- a/.github/workflows/e2e-main-retry.yaml +++ b/.github/workflows/e2e-main-retry.yaml @@ -32,7 +32,7 @@ jobs: concurrency: group: e2e-main-retry-${{ github.event.workflow_run.id }} cancel-in-progress: false - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 permissions: actions: write diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 1c0e06319fd..5ba38be34f2 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -96,7 +96,7 @@ env: jobs: base-image-publication: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 55 permissions: actions: read @@ -149,7 +149,7 @@ jobs: generate-matrix: needs: base-image-publication - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 outputs: cli_artifact_provenance: ${{ steps.record_cli_artifact.outputs.provenance }} @@ -170,19 +170,19 @@ jobs: set -euo pipefail case "${JOBS}:${TARGETS}" in :) - matrix='[{"id":"ubuntu-policy-custom-missing-presets-negative","runner":"ubuntu-latest"},{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"ubuntu-latest"},{"id":"ubuntu-repo-cloud-openclaw","runner":"ubuntu-latest"},{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"ubuntu-latest"}]' + matrix='[{"id":"ubuntu-policy-custom-missing-presets-negative","runner":"linux-amd64-cpu4"},{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"linux-amd64-cpu4"},{"id":"ubuntu-repo-cloud-openclaw","runner":"linux-amd64-cpu4"},{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"linux-amd64-cpu4"}]' ;; managed-image-protected-runtime:) matrix='[]' ;; :ubuntu-repo-cloud-langchain-deepagents-code) - matrix='[{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"ubuntu-latest","label":"ubuntu-repo-cloud-langchain-deepagents-code"}]' + matrix='[{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"linux-amd64-cpu4","label":"ubuntu-repo-cloud-langchain-deepagents-code"}]' ;; :ubuntu-repo-docker-post-reboot-recovery) - matrix='[{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"ubuntu-latest","label":"ubuntu-repo-docker-post-reboot-recovery"}]' + matrix='[{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"linux-amd64-cpu4","label":"ubuntu-repo-docker-post-reboot-recovery"}]' ;; :ubuntu-repo-cloud-langchain-deepagents-code,ubuntu-repo-docker-post-reboot-recovery) - matrix='[{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"ubuntu-latest","label":"ubuntu-repo-cloud-langchain-deepagents-code"},{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"ubuntu-latest","label":"ubuntu-repo-docker-post-reboot-recovery"}]' + matrix='[{"id":"ubuntu-repo-cloud-langchain-deepagents-code","runner":"linux-amd64-cpu4","label":"ubuntu-repo-cloud-langchain-deepagents-code"},{"id":"ubuntu-repo-docker-post-reboot-recovery","runner":"linux-amd64-cpu4","label":"ubuntu-repo-docker-post-reboot-recovery"}]' ;; *) echo "::error::PR E2E target is not approved by the trusted controller" >&2 @@ -201,7 +201,7 @@ jobs: shell: bash run: | set -euo pipefail - larger_runner="ubuntu-latest" + larger_runner="linux-amd64-cpu4" if [[ "${REPOSITORY}" == "NVIDIA/NemoClaw" && "${REF}" == "refs/heads/main" && -z "${CHECKOUT_SHA}" && -n "${LARGER_RUNNER_LABEL}" ]]; then if [[ ! "${LARGER_RUNNER_LABEL}" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ ]]; then echo "::error::E2E_LARGER_RUNNER_LABEL must be a 1-64 character workflow label using letters, digits, dots, underscores, or hyphens" >&2 @@ -209,7 +209,7 @@ jobs: fi larger_runner="${LARGER_RUNNER_LABEL}" fi - runner_routing="$(jq -cn --arg standard "ubuntu-latest" --arg larger "${larger_runner}" '{"channels-stop-start-hermes":$larger,"channels-stop-start-openclaw":$standard,"common-egress-agent":$larger,"hermes-discord":$larger,"hermes-e2e":$larger,"hermes-inference-switch":$larger,"hermes-shields-config":$larger,"mcp-bridge-deepagents":$larger,"mcp-bridge-hermes":$larger,"mcp-bridge-openclaw":$standard,"rebuild-hermes":$larger,"rebuild-hermes-stale-base":$larger,"security-posture-hermes":$larger,"security-posture-openclaw":$standard}')" + runner_routing="$(jq -cn --arg standard "linux-amd64-cpu4" --arg larger "${larger_runner}" '{"channels-stop-start-hermes":$larger,"channels-stop-start-openclaw":$standard,"common-egress-agent":$larger,"hermes-discord":$larger,"hermes-e2e":$larger,"hermes-inference-switch":$larger,"hermes-shields-config":$larger,"mcp-bridge-deepagents":$larger,"mcp-bridge-hermes":$larger,"mcp-bridge-openclaw":$standard,"rebuild-hermes":$larger,"rebuild-hermes-stale-base":$larger,"security-posture-hermes":$larger,"security-posture-openclaw":$standard}')" printf 'runner_routing=%s\n' "${runner_routing}" >> "${GITHUB_OUTPUT}" - name: Authenticate manual PR dispatch @@ -607,7 +607,7 @@ jobs: retired-selector-compatibility: needs: generate-matrix if: ${{ inputs.checkout_sha != '' && (contains(format(',{0},', inputs.jobs), ',credential-migration,') || contains(format(',{0},', inputs.jobs), ',credential-sanitization,') || contains(format(',{0},', inputs.jobs), ',diagnostics,') || contains(format(',{0},', inputs.jobs), ',docs-validation,') || contains(format(',{0},', inputs.jobs), ',gateway-drift-preflight,') || contains(format(',{0},', inputs.jobs), ',gateway-health-honest,') || contains(format(',{0},', inputs.jobs), ',onboard-negative-paths,') || contains(format(',{0},', inputs.jobs), ',openshell-version-pin,') || contains(format(',{0},', inputs.jobs), ',sandbox-rebuild,') || contains(format(',{0},', inputs.jobs), ',ubuntu-repo-cli-smoke,') || contains(format(',{0},', inputs.jobs), ',upgrade-stale-sandbox,') || contains(format(',{0},', inputs.targets), ',sandbox-rebuild,') || contains(format(',{0},', inputs.targets), ',upgrade-stale-sandbox,')) }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 env: E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/retired-selector-compatibility @@ -645,7 +645,7 @@ jobs: name: Exact staging Brev Launchable needs: generate-matrix if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.ref == 'refs/heads/main' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && ((inputs.jobs == 'staging-brev-launchable' && inputs.targets == '') || (inputs.include_staging_brev_launchable && inputs.jobs == '' && inputs.targets == '')))) }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 180 permissions: contents: read @@ -937,7 +937,7 @@ jobs: name: Shared E2E (${{ matrix.id }}) needs: generate-matrix if: ${{ needs.generate-matrix.outputs.test_matrix != '[]' }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 strategy: fail-fast: false @@ -986,7 +986,7 @@ jobs: needs: generate-matrix # Run on every main push. Exact manual selection remains available for diagnosis. if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openshell-gateway-auth-contract,') || contains(format(',{0},', inputs.targets), ',openshell-gateway-auth-contract,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 20 env: E2E_JOB: "1" @@ -1386,7 +1386,7 @@ jobs: openshell-credential-generation-window: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',mcp-bridge,') || contains(format(',{0},', inputs.targets), ',mcp-bridge,') || contains(format(',{0},', inputs.jobs), ',openshell-credential-generation-window,') || contains(format(',{0},', inputs.targets), ',openshell-credential-generation-window,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read # Keep the credential-generation lifecycle on a fresh runner so it can @@ -1505,7 +1505,7 @@ jobs: needs: generate-matrix # Run moving OpenShell development artifacts on every main push. if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',mcp-bridge-dev,') || contains(format(',{0},', inputs.targets), ',mcp-bridge-dev,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read timeout-minutes: 90 @@ -1625,7 +1625,7 @@ jobs: skill-agent: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',skill-agent,') || contains(format(',{0},', inputs.targets), ',skill-agent,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 env: E2E_JOB: "1" @@ -1706,7 +1706,7 @@ jobs: openclaw-skill-cli: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-skill-cli,') || contains(format(',{0},', inputs.targets), ',openclaw-skill-cli,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 60 env: E2E_JOB: "1" @@ -1755,7 +1755,7 @@ jobs: inference-routing: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',inference-routing,') || contains(format(',{0},', inputs.targets), ',inference-routing,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -1830,7 +1830,7 @@ jobs: cloud-inference: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',cloud-inference,') || contains(format(',{0},', inputs.targets), ',cloud-inference,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 50 env: E2E_JOB: "1" @@ -1960,10 +1960,10 @@ jobs: matrix: include: - platform: linux/amd64 - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 shard: linux-amd64 - platform: linux/arm64 - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 shard: linux-arm64 env: E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/managed-image-multiarch-startup/${{ matrix.shard }} @@ -2293,7 +2293,7 @@ jobs: name: Compile protected llama.cpp DGX Spark plan needs: generate-matrix if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.ref == 'refs/heads/main' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.jobs == '' && inputs.targets == '') || contains(format(',{0},', inputs.jobs), ',llama-cpp-dgx-spark-qualification,') || contains(format(',{0},', inputs.targets), ',llama-cpp-dgx-spark-qualification,')) }} - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 15 permissions: contents: read @@ -2841,7 +2841,7 @@ jobs: agent-turn-latency: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',agent-turn-latency,') || contains(format(',{0},', inputs.targets), ',agent-turn-latency,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 110 env: E2E_JOB: "1" @@ -2939,7 +2939,7 @@ jobs: kimi-inference-compat: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',kimi-inference-compat,') || contains(format(',{0},', inputs.targets), ',kimi-inference-compat,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 50 env: E2E_JOB: "1" @@ -3089,7 +3089,7 @@ jobs: brave-search: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',brave-search,') || contains(format(',{0},', inputs.targets), ',brave-search,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -3156,7 +3156,7 @@ jobs: ollama-auth-proxy: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',ollama-auth-proxy,') || contains(format(',{0},', inputs.targets), ',ollama-auth-proxy,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -3196,7 +3196,7 @@ jobs: cron-preflight-inference-local: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',cron-preflight-inference-local,') || contains(format(',{0},', inputs.targets), ',cron-preflight-inference-local,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -3262,7 +3262,7 @@ jobs: issue-4434-tui-unreachable-inference: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',issue-4434-tui-unreachable-inference,') || contains(format(',{0},', inputs.targets), ',issue-4434-tui-unreachable-inference,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 120 env: E2E_JOB: "1" @@ -3340,7 +3340,7 @@ jobs: dashboard-remote-bind: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',dashboard-remote-bind,') || contains(format(',{0},', inputs.targets), ',dashboard-remote-bind,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 65 env: E2E_JOB: "1" @@ -3390,7 +3390,7 @@ jobs: sessions-agents-cli: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',sessions-agents-cli,') || contains(format(',{0},', inputs.targets), ',sessions-agents-cli,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 70 env: E2E_JOB: "1" @@ -3928,7 +3928,7 @@ jobs: - name: Run Hermes Discord live test # Preserves the - # ubuntu-latest Docker/OpenShell/Hermes Discord schema, provider, + # linux-amd64-cpu4 Docker/OpenShell/Hermes Discord schema, provider, # placeholder isolation, native gateway rewrite, and rebuild contracts. env: NVIDIA_INFERENCE_API_KEY: ${{ secrets.NVIDIA_INFERENCE_API_KEY }} @@ -3959,7 +3959,7 @@ jobs: name: Network policy (${{ matrix.scenario }}) needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',network-policy,') || contains(format(',{0},', inputs.targets), ',network-policy,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 strategy: fail-fast: false @@ -4170,7 +4170,7 @@ jobs: shields-config: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',shields-config,') || contains(format(',{0},', inputs.targets), ',shields-config,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -4304,7 +4304,7 @@ jobs: rebuild-openclaw: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',rebuild-openclaw,') || contains(format(',{0},', inputs.targets), ',rebuild-openclaw,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 130 env: E2E_JOB: "1" @@ -4615,7 +4615,7 @@ jobs: overlayfs-autofix: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',overlayfs-autofix,') || contains(format(',{0},', inputs.targets), ',overlayfs-autofix,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 env: E2E_JOB: "1" @@ -4667,7 +4667,7 @@ jobs: state-backup-restore: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',state-backup-restore,') || contains(format(',{0},', inputs.targets), ',state-backup-restore,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 60 env: E2E_JOB: "1" @@ -4737,7 +4737,7 @@ jobs: double-onboard: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',double-onboard,') || contains(format(',{0},', inputs.targets), ',double-onboard,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 env: E2E_JOB: "1" @@ -4802,7 +4802,7 @@ jobs: # timeout-minutes only after runner assignment. Maintainers must keep the # configured runner label online. if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.ref == 'refs/heads/main' && ((github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',jetson-nvmap-gpu,') || contains(format(',{0},', inputs.targets), ',jetson-nvmap-gpu,')) }} - runs-on: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '') || inputs.allow_jetson_runner_queue) && (vars.JETSON_E2E_RUNNER_LABEL || 'linux-arm64-gpu-jetson-orin-latest-1') || 'ubuntu-latest' }} + runs-on: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '') || inputs.allow_jetson_runner_queue) && (vars.JETSON_E2E_RUNNER_LABEL || 'linux-arm64-gpu-jetson-orin-latest-1') || 'linux-amd64-cpu4' }} timeout-minutes: 60 env: E2E_JOB: "1" @@ -4880,7 +4880,7 @@ jobs: concurrent-gateway-ports: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',concurrent-gateway-ports,') || contains(format(',{0},', inputs.targets), ',concurrent-gateway-ports,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 env: E2E_JOB: "1" @@ -4942,7 +4942,7 @@ jobs: onboard-resume: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',onboard-resume,') || contains(format(',{0},', inputs.targets), ',onboard-resume,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -5003,7 +5003,7 @@ jobs: full-e2e: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',full-e2e,') || contains(format(',{0},', inputs.targets), ',full-e2e,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 75 env: E2E_JOB: "1" @@ -5173,7 +5173,7 @@ jobs: cloud-onboard: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',cloud-onboard,') || contains(format(',{0},', inputs.targets), ',cloud-onboard,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 70 env: E2E_JOB: "1" @@ -5357,7 +5357,7 @@ jobs: onboard-repair: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',onboard-repair,') || contains(format(',{0},', inputs.targets), ',onboard-repair,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 75 env: E2E_JOB: "1" @@ -5418,7 +5418,7 @@ jobs: issue-4462-scope-upgrade-approval: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',issue-4462-scope-upgrade-approval,') || contains(format(',{0},', inputs.targets), ',issue-4462-scope-upgrade-approval,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 env: E2E_JOB: "1" @@ -5482,7 +5482,7 @@ jobs: token-rotation: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',token-rotation,') || contains(format(',{0},', inputs.targets), ',token-rotation,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -5510,7 +5510,7 @@ jobs: provenance-json: ${{ needs.generate-matrix.outputs.cli_artifact_provenance }} - name: Run token rotation live test - # Preserve the original runner class: ubuntu-latest with Docker/OpenShell + # Preserve the original runner class: linux-amd64-cpu4 with Docker/OpenShell # plus the fake OpenAI-compatible endpoint path and fake # Telegram/Discord/Slack token boundary. env: @@ -5539,7 +5539,7 @@ jobs: messaging-compatible-endpoint: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',messaging-compatible-endpoint,') || contains(format(',{0},', inputs.targets), ',messaging-compatible-endpoint,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -5600,7 +5600,7 @@ jobs: matrix: include: - id: v0.0.36-x86_64 - runner: ubuntu-latest + runner: linux-amd64-cpu4 shard: v0-0-36-x86-64 nemoclaw_ref: v0.0.36 nemoclaw_commit: "3351fbdd4eb7d9b80ec471545083956327da2b10" @@ -5609,7 +5609,7 @@ jobs: openshell_version: 0.0.36 openclaw_version: 2026.4.24 - id: v0.0.55-x86_64 - runner: ubuntu-latest + runner: linux-amd64-cpu4 shard: v0-0-55-x86-64 nemoclaw_ref: v0.0.55 nemoclaw_commit: "95d483fe2b6569d68e59493c60f19df09a068e8f" @@ -5618,7 +5618,7 @@ jobs: openshell_version: 0.0.44 openclaw_version: 2026.5.22 - id: v0.0.55-aarch64 - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 shard: v0-0-55-aarch64 nemoclaw_ref: v0.0.55 nemoclaw_commit: "95d483fe2b6569d68e59493c60f19df09a068e8f" @@ -5627,7 +5627,7 @@ jobs: openshell_version: 0.0.44 openclaw_version: 2026.5.22 - id: v0.0.74-x86_64 - runner: ubuntu-latest + runner: linux-amd64-cpu4 shard: v0-0-74-x86-64 nemoclaw_ref: v0.0.74 nemoclaw_commit: "3a05b54e8ec3e1d5550ec5c728de54af872bffe3" @@ -5636,7 +5636,7 @@ jobs: openshell_version: 0.0.72 openclaw_version: 2026.5.27 - id: v0.0.89-x86_64 - runner: ubuntu-latest + runner: linux-amd64-cpu4 shard: v0-0-89-x86-64 nemoclaw_ref: v0.0.89 nemoclaw_commit: "1143aa5cce77f3bad1b3b5588bd7fddbe438237e" @@ -5711,7 +5711,7 @@ jobs: messaging-providers: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',messaging-providers,') || contains(format(',{0},', inputs.targets), ',messaging-providers,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 90 env: E2E_JOB: "1" @@ -5774,7 +5774,7 @@ jobs: bootstrap-install-smoke: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',bootstrap-install-smoke,') || contains(format(',{0},', inputs.targets), ',bootstrap-install-smoke,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 env: E2E_JOB: "1" @@ -5826,7 +5826,7 @@ jobs: model-router-provider-routed-inference: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',model-router-provider-routed-inference,') || contains(format(',{0},', inputs.targets), ',model-router-provider-routed-inference,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -5876,7 +5876,7 @@ jobs: snapshot-commands: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',snapshot-commands,') || contains(format(',{0},', inputs.targets), ',snapshot-commands,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 40 env: E2E_JOB: "1" @@ -5920,7 +5920,7 @@ jobs: sandbox-operations: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',sandbox-operations,') || contains(format(',{0},', inputs.jobs), ',sandbox-rlimits-connect,') || contains(format(',{0},', inputs.targets), ',sandbox-operations,') || contains(format(',{0},', inputs.targets), ',sandbox-rlimits-connect,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 # The live test receives 45 minutes for two onboards plus process/gateway # recovery. The remaining 15 minutes cover checkout, build, OpenShell setup, # artifact upload, and unconditional credential/resource cleanup. @@ -5992,7 +5992,7 @@ jobs: sandbox-survival: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',sandbox-survival,') || contains(format(',{0},', inputs.targets), ',sandbox-survival,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 env: E2E_JOB: "1" @@ -6049,7 +6049,7 @@ jobs: openclaw-plugin-runtime-exdev-release: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-plugin-runtime-exdev-release,') || contains(format(',{0},', inputs.targets), ',openclaw-plugin-runtime-exdev-release,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read timeout-minutes: 55 @@ -6119,7 +6119,7 @@ jobs: openclaw-plugin-runtime-exdev: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-plugin-runtime-exdev,') || contains(format(',{0},', inputs.targets), ',openclaw-plugin-runtime-exdev,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read # Two bounded 25-minute onboards plus the 20-minute rebuild and 15-minute @@ -6189,7 +6189,7 @@ jobs: openclaw-tui-chat-correlation: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-tui-chat-correlation,') || contains(format(',{0},', inputs.targets), ',openclaw-tui-chat-correlation,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read timeout-minutes: 75 @@ -6273,7 +6273,7 @@ jobs: gateway-guard-recovery: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',gateway-guard-recovery,') || contains(format(',{0},', inputs.targets), ',gateway-guard-recovery,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -6359,7 +6359,7 @@ jobs: openclaw-inference-switch: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-inference-switch,') || contains(format(',{0},', inputs.targets), ',openclaw-inference-switch,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read timeout-minutes: 90 @@ -6432,7 +6432,7 @@ jobs: bedrock-runtime-compatible-anthropic: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',bedrock-runtime-compatible-anthropic,') || contains(format(',{0},', inputs.targets), ',bedrock-runtime-compatible-anthropic,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 60 strategy: fail-fast: false @@ -6513,7 +6513,7 @@ jobs: device-auth-health: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',device-auth-health,') || contains(format(',{0},', inputs.targets), ',device-auth-health,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 40 env: E2E_JOB: "1" @@ -6577,7 +6577,7 @@ jobs: channels-add-remove: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',channels-add-remove,') || contains(format(',{0},', inputs.targets), ',channels-add-remove,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 75 env: E2E_JOB: "1" @@ -6653,7 +6653,7 @@ jobs: telegram-injection: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',telegram-injection,') || contains(format(',{0},', inputs.targets), ',telegram-injection,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -6846,7 +6846,7 @@ jobs: openclaw-slack-pairing: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-slack-pairing,') || contains(format(',{0},', inputs.targets), ',openclaw-slack-pairing,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 60 env: E2E_JOB: "1" @@ -6919,7 +6919,7 @@ jobs: issue-2478-crash-loop-recovery: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',issue-2478-crash-loop-recovery,') || contains(format(',{0},', inputs.targets), ',issue-2478-crash-loop-recovery,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 env: E2E_JOB: "1" @@ -6983,7 +6983,7 @@ jobs: openclaw-discord-pairing: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',openclaw-discord-pairing,') || contains(format(',{0},', inputs.targets), ',openclaw-discord-pairing,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 60 env: E2E_JOB: "1" @@ -7055,7 +7055,7 @@ jobs: tunnel-lifecycle: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',tunnel-lifecycle,') || contains(format(',{0},', inputs.targets), ',tunnel-lifecycle,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 75 env: E2E_JOB: "1" @@ -7138,7 +7138,7 @@ jobs: spark-install: needs: generate-matrix if: ${{ (github.event_name != 'workflow_dispatch' || (inputs.jobs == '' && inputs.targets == '')) || contains(format(',{0},', inputs.jobs), ',spark-install,') || contains(format(',{0},', inputs.targets), ',spark-install,') }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 env: E2E_JOB: "1" @@ -7193,7 +7193,7 @@ jobs: # even when target jobs failed — that's the whole point of a result # comment. report-to-pr: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 # This entire workflow is dispatch-only. Keeping selective jobs in `needs` # makes the report wait for and record any requested job without adding @@ -7334,7 +7334,7 @@ jobs: # ── Push/manual scorecard ───────────────────────────────────────────────── scorecard: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 needs: *e2e-result-jobs if: ${{ always() && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.checkout_sha == '')) }} diff --git a/.github/workflows/hosted-runner-recovery.yaml b/.github/workflows/hosted-runner-recovery.yaml index b7d4500a532..6fb3546c93b 100644 --- a/.github/workflows/hosted-runner-recovery.yaml +++ b/.github/workflows/hosted-runner-recovery.yaml @@ -38,7 +38,7 @@ jobs: group: hosted-runner-recovery-${{ github.event.workflow_run.workflow_id }} queue: max cancel-in-progress: false - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 permissions: actions: write diff --git a/.github/workflows/installer-hash-check.yaml b/.github/workflows/installer-hash-check.yaml index 4265f551413..5c0c5a404ff 100644 --- a/.github/workflows/installer-hash-check.yaml +++ b/.github/workflows/installer-hash-check.yaml @@ -34,7 +34,7 @@ permissions: jobs: check-hash: if: github.repository == 'NVIDIA/NemoClaw' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Set up trusted installer hash parser runtime diff --git a/.github/workflows/label-merged-pr-release-target.yaml b/.github/workflows/label-merged-pr-release-target.yaml index 2cf07d22c49..967753d05cf 100644 --- a/.github/workflows/label-merged-pr-release-target.yaml +++ b/.github/workflows/label-merged-pr-release-target.yaml @@ -31,7 +31,7 @@ concurrency: jobs: label-release-target: if: ${{ github.event_name != 'pull_request_target' || github.event.pull_request.merged == true }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Apply release target to merged PRs diff --git a/.github/workflows/llama-cpp-image-attest.yaml b/.github/workflows/llama-cpp-image-attest.yaml index f893c019d81..1e2b398ce13 100644 --- a/.github/workflows/llama-cpp-image-attest.yaml +++ b/.github/workflows/llama-cpp-image-attest.yaml @@ -32,7 +32,7 @@ permissions: {} jobs: validate-inputs: name: Validate attestation inputs - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 5 permissions: {} outputs: @@ -94,7 +94,7 @@ jobs: attest: name: Generate and publish image evidence needs: validate-inputs - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 30 permissions: attestations: write diff --git a/.github/workflows/llama-cpp-image.yaml b/.github/workflows/llama-cpp-image.yaml index db29766cc3a..c7978f1b317 100644 --- a/.github/workflows/llama-cpp-image.yaml +++ b/.github/workflows/llama-cpp-image.yaml @@ -33,7 +33,7 @@ concurrency: jobs: config: name: Compile declarative image configuration - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 10 outputs: backend_directory: ${{ steps.manifest.outputs.backend_directory }} @@ -240,7 +240,7 @@ jobs: name: Validate trusted publication request needs: config if: github.event_name == 'workflow_dispatch' && inputs.publish == true - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 5 permissions: {} outputs: @@ -314,7 +314,7 @@ jobs: publication-preflight: name: Require public GHCR package needs: [config, publication-gate] - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 5 permissions: packages: read @@ -459,7 +459,7 @@ jobs: assemble-candidate: name: Assemble exact llama.cpp candidate index needs: [config, publication-gate, publish-platform] - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 15 permissions: contents: read @@ -586,7 +586,7 @@ jobs: scan-candidate: name: Scan llama.cpp digest (${{ matrix.arch }}) needs: [config, publication-gate, assemble-candidate] - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 20 permissions: contents: read @@ -664,7 +664,7 @@ jobs: scan-candidate, attest-candidate, ] - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 20 permissions: attestations: read diff --git a/.github/workflows/macos-e2e.yaml b/.github/workflows/macos-e2e.yaml index eaa418396f5..28ff2a6ab96 100644 --- a/.github/workflows/macos-e2e.yaml +++ b/.github/workflows/macos-e2e.yaml @@ -24,7 +24,7 @@ concurrency: jobs: macos-e2e: - runs-on: macos-26 + runs-on: [self-hosted, macOS, ARM64] timeout-minutes: 30 steps: - name: Checkout diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 717a2bad66b..8b9e744a19b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -22,7 +22,7 @@ concurrency: jobs: static-checks: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -34,7 +34,7 @@ jobs: uses: ./.github/actions/ci-static-checks build-typecheck: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -46,7 +46,7 @@ jobs: uses: ./.github/actions/ci-build-typecheck installer-integration: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -58,7 +58,7 @@ jobs: uses: ./.github/actions/ci-installer-integration wechat-runtime-audit: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 steps: - name: Checkout @@ -82,7 +82,7 @@ jobs: retention-days: 14 reviewed-npm-audit: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 steps: - name: Checkout @@ -97,7 +97,7 @@ jobs: report-dir: artifacts/reviewed-npm-audit real-openclaw-dist-harness: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 20 env: # This required proof reads reviewed npm metadata/tarballs. Keep npm's @@ -136,7 +136,7 @@ jobs: run: npx vitest run --project integration test/openclaw-security-audit-suppressions-real.test.ts --silent=false --reporter=default cli-test-shards: - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 15 strategy: fail-fast: false @@ -163,7 +163,7 @@ jobs: code-quality: write contents: read pull-requests: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Verify CLI shards completed @@ -237,7 +237,7 @@ jobs: code-quality: write contents: read pull-requests: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -262,7 +262,7 @@ jobs: if: always() permissions: actions: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 1 steps: - name: Verify required main checks diff --git a/.github/workflows/managed-images.yaml b/.github/workflows/managed-images.yaml index 0ef1b6ad2a2..9117fcd12dc 100644 --- a/.github/workflows/managed-images.yaml +++ b/.github/workflows/managed-images.yaml @@ -51,7 +51,7 @@ jobs: # GitHub's maintainer workflow approval. Exact digest publication is limited # to branches in NVIDIA/NemoClaw; fork jobs never log in or push. if: github.event_name == 'pull_request' - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 90 permissions: contents: read @@ -368,7 +368,7 @@ jobs: name: PR exact all-agent managed runtime activation needs: pr-build-and-entrypoint if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 90 permissions: contents: read @@ -475,7 +475,7 @@ jobs: platform: linux/amd64 artifact_platform: linux-amd64 required_binary: /usr/local/bin/openclaw - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 - agent: openclaw arch: arm64 display_name: OpenClaw @@ -485,7 +485,7 @@ jobs: platform: linux/arm64 artifact_platform: linux-arm64 required_binary: /usr/local/bin/openclaw - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 - agent: hermes arch: amd64 display_name: Hermes @@ -495,7 +495,7 @@ jobs: platform: linux/amd64 artifact_platform: linux-amd64 required_binary: /usr/local/bin/hermes - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 - agent: hermes arch: arm64 display_name: Hermes @@ -505,7 +505,7 @@ jobs: platform: linux/arm64 artifact_platform: linux-arm64 required_binary: /usr/local/bin/hermes - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 - agent: langchain-deepagents-code arch: amd64 display_name: Deep Agents Code @@ -515,7 +515,7 @@ jobs: platform: linux/amd64 artifact_platform: linux-amd64 required_binary: /usr/local/bin/dcode - runner: ubuntu-24.04 + runner: linux-amd64-cpu4 - agent: langchain-deepagents-code arch: arm64 display_name: Deep Agents Code @@ -525,7 +525,7 @@ jobs: platform: linux/arm64 artifact_platform: linux-arm64 required_binary: /usr/local/bin/dcode - runner: ubuntu-24.04-arm + runner: linux-arm64-cpu4 steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1074,7 +1074,7 @@ jobs: promote: name: Promote complete multi-platform managed image cohort needs: build-and-validate - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 30 permissions: contents: read diff --git a/.github/workflows/platform-vitest-main.yaml b/.github/workflows/platform-vitest-main.yaml index f812ebc9dc6..f4216fe76ed 100644 --- a/.github/workflows/platform-vitest-main.yaml +++ b/.github/workflows/platform-vitest-main.yaml @@ -24,7 +24,7 @@ concurrency: jobs: ubuntu-2604-contract: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 container: image: ubuntu:26.04@sha256:b7f48194d4d8b763a478a621cdc81c27be222ba2206ca3ca6bc42b49685f3d9e timeout-minutes: 20 @@ -81,7 +81,7 @@ jobs: test/install-preflight.test.ts macos-vitest: - runs-on: macos-26 + runs-on: [self-hosted, macOS, ARM64] timeout-minutes: 30 strategy: fail-fast: false @@ -158,7 +158,7 @@ jobs: run: npx vitest run --testTimeout 60000 --shard="${{ matrix.shard }}/4" wsl-vitest: - runs-on: windows-latest + runs-on: [self-hosted, Windows, X64] timeout-minutes: 90 strategy: fail-fast: false diff --git a/.github/workflows/podman-cpu-proof.yaml b/.github/workflows/podman-cpu-proof.yaml index 312bace2688..3ef38514973 100644 --- a/.github/workflows/podman-cpu-proof.yaml +++ b/.github/workflows/podman-cpu-proof.yaml @@ -26,7 +26,7 @@ concurrency: jobs: podman-cpu-lifecycle: name: Rootless Podman CPU lifecycle with Docker disabled - runs-on: ubuntu-26.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 30 env: E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/podman-cpu-proof diff --git a/.github/workflows/portable-profile-e2e.yaml b/.github/workflows/portable-profile-e2e.yaml index 488137dd2e1..063572f5a52 100644 --- a/.github/workflows/portable-profile-e2e.yaml +++ b/.github/workflows/portable-profile-e2e.yaml @@ -31,7 +31,7 @@ concurrency: jobs: rootless-linux: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 25 steps: - name: Checkout diff --git a/.github/workflows/pr-limit.yaml b/.github/workflows/pr-limit.yaml index 754893e79b7..fac2ca1e28f 100644 --- a/.github/workflows/pr-limit.yaml +++ b/.github/workflows/pr-limit.yaml @@ -17,7 +17,7 @@ permissions: jobs: check-pr-limit: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Check open PR count for author diff --git a/.github/workflows/pr-merge-conflict-fixer.yaml b/.github/workflows/pr-merge-conflict-fixer.yaml index ac5f236bca9..735dbc1fb0d 100644 --- a/.github/workflows/pr-merge-conflict-fixer.yaml +++ b/.github/workflows/pr-merge-conflict-fixer.yaml @@ -14,7 +14,7 @@ permissions: jobs: scan: name: Scan conflicting PRs - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 permissions: contents: read pull-requests: read @@ -44,7 +44,7 @@ jobs: name: Resolve PR #${{ matrix.item.pr_number }} needs: scan if: ${{ needs.scan.outputs.count != '0' }} - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 30 permissions: contents: read @@ -118,7 +118,7 @@ jobs: - scan - resolve if: ${{ always() && needs.scan.outputs.count != '0' }} - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 permissions: contents: write pull-requests: read diff --git a/.github/workflows/pr-review-advisor.yaml b/.github/workflows/pr-review-advisor.yaml index 92ca3aa33c6..ba3c7ab75c6 100644 --- a/.github/workflows/pr-review-advisor.yaml +++ b/.github/workflows/pr-review-advisor.yaml @@ -59,7 +59,7 @@ jobs: contents: read issues: read pull-requests: read - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 40 continue-on-error: ${{ !matrix.advisor.publish_comment }} strategy: @@ -336,7 +336,7 @@ jobs: permissions: contents: read pull-requests: write - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 10 env: PR_REVIEW_ADVISOR_COMMENT_MARKER: "" diff --git a/.github/workflows/pr-self-hosted.yaml b/.github/workflows/pr-self-hosted.yaml index 43e1af94e7b..294ccc324d5 100644 --- a/.github/workflows/pr-self-hosted.yaml +++ b/.github/workflows/pr-self-hosted.yaml @@ -29,7 +29,7 @@ concurrency: jobs: get-pr-info: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 outputs: pr-info: ${{ steps.get-pr-info.outputs.pr-info }} steps: diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 1c7b93097a8..1a167c31ef1 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -20,7 +20,7 @@ jobs: # Detect which files changed so we can skip expensive jobs for docs-only PRs. changes: if: ${{ github.event.action != 'edited' || github.event.changes.base != null }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 2 permissions: pull-requests: read @@ -46,7 +46,7 @@ jobs: docs-only-checks: needs: changes if: needs.changes.outputs.code != 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -93,7 +93,7 @@ jobs: static-checks: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -123,7 +123,7 @@ jobs: build-typecheck: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -152,7 +152,7 @@ jobs: installer-integration: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -213,7 +213,7 @@ jobs: wechat-runtime-audit: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 steps: - name: Checkout @@ -291,7 +291,7 @@ jobs: reviewed-npm-audit: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 steps: - name: Checkout @@ -376,7 +376,7 @@ jobs: cli-test-shards: needs: changes if: needs.changes.outputs.code == 'true' - runs-on: ubuntu-24.04 + runs-on: linux-amd64-cpu4 timeout-minutes: 15 strategy: fail-fast: false @@ -495,7 +495,7 @@ jobs: code-quality: write contents: read pull-requests: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Verify CLI shards completed @@ -586,7 +586,7 @@ jobs: code-quality: write contents: read pull-requests: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 steps: - name: Checkout @@ -626,7 +626,7 @@ jobs: if: always() permissions: actions: read - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 1 steps: - name: Verify required PR checks diff --git a/.github/workflows/regression-e2e.yaml b/.github/workflows/regression-e2e.yaml index b64670dfb66..45ec4d7b9a7 100644 --- a/.github/workflows/regression-e2e.yaml +++ b/.github/workflows/regression-e2e.yaml @@ -38,7 +38,7 @@ concurrency: jobs: select_regression_jobs: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 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 }} @@ -85,7 +85,7 @@ jobs: if: >- github.repository == 'NVIDIA/NemoClaw' && needs.select_regression_jobs.outputs.model_router_provider_routed_inference == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 permissions: contents: read @@ -125,7 +125,7 @@ jobs: if: >- github.repository == 'NVIDIA/NemoClaw' && needs.select_regression_jobs.outputs.openclaw_plugin_runtime_exdev == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read timeout-minutes: 55 @@ -179,7 +179,7 @@ jobs: if: >- github.repository == 'NVIDIA/NemoClaw' && needs.select_regression_jobs.outputs.openclaw_plugin_runtime_exdev == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 permissions: contents: read # Two bounded 25-minute onboards plus the 20-minute rebuild and 15-minute @@ -237,7 +237,7 @@ jobs: if: >- github.repository == 'NVIDIA/NemoClaw' && needs.select_regression_jobs.outputs.whatsapp_qr_compact == 'true' - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 steps: - name: Checkout diff --git a/.github/workflows/release-latest-tag.yaml b/.github/workflows/release-latest-tag.yaml index b7d81a16e9f..02503ec5520 100644 --- a/.github/workflows/release-latest-tag.yaml +++ b/.github/workflows/release-latest-tag.yaml @@ -27,7 +27,7 @@ concurrency: jobs: update-latest: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 steps: - name: Check out repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/release-lkg-brev-image.yaml b/.github/workflows/release-lkg-brev-image.yaml index d90428f42f6..833797d56d9 100644 --- a/.github/workflows/release-lkg-brev-image.yaml +++ b/.github/workflows/release-lkg-brev-image.yaml @@ -18,7 +18,7 @@ concurrency: jobs: dispatch-production-image: if: ${{ github.repository == 'NVIDIA/NemoClaw' && github.event.deleted == false }} - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 5 steps: - name: Check out LKG target diff --git a/.github/workflows/require-maintainer-edits.yaml b/.github/workflows/require-maintainer-edits.yaml index 8b64675e5b1..d4dd178101c 100644 --- a/.github/workflows/require-maintainer-edits.yaml +++ b/.github/workflows/require-maintainer-edits.yaml @@ -19,7 +19,7 @@ concurrency: jobs: require-maintainer-edits: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 2 steps: - name: Require maintainer edits for fork PRs diff --git a/.github/workflows/sandbox-images-and-e2e.yaml b/.github/workflows/sandbox-images-and-e2e.yaml index 478ae1b8007..7599474c1ca 100644 --- a/.github/workflows/sandbox-images-and-e2e.yaml +++ b/.github/workflows/sandbox-images-and-e2e.yaml @@ -26,7 +26,7 @@ permissions: jobs: build-sandbox-images: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 45 steps: - &checkout @@ -159,7 +159,7 @@ jobs: run: bash .github/scripts/docker-auth-cleanup.sh build-hermes-sandbox-image: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 steps: - *checkout @@ -315,7 +315,7 @@ jobs: run: bash .github/scripts/docker-auth-cleanup.sh test-hermes-sandbox-image: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 needs: build-hermes-sandbox-image timeout-minutes: 90 steps: @@ -401,7 +401,7 @@ jobs: docker system df || true messaging-plan-image-boundary: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 steps: - *checkout @@ -474,7 +474,7 @@ jobs: shell: bash run: bash .github/scripts/docker-auth-cleanup.sh state-dir-guard-metadata: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 30 needs: [build-sandbox-images, build-hermes-sandbox-image] env: @@ -529,7 +529,7 @@ jobs: uses: ./.github/actions/upload-e2e-artifacts build-sandbox-images-arm64: if: inputs.run_arm64 - runs-on: ubuntu-24.04-arm + runs-on: linux-arm64-cpu4 timeout-minutes: 45 steps: - *checkout @@ -588,7 +588,7 @@ jobs: run: bash .github/scripts/docker-auth-cleanup.sh test-e2e-sandbox: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 15 needs: build-sandbox-images steps: @@ -607,7 +607,7 @@ jobs: 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 + runs-on: linux-amd64-cpu4 timeout-minutes: 15 needs: build-sandbox-images steps: @@ -631,7 +631,7 @@ jobs: run: NEMOCLAW_TEST_IMAGE=nemoclaw-production bash test/e2e-gateway-isolation.sh runtime-overrides: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 # The live target owns 45 minutes; retain 15 minutes for setup, image # transfer, and the always-running artifact upload. timeout-minutes: 60 @@ -664,7 +664,7 @@ jobs: uses: ./.github/actions/upload-e2e-artifacts test-e2e-port-overrides: - runs-on: ubuntu-latest + runs-on: linux-amd64-cpu4 timeout-minutes: 10 needs: build-sandbox-images steps: diff --git a/.github/workflows/wsl-e2e.yaml b/.github/workflows/wsl-e2e.yaml index 0a697d8c375..e2e803c061f 100644 --- a/.github/workflows/wsl-e2e.yaml +++ b/.github/workflows/wsl-e2e.yaml @@ -18,7 +18,7 @@ concurrency: jobs: wsl-e2e: - runs-on: windows-latest + runs-on: [self-hosted, Windows, X64] timeout-minutes: 90 env: WSL_DISTRO: Ubuntu