Skip to content

Commit cd8ff12

Browse files
ci(e2e): split binary builds into per-platform workflows
Branch E2E used flags on the shared build workflows to keep Linux and macOS apart. Make each platform its own reusable workflow instead, with a plain matrix, so a consumer depends only on the platforms it needs and adding a platform means adding a workflow rather than another flag. Move the VM driver build steps shared by both platforms into a composite action. Release workflows call both platforms and keep their existing gating. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
1 parent b49f7e0 commit cd8ff12

10 files changed

Lines changed: 353 additions & 237 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: Build VM Driver
5+
description: Assemble the compressed VM runtime and build openshell-driver-vm
6+
7+
inputs:
8+
arch:
9+
description: Guest architecture used to select the Linux sandbox and VM init artifacts
10+
required: true
11+
triple:
12+
description: Rust target triple of the driver
13+
required: true
14+
supervisor-artifact:
15+
description: Artifact containing the openshell-supervisor binary embedded in the runtime
16+
required: true
17+
cargo-version:
18+
description: Cargo package version embedded in the binary
19+
required: true
20+
supervisor-image-tag:
21+
description: Default supervisor image tag embedded in the binary
22+
required: false
23+
default: ""
24+
entitlements-file:
25+
description: Path to an entitlements plist for macOS ad-hoc codesigning
26+
required: false
27+
default: ""
28+
runs:
29+
using: composite
30+
steps:
31+
- name: Download openshell-sandbox
32+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
33+
with:
34+
name: openshell-sandbox-${{ inputs.arch }}-unknown-linux-musl
35+
path: sandbox
36+
37+
- name: Download openshell-supervisor
38+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
39+
with:
40+
name: ${{ inputs.supervisor-artifact }}
41+
path: supervisor
42+
43+
- name: Download VM guest init
44+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
45+
with:
46+
name: openshell-vm-init-${{ inputs.arch }}-unknown-linux-musl
47+
path: vm-init
48+
49+
- name: Build VM runtime
50+
shell: nix develop -c bash -euo pipefail {0}
51+
run: |
52+
# HTTP 416 is not retried by Nix; restart the build once on failure.
53+
nix build .#vm-runtime || nix build .#vm-runtime
54+
55+
- name: Assemble compressed VM runtime
56+
shell: nix develop -c bash -euo pipefail {0}
57+
run: |
58+
compressed_dir="${RUNNER_TEMP}/vm-runtime-compressed"
59+
install -d "$compressed_dir"
60+
cp result/compressed/*.zst "$compressed_dir/"
61+
zstd -19 -T1 sandbox/openshell-sandbox -o "$compressed_dir/openshell-sandbox.zst"
62+
zstd -19 -T1 supervisor/openshell-supervisor -o "$compressed_dir/openshell-supervisor.zst"
63+
zstd -19 -T1 vm-init/openshell-vm-init -o "$compressed_dir/openshell-vm-init.zst"
64+
65+
- name: Build openshell-driver-vm
66+
uses: ./.github/actions/build-rust-binary
67+
env:
68+
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR: ${{ runner.temp }}/vm-runtime-compressed
69+
with:
70+
package: openshell-driver-vm
71+
binary: openshell-driver-vm
72+
triple: ${{ inputs.triple }}
73+
cargo-version: ${{ inputs.cargo-version }}
74+
supervisor-image-tag: ${{ inputs.supervisor-image-tag }}
75+
entitlements-file: ${{ inputs.entitlements-file }}

‎.github/workflows/branch-e2e.yml‎

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -101,27 +101,23 @@ jobs:
101101
echo "rpm_release=$rpm_release"
102102
} >> "$GITHUB_OUTPUT"
103103
104-
build-binaries:
104+
build-binaries-linux:
105105
needs: version
106106
permissions:
107107
contents: read
108-
uses: ./.github/workflows/build-binaries.yml
108+
uses: ./.github/workflows/build-binaries-linux.yml
109109
with:
110110
cargo-version: ${{ needs.version.outputs.cargo }}
111-
macos: false
112111
secrets:
113112
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
114113

115-
# macOS runners can queue for a long time. A separate call lets Linux
116-
# consumers start as soon as the Linux binaries are ready.
117114
build-binaries-macos:
118115
needs: version
119116
permissions:
120117
contents: read
121-
uses: ./.github/workflows/build-binaries.yml
118+
uses: ./.github/workflows/build-binaries-macos.yml
122119
with:
123120
cargo-version: ${{ needs.version.outputs.cargo }}
124-
linux: false
125121
secrets:
126122
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
127123

@@ -160,7 +156,7 @@ jobs:
160156

161157
# The conformance program, built once per architecture for the host lanes.
162158
# It lives in its own workspace and is not released, so it is not part of
163-
# build-binaries.yml.
159+
# build-binaries-linux.yml.
164160
build-conformance:
165161
name: openshell-conformance (${{ matrix.triple }})
166162
needs: [pr_metadata]
@@ -251,32 +247,30 @@ jobs:
251247
triple: ${{ matrix.triple }}
252248
cargo-version: ${{ needs.version.outputs.cargo }}
253249

254-
build-vm-driver:
255-
needs: [pr_metadata, version, build-binaries]
250+
build-vm-driver-linux:
251+
needs: [pr_metadata, version, build-binaries-linux]
256252
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
257253
permissions:
258254
contents: read
259-
uses: ./.github/workflows/build-vm-driver.yml
255+
uses: ./.github/workflows/build-vm-driver-linux.yml
260256
with:
261257
cargo-version: ${{ needs.version.outputs.cargo }}
262-
macos: false
263258
secrets:
264259
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
265260

266261
build-vm-driver-macos:
267-
needs: [pr_metadata, version, build-binaries, build-binaries-macos]
262+
needs: [pr_metadata, version, build-binaries-linux, build-binaries-macos]
268263
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
269264
permissions:
270265
contents: read
271-
uses: ./.github/workflows/build-vm-driver.yml
266+
uses: ./.github/workflows/build-vm-driver-macos.yml
272267
with:
273268
cargo-version: ${{ needs.version.outputs.cargo }}
274-
linux: false
275269
secrets:
276270
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
277271

278272
build-images:
279-
needs: [pr_metadata, build-binaries]
273+
needs: [pr_metadata, build-binaries-linux]
280274
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_any_e2e == 'true'
281275
permissions:
282276
contents: read
@@ -285,7 +279,7 @@ jobs:
285279

286280
build-deb:
287281
name: Build Debian packages
288-
needs: [pr_metadata, version, build-binaries, build-vm-driver]
282+
needs: [pr_metadata, version, build-binaries-linux, build-vm-driver-linux]
289283
if: needs.pr_metadata.outputs.run_integration == 'true'
290284
permissions:
291285
contents: read
@@ -297,7 +291,7 @@ jobs:
297291

298292
build-rpm:
299293
name: Build RPM packages
300-
needs: [pr_metadata, version, build-binaries]
294+
needs: [pr_metadata, version, build-binaries-linux]
301295
if: needs.pr_metadata.outputs.run_integration == 'true'
302296
permissions:
303297
actions: read
@@ -350,7 +344,7 @@ jobs:
350344
if-no-files-found: error
351345

352346
prepare-integration:
353-
needs: [pr_metadata, build-binaries, build-images, build-deb, build-rpm, build-tmachine-test-inputs]
347+
needs: [pr_metadata, build-binaries-linux, build-images, build-deb, build-rpm, build-tmachine-test-inputs]
354348
if: needs.pr_metadata.outputs.run_integration == 'true'
355349
permissions:
356350
actions: read
@@ -428,7 +422,7 @@ jobs:
428422
]
429423
430424
docker-e2e:
431-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
425+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
432426
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
433427
permissions:
434428
actions: read
@@ -441,7 +435,7 @@ jobs:
441435
runner: linux-arm64-cpu8
442436

443437
podman-e2e:
444-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
438+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
445439
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
446440
permissions:
447441
actions: read
@@ -455,7 +449,7 @@ jobs:
455449
[{"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"}]
456450
457451
podman-additional-ca-e2e:
458-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
452+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
459453
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
460454
permissions:
461455
actions: read
@@ -469,7 +463,7 @@ jobs:
469463
[{"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"}]
470464
471465
vm-e2e:
472-
needs: [pr_metadata, build-binaries, build-conformance, build-vm-driver]
466+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-vm-driver-linux]
473467
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
474468
permissions:
475469
actions: read
@@ -480,7 +474,7 @@ jobs:
480474
prebuilt-conformance: true
481475

482476
vm-additional-ca-e2e:
483-
needs: [pr_metadata, build-binaries, build-conformance, build-vm-driver]
477+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-vm-driver-linux]
484478
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
485479
permissions:
486480
actions: read
@@ -493,7 +487,7 @@ jobs:
493487
test-name: additional_ca
494488

495489
docker-external-driver-e2e:
496-
needs: [pr_metadata, build-binaries, build-conformance, build-gateway-plain, build-external-drivers, build-images]
490+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-gateway-plain, build-external-drivers, build-images]
497491
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
498492
permissions:
499493
actions: read
@@ -510,7 +504,7 @@ jobs:
510504
[{"suite":"external-driver","cmd":"mise run --no-deps --skip-deps e2e:docker:external-driver","apt_packages":"openssh-client","python_proto":false,"mcp":false}]
511505
512506
podman-external-driver-e2e:
513-
needs: [pr_metadata, build-binaries, build-conformance, build-gateway-plain, build-external-drivers, build-images]
507+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-gateway-plain, build-external-drivers, build-images]
514508
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
515509
permissions:
516510
actions: read
@@ -526,7 +520,7 @@ jobs:
526520
[{"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"}]
527521
528522
vm-external-driver-e2e:
529-
needs: [pr_metadata, build-binaries, build-conformance, build-gateway-plain, build-vm-driver]
523+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-gateway-plain, build-vm-driver-linux]
530524
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
531525
permissions:
532526
actions: read
@@ -540,7 +534,7 @@ jobs:
540534
e2e-task: e2e:vm:external-driver
541535

542536
gpu-e2e:
543-
needs: [pr_metadata, build-binaries, build-images]
537+
needs: [pr_metadata, build-binaries-linux, build-images]
544538
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_gpu_e2e == 'true'
545539
permissions:
546540
actions: read
@@ -551,7 +545,7 @@ jobs:
551545
image-tag: ${{ github.sha }}
552546

553547
kubernetes-e2e:
554-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
548+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
555549
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
556550
strategy:
557551
fail-fast: false
@@ -582,7 +576,7 @@ jobs:
582576
test-name: ${{ matrix.test_name }}
583577

584578
kubernetes-app-listener-e2e:
585-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
579+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
586580
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
587581
strategy:
588582
fail-fast: false
@@ -620,7 +614,7 @@ jobs:
620614
listener-takeover: ${{ matrix.takeover }}
621615

622616
kubernetes-workspace-managed-e2e:
623-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
617+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
624618
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
625619
permissions:
626620
actions: read
@@ -634,7 +628,7 @@ jobs:
634628
e2e-task: e2e:kubernetes:workspace-managed
635629

636630
kubernetes-external-driver-e2e:
637-
needs: [pr_metadata, build-binaries, build-conformance, build-gateway-plain, build-external-drivers, build-images]
631+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-gateway-plain, build-external-drivers, build-images]
638632
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
639633
permissions:
640634
actions: read
@@ -651,7 +645,7 @@ jobs:
651645
cluster-images: sandbox supervisor
652646

653647
kubernetes-workspace-operator-e2e:
654-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
648+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
655649
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
656650
permissions:
657651
actions: read
@@ -665,7 +659,7 @@ jobs:
665659
e2e-task: e2e:kubernetes:workspace-operator
666660

667661
kubernetes-ha-e2e:
668-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
662+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
669663
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true'
670664
permissions:
671665
actions: read
@@ -683,7 +677,7 @@ jobs:
683677
use-envoy-gateway: true
684678

685679
kubernetes-credential-drivers-e2e:
686-
needs: [pr_metadata, build-binaries, build-conformance, build-images]
680+
needs: [pr_metadata, build-binaries-linux, build-conformance, build-images]
687681
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true'
688682
permissions:
689683
actions: read

0 commit comments

Comments
 (0)