From 555cbb0dbbdd6d3cdab49f32e52dc2d7f5303eb8 Mon Sep 17 00:00:00 2001 From: Nick DiZazzo Date: Mon, 29 Jun 2026 18:38:11 -0400 Subject: [PATCH 1/3] PR comments --- .github/actions/compute-changes/action.yml | 35 ++++++++ .github/workflows/ci.yml | 95 ++++++++++++++++++---- tools/xtask/src/main.rs | 8 +- 3 files changed, 123 insertions(+), 15 deletions(-) diff --git a/.github/actions/compute-changes/action.yml b/.github/actions/compute-changes/action.yml index 6a6c3bf040..029b782321 100644 --- a/.github/actions/compute-changes/action.yml +++ b/.github/actions/compute-changes/action.yml @@ -69,6 +69,9 @@ outputs: sdk_smoke_required: description: 'Boolean: true if SDK smoke tests should run as soon as a binary is ready' value: ${{ steps.derive.outputs.sdk_smoke_required }} + linux_test_groups_json: + description: 'JSON array of Linux test groups to run' + value: ${{ steps.derive.outputs.linux_test_groups_json }} runs: using: composite @@ -319,6 +322,37 @@ runs: INFERENCE_ARTIFACT_REQUIRED="true" fi + LINUX_TEST_GROUPS_JSON='[]' + add_linux_test_group() { + local group="$1" + local cache_key="$2" + LINUX_TEST_GROUPS_JSON=$(jq -c --arg group "$group" --arg cache_key "$cache_key" '. + [{group: $group, cache_key: $cache_key}]' <<<"$LINUX_TEST_GROUPS_JSON") + } + + if [[ "${{ inputs.event_name }}" == "workflow_dispatch" ]] || [[ "$ALL_RUST" == "true" ]]; then + add_linux_test_group sdk-api linux-tests-sdk-api + add_linux_test_group skippy linux-tests-skippy + add_linux_test_group unit linux-tests-unit + add_linux_test_group protocol linux-tests-protocol + add_linux_test_group skippy-smoke linux-tests-skippy-smoke + else + if echo "$AFFECTED_CRATES" | jq -e 'index("mesh-llm-client") or index("mesh-llm-api-client") or index("mesh-llm-api-server") or index("mesh-llm-config") or index("mesh-llm-commands") or index("mesh-llm-events") or index("mesh-llm-hardware-profile") or index("mesh-llm-runtime-install") or index("mesh-llm-native-runtime") or index("mesh-llm-routing") or index("mesh-llm-types") or index("mesh-llm-sdk") or index("mesh-llm-cli") or index("mesh-llm-tui") or index("mesh-llm-embedded-runtime") or index("mesh-llm-console-server") or index("mesh-llm-ffi") or index("mesh-llm-nodejs")' >/dev/null; then + add_linux_test_group sdk-api linux-tests-sdk-api + fi + if echo "$AFFECTED_CRATES" | jq -e 'index("skippy-protocol") or index("skippy-server") or index("openai-frontend") or index("skippy-runtime") or index("skippy-topology") or index("skippy-model-package") or index("skippy-prompt") or index("metrics-server")' >/dev/null; then + add_linux_test_group skippy linux-tests-skippy + fi + if echo "$AFFECTED_CRATES" | jq -e 'index("model-artifact") or index("mesh-llm-host-runtime") or index("mesh-llm")' >/dev/null; then + add_linux_test_group unit linux-tests-unit + fi + if echo "$AFFECTED_CRATES" | jq -e 'index("mesh-llm") or index("mesh-llm-protocol")' >/dev/null; then + add_linux_test_group protocol linux-tests-protocol + fi + if [[ "$INFERENCE_ARTIFACT_REQUIRED" == "true" ]]; then + add_linux_test_group skippy-smoke linux-tests-skippy-smoke + fi + fi + # Set outputs using GITHUB_OUTPUT { echo "changed_files<> "$GITHUB_OUTPUT" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c9832e499..030080d243 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,9 @@ env: SCCACHE_GHA_ENABLED: "true" LLAMA_STAGE_BUILD_DIR: .deps/llama.cpp/build-stage-abi-static +permissions: + contents: read + jobs: changes: runs-on: ubuntu-24.04 @@ -37,6 +40,7 @@ jobs: affected_crates: ${{ steps.compute.outputs.affected_crates }} test_crates: ${{ steps.compute.outputs.test_crates }} batches_json: ${{ steps.compute.outputs.batches_json }} + linux_test_groups_json: ${{ steps.compute.outputs.linux_test_groups_json }} all_rust: ${{ steps.compute.outputs.all_rust }} docs_only: ${{ steps.compute.outputs.docs_only }} rust_changed: ${{ steps.compute.outputs.rust_changed }} @@ -49,6 +53,7 @@ jobs: steps: - uses: actions/checkout@v5 with: + persist-credentials: false fetch-depth: 0 - uses: dorny/paths-filter@v4 id: filter @@ -161,6 +166,8 @@ jobs: if: ${{ needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.docs_only != 'true' }} name: Linux CPU runs-on: ubuntu-24.04 + permissions: + contents: read container: image: ubuntu:22.04 defaults: @@ -174,6 +181,8 @@ jobs: RUSTC_WRAPPER: sccache steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - uses: pnpm/action-setup@v4 if: ${{ github.event_name == 'workflow_dispatch' || needs.changes.outputs.ui == 'true' }} @@ -226,6 +235,21 @@ jobs: - uses: mozilla-actions/sccache-action@v0.0.9 + - name: Disable missing sccache wrapper + run: | + if command -v sccache >/dev/null 2>&1; then + sccache --version + exit 0 + fi + + echo "::warning::sccache is not available in this Linux CPU container; running without Rust compiler cache" + { + echo "MESH_LLM_REQUIRE_SCCACHE=0" + echo "RUSTC_WRAPPER=" + echo "LLAMA_STAGE_USE_SCCACHE=0" + echo "SKIPPY_USE_SCCACHE=0" + } >> "$GITHUB_ENV" + - uses: Swatinem/rust-cache@v2 continue-on-error: true with: @@ -285,6 +309,11 @@ jobs: - name: Show sccache stats if: ${{ always() }} run: | + if ! command -v sccache >/dev/null 2>&1; then + echo "sccache not available; stats skipped" + exit 0 + fi + sccache --show-stats || true requests="$(sccache --show-stats 2>/dev/null | awk '/Compile requests/ { print $3; exit }')" if [ "${requests:-0}" = "0" ]; then @@ -293,9 +322,11 @@ jobs: linux_test_groups: needs: [changes, linux_cpu_artifact] - if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.linux_inference_artifact_required == 'true' }} + if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.linux_test_groups_json != '[]' }} name: Linux tests (${{ matrix.group }}) runs-on: ubuntu-24.04 + permissions: + contents: read container: image: ubuntu:22.04 defaults: @@ -304,17 +335,7 @@ jobs: strategy: fail-fast: false matrix: - include: - - group: sdk-api - cache_key: linux-tests-sdk-api - - group: skippy - cache_key: linux-tests-skippy - - group: unit - cache_key: linux-tests-unit - - group: protocol - cache_key: linux-tests-protocol - - group: skippy-smoke - cache_key: linux-tests-skippy-smoke + include: ${{ fromJson(needs.changes.outputs.linux_test_groups_json) }} env: AFFECTED: ${{ needs.changes.outputs.affected_crates }} ALL_RUST: ${{ needs.changes.outputs.all_rust }} @@ -325,6 +346,8 @@ jobs: RUSTC_WRAPPER: sccache steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - name: Install Linux test dependencies run: | @@ -402,14 +425,14 @@ jobs: ${{ env.CACHE_NAMESPACE }}-${{ runner.os }}-skippy-ci-smoke-models- - name: SDK and API crate tests - if: ${{ matrix.group == 'sdk-api' && (needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-client') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-api-client') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-api-server') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-config') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-commands') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-events') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-hardware-profile') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-runtime-install') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-sdk') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-cli') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-tui') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-embedded-runtime') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-console-server') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-ffi') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-nodejs')) }} + if: ${{ matrix.group == 'sdk-api' && (needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-client') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-api-client') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-api-server') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-config') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-commands') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-events') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-hardware-profile') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-runtime-install') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-native-runtime') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-routing') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-types') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-sdk') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-cli') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-tui') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-embedded-runtime') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-console-server') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-ffi') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-nodejs')) }} run: | should_test() { local crate="$1" [ "$ALL_RUST" = "true" ] || jq -e --arg crate "$crate" 'index($crate) != null' <<<"$AFFECTED" >/dev/null } - for c in mesh-llm-client mesh-llm-api-client mesh-llm-api-server mesh-llm-config mesh-llm-commands mesh-llm-events mesh-llm-hardware-profile mesh-llm-runtime-install mesh-llm-cli mesh-llm-tui mesh-llm-embedded-runtime mesh-llm-sdk mesh-llm-console-server mesh-llm-ffi mesh-llm-nodejs; do + for c in mesh-llm-client mesh-llm-api-client mesh-llm-api-server mesh-llm-config mesh-llm-commands mesh-llm-events mesh-llm-hardware-profile mesh-llm-runtime-install mesh-llm-native-runtime mesh-llm-routing mesh-llm-types mesh-llm-cli mesh-llm-tui mesh-llm-embedded-runtime mesh-llm-sdk mesh-llm-console-server mesh-llm-ffi mesh-llm-nodejs; do if should_test "$c"; then cargo test -p "$c" else @@ -503,8 +526,12 @@ jobs: if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.docs_only != 'true' }} name: Linux client-auto boot test runs-on: ubuntu-24.04 + permissions: + contents: read steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - name: Install client-auto smoke dependencies run: sudo apt-get update && sudo apt-get install -y curl jq python3 - uses: actions/download-artifact@v6 @@ -520,6 +547,8 @@ jobs: needs: changes if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'model-artifact')) && needs.changes.outputs.docs_only != 'true' }} name: HuggingFace download smoke + permissions: + contents: read uses: ./.github/workflows/hf-download-smoke.yml with: timeout_minutes: 15 @@ -529,6 +558,8 @@ jobs: inference_smoke_tests: needs: [changes, linux_cpu_artifact] if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.linux_inference_artifact_required == 'true' && (github.event_name == 'workflow_dispatch' || needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'skippy-server') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'skippy-runtime') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'openai-frontend') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'model-artifact')) && needs.changes.outputs.docs_only != 'true' }} + permissions: + contents: read uses: ./.github/workflows/smoke.yml with: artifact_name: ci-linux-inference-binaries @@ -541,6 +572,8 @@ jobs: needs: [changes, linux_cpu_artifact] if: ${{ needs.linux_cpu_artifact.result == 'success' && (vars.MESH_AGENT_BASE_URL != '' || vars.MESH_OPENCODE_BASE_URL != '') && (github.event_name == 'workflow_dispatch' || needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'openai-frontend') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-client')) && needs.changes.outputs.docs_only != 'true' }} runs-on: ubuntu-24.04 + permissions: + contents: read timeout-minutes: 45 env: MESH_AGENT_BASE_URL: ${{ vars.MESH_AGENT_BASE_URL || vars.MESH_OPENCODE_BASE_URL }} @@ -556,6 +589,8 @@ jobs: # Keep live-agent smoke on an explicit Node version so CI does not depend # on GitHub-hosted image defaults. - uses: actions/checkout@v4 + with: + persist-credentials: false - uses: actions/setup-node@v4 with: node-version: 24 @@ -586,6 +621,8 @@ jobs: two_node_client_serving_smoke: needs: [changes, linux_cpu_artifact] if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.linux_inference_artifact_required == 'true' && (github.event_name == 'workflow_dispatch' || needs.changes.outputs.all_rust == 'true' || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'openai-frontend') || contains(fromJson(needs.changes.outputs.affected_crates || '[]'), 'mesh-llm-client')) && needs.changes.outputs.docs_only != 'true' }} + permissions: + contents: read uses: ./.github/workflows/scripted-binary-smoke.yml with: artifact_name: ci-linux-inference-binaries @@ -600,6 +637,8 @@ jobs: rust_sdk_smoke: needs: [changes, linux_cpu_artifact] if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.sdk_smoke_required == 'true' && needs.changes.outputs.docs_only != 'true' }} + permissions: + contents: read uses: ./.github/workflows/sdk-smoke.yml with: sdk_kind: rust @@ -614,6 +653,8 @@ jobs: kotlin_sdk_smoke: needs: [changes, linux_cpu_artifact] if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.sdk_smoke_required == 'true' && needs.changes.outputs.docs_only != 'true' }} + permissions: + contents: read uses: ./.github/workflows/sdk-smoke.yml with: sdk_kind: kotlin @@ -628,6 +669,8 @@ jobs: swift_sdk_smoke: needs: [changes, macos] if: ${{ needs.macos.result == 'success' && (github.event_name == 'workflow_dispatch' || needs.changes.outputs.sdk == 'true') && needs.changes.outputs.docs_only != 'true' }} + permissions: + contents: read uses: ./.github/workflows/sdk-smoke.yml with: sdk_kind: swift @@ -644,11 +687,15 @@ jobs: needs: changes if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.rust == 'true' || needs.changes.outputs.ui == 'true' || needs.changes.outputs.benchmarks == 'true') && needs.changes.outputs.docs_only != 'true' }} runs-on: macos-latest + permissions: + contents: read env: LLAMA_STAGE_BACKEND: metal LLAMA_STAGE_BUILD_DIR: .deps/llama.cpp/build-stage-abi-metal steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - uses: pnpm/action-setup@v4 if: ${{ github.event_name == 'workflow_dispatch' || needs.changes.outputs.ui == 'true' }} with: @@ -761,6 +808,8 @@ jobs: if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.backend_changed == 'true' || needs.changes.outputs.benchmarks == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Linux CUDA slim runs-on: [self-hosted, Linux, X64, carrack] + permissions: + contents: read container: image: nvidia/cuda:${{ vars.CUDA_VERSION || '12.6.3' }}-devel-ubuntu22.04 env: @@ -783,6 +832,8 @@ jobs: done rm -rf /var/lib/apt/lists/* - uses: actions/checkout@v5 + with: + persist-credentials: false - uses: dtolnay/rust-toolchain@stable - name: Configure Linux Rust linker run: | @@ -819,6 +870,8 @@ jobs: if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.backend_changed == 'true' || needs.changes.outputs.benchmarks == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Linux ROCm slim runs-on: ubuntu-24.04 + permissions: + contents: read container: image: rocm/dev-ubuntu-24.04:7.0-complete env: @@ -840,6 +893,8 @@ jobs: done rm -rf /var/lib/apt/lists/* - uses: actions/checkout@v5 + with: + persist-credentials: false - uses: dtolnay/rust-toolchain@stable - name: Configure Linux Rust linker run: | @@ -872,12 +927,16 @@ jobs: if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.backend_changed == 'true' || needs.changes.outputs.benchmarks == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Linux Vulkan runs-on: ubuntu-24.04 + permissions: + contents: read env: LLAMA_STAGE_BACKEND: vulkan LLAMA_STAGE_BUILD_DIR: .deps/llama-build/build-stage-abi-vulkan MESH_LLM_SKIP_UI: "1" steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - name: Install Vulkan build packages run: sudo apt-get update && sudo apt-get install -y build-essential cmake ninja-build pkg-config libssl-dev libdbus-1-dev glslc libvulkan-dev spirv-headers lld - uses: dtolnay/rust-toolchain@stable @@ -920,6 +979,8 @@ jobs: if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.rust == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Windows CPU runs-on: windows-2022 + permissions: + contents: read env: RUN_WINDOWS_CPU_FULL: ${{ github.event_name == 'workflow_dispatch' || needs.changes.outputs.windows_cpu == 'true' }} LLAMA_STAGE_BACKEND: cpu @@ -929,6 +990,8 @@ jobs: RUSTC_WRAPPER: sccache steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - name: Use fast Windows CPU check if: ${{ env.RUN_WINDOWS_CPU_FULL != 'true' }} shell: pwsh @@ -991,6 +1054,8 @@ jobs: if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.rust == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Windows ${{ matrix.name }} runs-on: windows-2022 + permissions: + contents: read env: RUN_WINDOWS_GPU: ${{ github.event_name == 'workflow_dispatch' || needs.changes.outputs.windows_gpu == 'true' }} LLAMA_STAGE_BUILD_DIR: .deps/llama.cpp/build-stage-abi-${{ matrix.backend }} @@ -1022,6 +1087,8 @@ jobs: run: Write-Host "Skipping Windows ${{ matrix.name }} because this change does not touch Windows GPU build inputs." - uses: actions/checkout@v5 if: ${{ env.RUN_WINDOWS_GPU == 'true' }} + with: + persist-credentials: false - uses: dtolnay/rust-toolchain@stable if: ${{ env.RUN_WINDOWS_GPU == 'true' }} - uses: taiki-e/install-action@just diff --git a/tools/xtask/src/main.rs b/tools/xtask/src/main.rs index d3de806f1d..4119c1ed9b 100644 --- a/tools/xtask/src/main.rs +++ b/tools/xtask/src/main.rs @@ -1861,6 +1861,12 @@ fn check_ci_crate_test_coverage(ci_workflow: &str) -> DynResult<()> { "mesh-llm-runtime-install", "mesh LLM runtime install crate tests", ), + ( + "mesh-llm-native-runtime", + "mesh LLM native runtime crate tests", + ), + ("mesh-llm-routing", "mesh LLM routing crate tests"), + ("mesh-llm-types", "mesh LLM shared types crate tests"), ("mesh-llm-cli", "mesh LLM CLI crate tests"), ("mesh-llm-tui", "mesh LLM TUI crate tests"), ( @@ -1892,7 +1898,7 @@ fn check_ci_crate_test_coverage(ci_workflow: &str) -> DynResult<()> { )?; ensure_contains( ci_workflow, - "for c in mesh-llm-client mesh-llm-api-client mesh-llm-api-server mesh-llm-config mesh-llm-commands mesh-llm-events mesh-llm-hardware-profile mesh-llm-runtime-install mesh-llm-cli mesh-llm-tui mesh-llm-embedded-runtime mesh-llm-sdk mesh-llm-console-server mesh-llm-ffi mesh-llm-nodejs; do", + "for c in mesh-llm-client mesh-llm-api-client mesh-llm-api-server mesh-llm-config mesh-llm-commands mesh-llm-events mesh-llm-hardware-profile mesh-llm-runtime-install mesh-llm-native-runtime mesh-llm-routing mesh-llm-types mesh-llm-cli mesh-llm-tui mesh-llm-embedded-runtime mesh-llm-sdk mesh-llm-console-server mesh-llm-ffi mesh-llm-nodejs; do", "CI SDK/API crate test loop", )?; ensure_contains( From 9d477844b600f8ccc7150dd2574599a4971aa700 Mon Sep 17 00:00:00 2001 From: Nick DiZazzo Date: Mon, 29 Jun 2026 18:55:37 -0400 Subject: [PATCH 2/3] use labels instead of runner name --- .github/actionlint.yaml | 3 ++- .github/workflows/ci.yml | 2 +- .github/workflows/pr_builds.yml | 2 +- .github/workflows/release.yml | 9 +++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index ad18e1c85a..39ca8ebf70 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -4,7 +4,8 @@ self-hosted-runner: - Linux - X64 - ARM64 - - carrack + - amd64 + - gpu-nvidia - blacksmith-4vcpu-ubuntu-2404 - blacksmith-6vcpu-macos-15 - blacksmith-4vcpu-ubuntu-2404-arm diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 030080d243..51acb4771a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -807,7 +807,7 @@ jobs: needs: changes if: ${{ (github.event_name == 'workflow_dispatch' || needs.changes.outputs.backend_changed == 'true' || needs.changes.outputs.benchmarks == 'true') && needs.changes.outputs.docs_only != 'true' }} name: Linux CUDA slim - runs-on: [self-hosted, Linux, X64, carrack] + runs-on: [self-hosted, Linux, X64, amd64, gpu-nvidia] permissions: contents: read container: diff --git a/.github/workflows/pr_builds.yml b/.github/workflows/pr_builds.yml index 044858f2ec..39d9850360 100644 --- a/.github/workflows/pr_builds.yml +++ b/.github/workflows/pr_builds.yml @@ -294,7 +294,7 @@ jobs: backend: cuda container: nvidia/cuda:${{ vars.CUDA_VERSION || '12.6.3' }}-devel-ubuntu22.04 cache_key: linux-cuda-slim - runs_on: '["self-hosted","Linux","X64","carrack"]' + runs_on: '["self-hosted","Linux","X64","amd64","gpu-nvidia"]' - name: ROCm slim backend: rocm container: rocm/dev-ubuntu-24.04:7.2.3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68ce3c74f3..291c2f1a10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -388,10 +388,11 @@ jobs: name: Build native runtime Linux x86_64 CUDA (${{ matrix.cuda_major }}) needs: metadata if: ${{ needs.metadata.outputs.skip_gpu_bundles != 'true' }} - # Carrack is the dedicated Linux x64 NVIDIA host. Keep ARM64 artifact + # Carrack is the dedicated Linux x64 NVIDIA host. Match it by labels, not + # runner name. Keep ARM64 artifact # compilation on GitHub-hosted ARM runners; CM-class ARM64 runners are # smoke/test-only below. - runs-on: [self-hosted, Linux, X64, carrack] + runs-on: [self-hosted, Linux, X64, amd64, gpu-nvidia] strategy: fail-fast: false matrix: @@ -807,8 +808,8 @@ jobs: needs: metadata if: ${{ needs.metadata.outputs.skip_gpu_bundles != 'true' }} # CUDA release bundles are the release long pole and benefit most from the - # dedicated Linux x64 NVIDIA carrack runner. - runs-on: [self-hosted, Linux, X64, carrack] + # dedicated Linux x64 NVIDIA host. + runs-on: [self-hosted, Linux, X64, amd64, gpu-nvidia] strategy: fail-fast: false matrix: From 34d5e6d3d409d67783b667e5bb55e9f9954c32f7 Mon Sep 17 00:00:00 2001 From: Nick DiZazzo Date: Mon, 29 Jun 2026 19:08:37 -0400 Subject: [PATCH 3/3] small fixup for linux gating --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51acb4771a..7d198b2537 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -321,8 +321,8 @@ jobs: fi linux_test_groups: - needs: [changes, linux_cpu_artifact] - if: ${{ needs.linux_cpu_artifact.result == 'success' && needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.linux_inference_artifact_required == 'true' && needs.changes.outputs.linux_test_groups_json != '[]' }} + needs: changes + if: ${{ needs.changes.outputs.docs_only != 'true' && needs.changes.outputs.linux_test_groups_json != '[]' }} name: Linux tests (${{ matrix.group }}) runs-on: ubuntu-24.04 permissions: