diff --git a/.github/actions/build-vm-driver/action.yml b/.github/actions/build-vm-driver/action.yml new file mode 100644 index 0000000000..7942058d94 --- /dev/null +++ b/.github/actions/build-vm-driver/action.yml @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: Build VM Driver +description: Assemble the compressed VM runtime and build openshell-driver-vm + +inputs: + arch: + description: Guest architecture used to select the Linux sandbox and VM init artifacts + required: true + triple: + description: Rust target triple of the driver + required: true + supervisor-artifact: + description: Artifact containing the openshell-supervisor binary embedded in the runtime + required: true + cargo-version: + description: Cargo package version embedded in the binary + required: true + supervisor-image-tag: + description: Default supervisor image tag embedded in the binary + required: false + default: "" + entitlements-file: + description: Path to an entitlements plist for macOS ad-hoc codesigning + required: false + default: "" +runs: + using: composite + steps: + - name: Download openshell-sandbox + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openshell-sandbox-${{ inputs.arch }}-unknown-linux-musl + path: sandbox + + - name: Download openshell-supervisor + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ inputs.supervisor-artifact }} + path: supervisor + + - name: Download VM guest init + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openshell-vm-init-${{ inputs.arch }}-unknown-linux-musl + path: vm-init + + - name: Build VM runtime + shell: nix develop -c bash -euo pipefail {0} + run: | + # HTTP 416 is not retried by Nix; restart the build once on failure. + nix build .#vm-runtime || nix build .#vm-runtime + + - name: Assemble compressed VM runtime + shell: nix develop -c bash -euo pipefail {0} + run: | + compressed_dir="${RUNNER_TEMP}/vm-runtime-compressed" + install -d "$compressed_dir" + cp result/compressed/*.zst "$compressed_dir/" + zstd -19 -T1 sandbox/openshell-sandbox -o "$compressed_dir/openshell-sandbox.zst" + zstd -19 -T1 supervisor/openshell-supervisor -o "$compressed_dir/openshell-supervisor.zst" + zstd -19 -T1 vm-init/openshell-vm-init -o "$compressed_dir/openshell-vm-init.zst" + + - name: Build openshell-driver-vm + uses: ./.github/actions/build-rust-binary + env: + OPENSHELL_VM_RUNTIME_COMPRESSED_DIR: ${{ runner.temp }}/vm-runtime-compressed + with: + package: openshell-driver-vm + binary: openshell-driver-vm + triple: ${{ inputs.triple }} + cargo-version: ${{ inputs.cargo-version }} + supervisor-image-tag: ${{ inputs.supervisor-image-tag }} + entitlements-file: ${{ inputs.entitlements-file }} diff --git a/.github/workflows/branch-e2e.yml b/.github/workflows/branch-e2e.yml index cc558fb4e2..c9812b410d 100644 --- a/.github/workflows/branch-e2e.yml +++ b/.github/workflows/branch-e2e.yml @@ -101,11 +101,21 @@ jobs: echo "rpm_release=$rpm_release" } >> "$GITHUB_OUTPUT" - build-binaries: + build-binaries-linux: needs: version permissions: contents: read - uses: ./.github/workflows/build-binaries.yml + uses: ./.github/workflows/build-binaries-linux.yml + with: + cargo-version: ${{ needs.version.outputs.cargo }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-binaries-macos: + needs: version + permissions: + contents: read + uses: ./.github/workflows/build-binaries-macos.yml with: cargo-version: ${{ needs.version.outputs.cargo }} secrets: @@ -183,19 +193,30 @@ jobs: triple: ${{ matrix.triple }} cargo-version: ${{ needs.version.outputs.cargo }} - build-vm-driver: - needs: [pr_metadata, version, build-binaries] + build-vm-driver-linux: + needs: [pr_metadata, version, build-binaries-linux] + if: needs.pr_metadata.outputs.run_core_e2e == 'true' + permissions: + contents: read + uses: ./.github/workflows/build-vm-driver-linux.yml + with: + cargo-version: ${{ needs.version.outputs.cargo }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-vm-driver-macos: + needs: [pr_metadata, version, build-binaries-linux, build-binaries-macos] if: needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: contents: read - uses: ./.github/workflows/build-vm-driver.yml + uses: ./.github/workflows/build-vm-driver-macos.yml with: cargo-version: ${{ needs.version.outputs.cargo }} secrets: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} build-images: - needs: [pr_metadata, build-binaries] + needs: [pr_metadata, build-binaries-linux] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_any_e2e == 'true' permissions: contents: read @@ -204,7 +225,7 @@ jobs: build-deb: name: Build Debian packages - needs: [pr_metadata, version, build-binaries, build-vm-driver] + needs: [pr_metadata, version, build-binaries-linux, build-vm-driver-linux] if: needs.pr_metadata.outputs.run_integration == 'true' permissions: contents: read @@ -216,7 +237,7 @@ jobs: build-rpm: name: Build RPM packages - needs: [pr_metadata, version, build-binaries] + needs: [pr_metadata, version, build-binaries-linux] if: needs.pr_metadata.outputs.run_integration == 'true' permissions: actions: read @@ -228,8 +249,48 @@ jobs: rpm-release: ${{ needs.version.outputs.rpm_release }} cargo-version: ${{ needs.version.outputs.cargo }} + # Test inputs don't depend on the packages, so build them while the packages + # build instead of in prepare-integration. + build-tmachine-test-inputs: + name: Build tmachine test inputs + needs: [pr_metadata] + if: needs.pr_metadata.outputs.run_integration == 'true' + permissions: + contents: read + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + ref: ${{ github.sha }} + - uses: ./.github/actions/setup-nix + - name: Build test archives + run: | + # Retry dependency preparation, then generate artifacts once. + nix build --no-link .#build-artifacts-test-archives || nix build --no-link .#build-artifacts-test-archives + nix run .#build-artifacts-test-archives + - name: Build test workload images + run: | + # Retry dependency preparation, then generate artifacts once. + nix build --no-link .#build-artifacts-test-images || nix build --no-link .#build-artifacts-test-images + nix run .#build-artifacts-test-images + - name: Package Helm chart + run: | + # Retry dependency preparation, then generate artifacts once. + nix build --no-link .#build-artifacts-helm || nix build --no-link .#build-artifacts-helm + nix run .#build-artifacts-helm + - name: Upload tmachine test inputs + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: openshell-tmachine-test-inputs + path: artifacts + compression-level: 0 + retention-days: 5 + if-no-files-found: error + prepare-integration: - needs: [pr_metadata, build-binaries, build-images, build-deb, build-rpm] + needs: [pr_metadata, build-binaries-linux, build-images, build-deb, build-rpm, build-tmachine-test-inputs] if: needs.pr_metadata.outputs.run_integration == 'true' permissions: actions: read @@ -239,6 +300,7 @@ jobs: with: deb-artifact-name: deb-linux-amd64 rpm-artifact-name: rpm-linux-x86_64 + test-inputs-artifact-name: openshell-tmachine-test-inputs # Run driver-independent conformance tests. conformance-integration: @@ -306,7 +368,7 @@ jobs: ] docker-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -318,7 +380,7 @@ jobs: runner: linux-arm64-cpu8 podman-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -331,7 +393,7 @@ jobs: [{"suite":"ci","runner":"ubuntu-26.04","podman_major":"5","podman_package_version":"5.7.0+ds2-3build1","conmon_package_version":"2.1.13+ds1-2","cmd":"mise run --no-deps --skip-deps e2e:podman:ci"}] podman-additional-ca-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -344,7 +406,7 @@ jobs: [{"suite":"additional-ca","runner":"ubuntu-26.04","podman_major":"5","podman_package_version":"5.7.0+ds2-3build1","conmon_package_version":"2.1.13+ds1-2","cmd":"OPENSHELL_E2E_PODMAN_TEST=additional_ca mise run --no-deps --skip-deps e2e:podman"}] vm-e2e: - needs: [pr_metadata, build-binaries, build-vm-driver] + needs: [pr_metadata, build-binaries-linux, build-vm-driver-linux] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -353,7 +415,7 @@ jobs: uses: ./.github/workflows/e2e-vm-test.yml vm-additional-ca-e2e: - needs: [pr_metadata, build-binaries, build-vm-driver] + needs: [pr_metadata, build-binaries-linux, build-vm-driver-linux] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -365,7 +427,7 @@ jobs: test-name: additional_ca docker-external-driver-e2e: - needs: [pr_metadata, build-binaries, build-gateway-plain, build-external-drivers, build-images] + needs: [pr_metadata, build-binaries-linux, build-gateway-plain, build-external-drivers, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -381,7 +443,7 @@ jobs: [{"suite":"external-driver","cmd":"mise run --no-deps --skip-deps e2e:docker:external-driver","apt_packages":"openssh-client","python_proto":false,"mcp":false}] podman-external-driver-e2e: - needs: [pr_metadata, build-binaries, build-gateway-plain, build-external-drivers, build-images] + needs: [pr_metadata, build-binaries-linux, build-gateway-plain, build-external-drivers, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -396,7 +458,7 @@ jobs: [{"suite":"external-driver","runner":"ubuntu-26.04","podman_major":"5","podman_package_version":"5.7.0+ds2-3build1","conmon_package_version":"2.1.13+ds1-2","cmd":"mise run --no-deps --skip-deps e2e:podman:external-driver"}] vm-external-driver-e2e: - needs: [pr_metadata, build-binaries, build-gateway-plain, build-vm-driver] + needs: [pr_metadata, build-binaries-linux, build-gateway-plain, build-vm-driver-linux] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -409,7 +471,7 @@ jobs: e2e-task: e2e:vm:external-driver gpu-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_gpu_e2e == 'true' permissions: actions: read @@ -420,7 +482,7 @@ jobs: image-tag: ${{ github.sha }} kubernetes-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' strategy: fail-fast: false @@ -450,7 +512,7 @@ jobs: test-name: ${{ matrix.test_name }} kubernetes-app-listener-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' strategy: fail-fast: false @@ -487,7 +549,7 @@ jobs: listener-takeover: ${{ matrix.takeover }} kubernetes-workspace-managed-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -500,7 +562,7 @@ jobs: e2e-task: e2e:kubernetes:workspace-managed kubernetes-external-driver-e2e: - needs: [pr_metadata, build-binaries, build-gateway-plain, build-external-drivers, build-images] + needs: [pr_metadata, build-binaries-linux, build-gateway-plain, build-external-drivers, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -516,7 +578,7 @@ jobs: cluster-images: sandbox supervisor kubernetes-workspace-operator-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true' permissions: actions: read @@ -529,7 +591,7 @@ jobs: e2e-task: e2e:kubernetes:workspace-operator kubernetes-ha-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true' permissions: actions: read @@ -546,7 +608,7 @@ jobs: use-envoy-gateway: true kubernetes-credential-drivers-e2e: - needs: [pr_metadata, build-binaries, build-images] + needs: [pr_metadata, build-binaries-linux, build-images] if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true' permissions: actions: read @@ -562,6 +624,8 @@ jobs: name: Core E2E result needs: - pr_metadata + - build-binaries-macos + - build-vm-driver-macos - conformance-integration - feature-specific-integration - driver-specific-integration @@ -591,7 +655,7 @@ jobs: gpu-e2e-result: name: GPU E2E result - needs: [pr_metadata, gpu-e2e] + needs: [pr_metadata, build-binaries-macos, gpu-e2e] if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_gpu_e2e == 'true' runs-on: ubuntu-latest steps: @@ -604,7 +668,7 @@ jobs: kubernetes-ha-e2e-result: name: Kubernetes HA E2E result - needs: [pr_metadata, kubernetes-ha-e2e] + needs: [pr_metadata, build-binaries-macos, kubernetes-ha-e2e] if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true' runs-on: ubuntu-latest steps: @@ -617,7 +681,7 @@ jobs: kubernetes-credential-drivers-e2e-result: name: Kubernetes Credential Drivers E2E result - needs: [pr_metadata, kubernetes-credential-drivers-e2e] + needs: [pr_metadata, build-binaries-macos, kubernetes-credential-drivers-e2e] if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries-linux.yml similarity index 90% rename from .github/workflows/build-binaries.yml rename to .github/workflows/build-binaries-linux.yml index 1289968d14..1adf9be0e2 100644 --- a/.github/workflows/build-binaries.yml +++ b/.github/workflows/build-binaries-linux.yml @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -name: Build Binaries +name: Build Linux Binaries on: workflow_call: @@ -40,8 +40,6 @@ jobs: runner: linux-amd64-cpu8 - triple: aarch64-unknown-linux-musl runner: linux-arm64-cpu8 - - triple: aarch64-apple-darwin - runner: macos-15-xlarge runs-on: ${{ matrix.runner }} timeout-minutes: 60 steps: &build_steps @@ -74,8 +72,6 @@ jobs: runner: linux-amd64-cpu8 - triple: aarch64-unknown-linux-musl runner: linux-arm64-cpu8 - - triple: aarch64-apple-darwin - runner: macos-15-xlarge runs-on: ${{ matrix.runner }} timeout-minutes: 60 steps: *build_steps @@ -92,8 +88,6 @@ jobs: runner: linux-amd64-cpu8 - triple: aarch64-unknown-linux-gnu runner: linux-arm64-cpu8 - - triple: aarch64-apple-darwin - runner: macos-15-xlarge runs-on: ${{ matrix.runner }} timeout-minutes: 60 steps: *build_steps @@ -122,10 +116,6 @@ jobs: binary: openshell-supervisor triple: aarch64-unknown-linux-gnu runner: linux-arm64-cpu8 - - package: openshell-supervisor - binary: openshell-supervisor - triple: aarch64-apple-darwin - runner: macos-15-xlarge runs-on: ${{ matrix.runner }} timeout-minutes: 60 steps: *build_steps diff --git a/.github/workflows/build-binaries-macos.yml b/.github/workflows/build-binaries-macos.yml new file mode 100644 index 0000000000..e5f7d09648 --- /dev/null +++ b/.github/workflows/build-binaries-macos.yml @@ -0,0 +1,63 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: Build macOS Binaries + +on: + workflow_call: + inputs: + cargo-version: + required: true + type: string + supervisor-image-tag: + required: false + type: string + default: "" + checkout-ref: + required: false + type: string + default: "" + secrets: + CACHIX_AUTH_TOKEN: + required: true + +permissions: + contents: read + +jobs: + build: + name: ${{ matrix.binary }} (${{ matrix.triple }}) + strategy: + fail-fast: false + matrix: + include: + - package: openshell-cli + binary: openshell + triple: aarch64-apple-darwin + - package: openshell-prover-cli + binary: openshell-prover + triple: aarch64-apple-darwin + - package: openshell-gateway + binary: openshell-gateway + triple: aarch64-apple-darwin + - package: openshell-supervisor + binary: openshell-supervisor + triple: aarch64-apple-darwin + runs-on: macos-15-xlarge + timeout-minutes: 60 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + ref: ${{ inputs.checkout-ref || github.sha }} + - uses: ./.github/actions/setup-nix + with: + prepare-shell: "true" + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: ./.github/actions/build-rust-binary + with: + package: ${{ matrix.package }} + binary: ${{ matrix.binary }} + triple: ${{ matrix.triple }} + cargo-version: ${{ inputs.cargo-version }} + supervisor-image-tag: ${{ inputs.supervisor-image-tag }} diff --git a/.github/workflows/build-vm-driver-linux.yml b/.github/workflows/build-vm-driver-linux.yml new file mode 100644 index 0000000000..e6676d5b2a --- /dev/null +++ b/.github/workflows/build-vm-driver-linux.yml @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: Build Linux VM Driver + +on: + workflow_call: + inputs: + cargo-version: + required: true + type: string + supervisor-image-tag: + required: false + type: string + default: "" + checkout-ref: + required: false + type: string + default: "" + secrets: + CACHIX_AUTH_TOKEN: + required: true + +permissions: + contents: read + +jobs: + build: + name: openshell-driver-vm (${{ matrix.triple }}) + strategy: + matrix: + include: + - arch: x86_64 + triple: x86_64-unknown-linux-gnu + runner: linux-amd64-cpu8 + - arch: aarch64 + triple: aarch64-unknown-linux-gnu + runner: linux-arm64-cpu8 + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + ref: ${{ inputs['checkout-ref'] || github.sha }} + + - uses: ./.github/actions/setup-nix + with: + prepare-shell: "true" + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - uses: ./.github/actions/build-vm-driver + with: + arch: ${{ matrix.arch }} + triple: ${{ matrix.triple }} + supervisor-artifact: openshell-supervisor-${{ matrix.arch }}-unknown-linux-gnu + cargo-version: ${{ inputs['cargo-version'] }} + supervisor-image-tag: ${{ inputs['supervisor-image-tag'] }} diff --git a/.github/workflows/build-vm-driver-macos.yml b/.github/workflows/build-vm-driver-macos.yml new file mode 100644 index 0000000000..ad2cfba13c --- /dev/null +++ b/.github/workflows/build-vm-driver-macos.yml @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: Build macOS VM Driver + +on: + workflow_call: + inputs: + cargo-version: + required: true + type: string + supervisor-image-tag: + required: false + type: string + default: "" + checkout-ref: + required: false + type: string + default: "" + secrets: + CACHIX_AUTH_TOKEN: + required: true + +permissions: + contents: read + +jobs: + build: + name: openshell-driver-vm (${{ matrix.triple }}) + strategy: + matrix: + include: + - arch: aarch64 + triple: aarch64-apple-darwin + runs-on: macos-15-xlarge + timeout-minutes: 60 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + ref: ${{ inputs['checkout-ref'] || github.sha }} + + - uses: ./.github/actions/setup-nix + with: + prepare-shell: "true" + cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - uses: ./.github/actions/build-vm-driver + with: + arch: ${{ matrix.arch }} + triple: ${{ matrix.triple }} + supervisor-artifact: openshell-supervisor-${{ matrix.arch }}-apple-darwin + cargo-version: ${{ inputs['cargo-version'] }} + supervisor-image-tag: ${{ inputs['supervisor-image-tag'] }} + entitlements-file: crates/openshell-driver-vm/entitlements.plist diff --git a/.github/workflows/build-vm-driver.yml b/.github/workflows/build-vm-driver.yml deleted file mode 100644 index a93f6928da..0000000000 --- a/.github/workflows/build-vm-driver.yml +++ /dev/null @@ -1,113 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -name: Build VM Driver - -on: - workflow_call: - inputs: - cargo-version: - required: true - type: string - supervisor-image-tag: - required: false - type: string - default: "" - checkout-ref: - required: false - type: string - default: "" - secrets: - CACHIX_AUTH_TOKEN: - required: true - -permissions: - contents: read - -jobs: - build: - name: openshell-driver-vm (${{ matrix.triple }}) - strategy: - matrix: - include: - - arch: x86_64 - triple: x86_64-unknown-linux-gnu - runner: linux-amd64-cpu8 - - arch: aarch64 - triple: aarch64-unknown-linux-gnu - runner: linux-arm64-cpu8 - - arch: aarch64 - triple: aarch64-apple-darwin - runner: macos-15-xlarge - entitlements-file: crates/openshell-driver-vm/entitlements.plist - runs-on: ${{ matrix.runner }} - timeout-minutes: 60 - defaults: - run: - shell: nix develop -c bash -euo pipefail {0} - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - ref: ${{ inputs['checkout-ref'] || github.sha }} - - - uses: ./.github/actions/setup-nix - with: - prepare-shell: "true" - cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} - - - name: Download openshell-sandbox - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: openshell-sandbox-${{ matrix.arch }}-unknown-linux-musl - path: sandbox - - - name: Download openshell-supervisor - if: endsWith(matrix.triple, '-unknown-linux-gnu') - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: openshell-supervisor-${{ matrix.arch }}-unknown-linux-gnu - path: supervisor - - - name: Download native macOS host supervisor - if: endsWith(matrix.triple, '-apple-darwin') - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: openshell-supervisor-aarch64-apple-darwin - path: host-supervisor - - - name: Download VM guest init - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: openshell-vm-init-${{ matrix.arch }}-unknown-linux-musl - path: vm-init - - - name: Build VM runtime - run: | - # HTTP 416 is not retried by Nix; restart the build once on failure. - nix build .#vm-runtime || nix build .#vm-runtime - - - name: Assemble compressed VM runtime - run: | - compressed_dir="${RUNNER_TEMP}/vm-runtime-compressed" - host_supervisor="supervisor/openshell-supervisor" - if [[ "${{ matrix.triple }}" == *-apple-darwin ]]; then - host_supervisor="host-supervisor/openshell-supervisor" - fi - install -d "$compressed_dir" - cp result/compressed/*.zst "$compressed_dir/" - zstd -19 -T1 sandbox/openshell-sandbox -o "$compressed_dir/openshell-sandbox.zst" - zstd -19 -T1 "$host_supervisor" -o "$compressed_dir/openshell-supervisor.zst" - zstd -19 -T1 vm-init/openshell-vm-init -o "$compressed_dir/openshell-vm-init.zst" - - - name: Build openshell-driver-vm - uses: ./.github/actions/build-rust-binary - env: - OPENSHELL_VM_RUNTIME_COMPRESSED_DIR: ${{ runner.temp }}/vm-runtime-compressed - with: - package: openshell-driver-vm - binary: openshell-driver-vm - triple: ${{ matrix.triple }} - cargo-version: ${{ inputs['cargo-version'] }} - supervisor-image-tag: ${{ inputs['supervisor-image-tag'] }} - entitlements-file: ${{ matrix.entitlements-file }} diff --git a/.github/workflows/prepare-integration-inputs.yml b/.github/workflows/prepare-integration-inputs.yml index 7b2bf62ab1..9a8784285e 100644 --- a/.github/workflows/prepare-integration-inputs.yml +++ b/.github/workflows/prepare-integration-inputs.yml @@ -26,6 +26,11 @@ on: required: false type: string default: "" + test-inputs-artifact-name: + description: Prebuilt test archives, test workload images, and Helm chart; built here when empty + required: false + type: string + default: "" outputs: source_sha: description: Source revision of the candidate artifacts @@ -66,6 +71,7 @@ jobs: persist-credentials: false - uses: ./.github/actions/setup-nix + if: inputs['test-inputs-artifact-name'] == '' - name: Download CLI artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -151,19 +157,31 @@ jobs: docker tag "ghcr.io/nvidia/openshell/supervisor:${IMAGE_TAG}" openshell/supervisor:tmachine docker save --output artifacts/images/openshell-supervisor-tmachine.tar openshell/supervisor:tmachine + - name: Download test inputs + if: inputs['test-inputs-artifact-name'] != '' + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ inputs['test-inputs-artifact-name'] }} + path: artifacts + github-token: ${{ github.token }} + run-id: ${{ inputs['artifact-run-id'] || github.run_id }} + - name: Build test archives + if: inputs['test-inputs-artifact-name'] == '' run: | # Retry dependency preparation, then generate artifacts once. nix build --no-link .#build-artifacts-test-archives || nix build --no-link .#build-artifacts-test-archives nix run .#build-artifacts-test-archives - name: Build test workload images + if: inputs['test-inputs-artifact-name'] == '' run: | # Retry dependency preparation, then generate artifacts once. nix build --no-link .#build-artifacts-test-images || nix build --no-link .#build-artifacts-test-images nix run .#build-artifacts-test-images - name: Package Helm chart + if: inputs['test-inputs-artifact-name'] == '' run: | # Retry dependency preparation, then generate artifacts once. nix build --no-link .#build-artifacts-helm || nix build --no-link .#build-artifacts-helm diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index c85d29d2fc..2ffc73b2ce 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -116,11 +116,11 @@ jobs: echo "source_sha=$(git rev-parse HEAD)" } >> "$GITHUB_OUTPUT" - build-binaries: + build-binaries-linux: needs: compute-versions permissions: contents: read - uses: ./.github/workflows/build-binaries.yml + uses: ./.github/workflows/build-binaries-linux.yml with: cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} supervisor-image-tag: ${{ needs.compute-versions.outputs.semver }} @@ -128,11 +128,35 @@ jobs: secrets: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} - build-vm-driver: - needs: [compute-versions, build-binaries] + build-binaries-macos: + needs: compute-versions + permissions: + contents: read + uses: ./.github/workflows/build-binaries-macos.yml + with: + cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} + supervisor-image-tag: ${{ needs.compute-versions.outputs.semver }} + checkout-ref: ${{ needs.compute-versions.outputs.source_sha }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-vm-driver-linux: + needs: [compute-versions, build-binaries-linux] + permissions: + contents: read + uses: ./.github/workflows/build-vm-driver-linux.yml + with: + cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} + supervisor-image-tag: ${{ needs.compute-versions.outputs.semver }} + checkout-ref: ${{ needs.compute-versions.outputs.source_sha }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-vm-driver-macos: + needs: [compute-versions, build-binaries-linux, build-binaries-macos] permissions: contents: read - uses: ./.github/workflows/build-vm-driver.yml + uses: ./.github/workflows/build-vm-driver-macos.yml with: cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} supervisor-image-tag: ${{ needs.compute-versions.outputs.semver }} @@ -141,7 +165,7 @@ jobs: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} package-binaries: - needs: [compute-versions, build-binaries, build-vm-driver] + needs: [compute-versions, build-binaries-linux, build-binaries-macos, build-vm-driver-linux, build-vm-driver-macos] permissions: actions: read contents: read @@ -150,7 +174,7 @@ jobs: checkout-ref: ${{ needs.compute-versions.outputs.source_sha }} build-images: - needs: [compute-versions, build-binaries] + needs: [compute-versions, build-binaries-linux, build-binaries-macos] permissions: contents: read packages: write @@ -202,7 +226,7 @@ jobs: build-deb: name: Build Debian Packages - needs: [compute-versions, build-binaries, build-vm-driver] + needs: [compute-versions, build-binaries-linux, build-binaries-macos, build-vm-driver-linux, build-vm-driver-macos] uses: ./.github/workflows/deb-package.yml with: deb-version: ${{ needs.compute-versions.outputs.deb_version }} @@ -210,14 +234,14 @@ jobs: build-snap: name: Build Snap - needs: [compute-versions, build-binaries] + needs: [compute-versions, build-binaries-linux, build-binaries-macos] uses: ./.github/workflows/snap-package.yml with: checkout-ref: ${{ needs.compute-versions.outputs.source_sha }} build-rpm: name: Build RPM Packages - needs: [compute-versions, build-binaries] + needs: [compute-versions, build-binaries-linux, build-binaries-macos] uses: ./.github/workflows/rpm-package.yml with: checkout-ref: ${{ needs.compute-versions.outputs.source_sha }} diff --git a/.github/workflows/release-dev.yml b/.github/workflows/release-dev.yml index 71db45ffb1..1e77854af3 100644 --- a/.github/workflows/release-dev.yml +++ b/.github/workflows/release-dev.yml @@ -59,11 +59,11 @@ jobs: echo "rpm_release=$(uv run python tasks/scripts/release.py get-version --dev --rpm-release)" } >> "$GITHUB_OUTPUT" - build-binaries: + build-binaries-linux: needs: compute-versions permissions: contents: read - uses: ./.github/workflows/build-binaries.yml + uses: ./.github/workflows/build-binaries-linux.yml with: cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} supervisor-image-tag: dev @@ -71,11 +71,35 @@ jobs: secrets: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} - build-vm-driver: - needs: [compute-versions, build-binaries] + build-binaries-macos: + needs: compute-versions + permissions: + contents: read + uses: ./.github/workflows/build-binaries-macos.yml + with: + cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} + supervisor-image-tag: dev + checkout-ref: ${{ github.sha }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-vm-driver-linux: + needs: [compute-versions, build-binaries-linux] + permissions: + contents: read + uses: ./.github/workflows/build-vm-driver-linux.yml + with: + cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} + supervisor-image-tag: dev + checkout-ref: ${{ github.sha }} + secrets: + CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} + + build-vm-driver-macos: + needs: [compute-versions, build-binaries-linux, build-binaries-macos] permissions: contents: read - uses: ./.github/workflows/build-vm-driver.yml + uses: ./.github/workflows/build-vm-driver-macos.yml with: cargo-version: ${{ needs.compute-versions.outputs.cargo_version }} supervisor-image-tag: dev @@ -84,7 +108,7 @@ jobs: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} package-binaries: - needs: [build-binaries, build-vm-driver] + needs: [build-binaries-linux, build-binaries-macos, build-vm-driver-linux, build-vm-driver-macos] permissions: actions: read contents: read @@ -93,7 +117,7 @@ jobs: checkout-ref: ${{ github.sha }} build-images: - needs: build-binaries + needs: [build-binaries-linux, build-binaries-macos] permissions: contents: read packages: write @@ -102,7 +126,7 @@ jobs: checkout-ref: ${{ github.sha }} prepare-integration: - needs: [build-binaries, build-deb, build-images, build-rpm] + needs: [build-binaries-linux, build-binaries-macos, build-deb, build-images, build-rpm] permissions: actions: read contents: read @@ -141,7 +165,7 @@ jobs: CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }} docker-e2e: - needs: [build-binaries, build-images] + needs: [build-binaries-linux, build-binaries-macos, build-images] permissions: actions: read contents: read @@ -153,7 +177,7 @@ jobs: runner: linux-arm64-cpu8 vm-e2e: - needs: [build-binaries, build-vm-driver] + needs: [build-binaries-linux, build-binaries-macos, build-vm-driver-linux, build-vm-driver-macos] permissions: actions: read contents: read @@ -227,7 +251,7 @@ jobs: build-deb: name: Build Debian Packages - needs: [compute-versions, build-binaries, build-vm-driver] + needs: [compute-versions, build-binaries-linux, build-binaries-macos, build-vm-driver-linux, build-vm-driver-macos] uses: ./.github/workflows/deb-package.yml with: deb-version: ${{ needs.compute-versions.outputs.deb_version }} @@ -235,14 +259,14 @@ jobs: build-snap: name: Build snap - needs: [compute-versions, build-binaries] + needs: [compute-versions, build-binaries-linux, build-binaries-macos] uses: ./.github/workflows/snap-package.yml with: checkout-ref: ${{ github.sha }} build-rpm: name: Build RPM Packages - needs: [compute-versions, build-binaries] + needs: [compute-versions, build-binaries-linux, build-binaries-macos] uses: ./.github/workflows/rpm-package.yml with: checkout-ref: ${{ github.sha }} diff --git a/CI.md b/CI.md index e9384acf15..43b6bca3ae 100644 --- a/CI.md +++ b/CI.md @@ -690,7 +690,7 @@ The bot's full administrator documentation is internal to NVIDIA. The only comma |---|---| | `.github/workflows/branch-checks.yml` | Required non-E2E checks. Triggers on `push: pull-request/[0-9]+` for PR mirrors and `merge_group` for queued merges. | | `.github/workflows/branch-e2e.yml` | Standard, GPU, Kubernetes HA, and Kubernetes credential-driver E2E. PR mirror pushes use `test:e2e`, `test:e2e-gpu`, and `test:e2e-kubernetes` labels; merge groups do not run E2E. | -| `.github/workflows/build-binaries.yml`, `build-vm-driver.yml` | Shared binary matrices used by branch and release workflows. The VM driver remains separate because its build consumes the runtime binaries. | +| `.github/workflows/build-binaries-{linux,macos}.yml`, `build-vm-driver-{linux,macos}.yml` | Shared per-platform binary matrices used by branch and release workflows. Each platform is its own workflow, so a consumer depends only on the platforms it needs. The VM driver remains separate because its build consumes the runtime binaries; both platforms share the steps in `.github/actions/build-vm-driver`. | | `.github/workflows/build-images.yml` | Builds and pushes multi-platform images, then uploads the same OCI images as workflow artifacts. | | `.github/workflows/package-release-binaries.yml` | Packages raw build artifacts into release tarballs without rebuilding them. | | `.github/workflows/e2e-docker-test.yml`, `e2e-podman-test.yml`, `e2e-vm-test.yml`, `e2e-kubernetes-test.yml` | Reusable runtime lanes called directly by branch and release workflows. Callers select suites and declare only the artifacts each runtime consumes. |