Skip to content

Commit e177646

Browse files
committed
ci: parallelize artifact builds
Refs #1683 Signed-off-by: Simon Scatton <[email protected]>
1 parent eb1084e commit e177646

5 files changed

Lines changed: 368 additions & 236 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: Build Docker Image
5+
description: Build and push one architecture of an OpenShell image
6+
7+
inputs:
8+
component:
9+
description: Docker image and Dockerfile name
10+
required: true
11+
binary:
12+
description: Binary staged in the Docker build context
13+
required: true
14+
triple:
15+
description: Binary artifact target triple
16+
required: true
17+
arch:
18+
description: Docker architecture name
19+
required: true
20+
platform:
21+
description: Docker platform
22+
required: true
23+
github-token:
24+
description: Token used to push the image
25+
required: true
26+
27+
runs:
28+
using: composite
29+
steps:
30+
- uses: ./.github/actions/setup-buildx
31+
with:
32+
buildkitd-config: /etc/buildkit/buildkitd.toml
33+
34+
- name: Log in to GHCR
35+
shell: bash
36+
run: echo "${{ inputs.github-token }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
37+
38+
- name: Download ${{ inputs.binary }}
39+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
40+
with:
41+
name: ${{ inputs.binary }}-${{ inputs.triple }}
42+
path: artifact
43+
44+
- name: Stage ${{ inputs.binary }}
45+
shell: bash
46+
run: |
47+
install -d deploy/docker/.build/prebuilt-binaries/${{ inputs.arch }}
48+
tar -xzf artifact/${{ inputs.binary }}-${{ inputs.triple }}.tar.gz -C artifact
49+
install -m 0755 artifact/${{ inputs.binary }} deploy/docker/.build/prebuilt-binaries/${{ inputs.arch }}/${{ inputs.binary }}
50+
51+
- name: Build ${{ inputs.component }} image
52+
shell: bash
53+
run: |
54+
docker buildx build \
55+
--builder openshell \
56+
--platform ${{ inputs.platform }} \
57+
--file deploy/docker/Dockerfile.${{ inputs.component }} \
58+
--target ${{ inputs.component }} \
59+
--tag ghcr.io/nvidia/openshell/${{ inputs.component }}:${{ github.sha }}-${{ inputs.arch }} \
60+
--cache-from type=gha,scope=${{ inputs.component }}-${{ inputs.arch }} \
61+
--cache-to type=gha,mode=max,scope=${{ inputs.component }}-${{ inputs.arch }} \
62+
--provenance=false \
63+
--push \
64+
.

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

Lines changed: 154 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -76,25 +76,139 @@ jobs:
7676
echo "run_any_e2e=$run_any_e2e"
7777
} >> "$GITHUB_OUTPUT"
7878
79-
build-binaries:
79+
version:
8080
needs: [pr_metadata]
8181
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_any_e2e == 'true'
8282
permissions:
8383
contents: read
84+
runs-on: ubuntu-latest
85+
timeout-minutes: 5
86+
outputs:
87+
cargo: ${{ steps.version.outputs.cargo }}
88+
steps:
89+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
90+
with:
91+
fetch-depth: 0
92+
93+
- name: Compute version
94+
id: version
95+
run: |
96+
cargo="$(python3 tasks/scripts/release.py get-version --cargo)"
97+
echo "cargo=$cargo" >> "$GITHUB_OUTPUT"
98+
99+
build-cli:
100+
needs: version
101+
permissions:
102+
contents: read
103+
strategy:
104+
matrix:
105+
include:
106+
- triple: x86_64-unknown-linux-musl
107+
runner: linux-amd64-cpu8
108+
dev_shell: .#devShells.x86_64-linux.musl
109+
- triple: aarch64-unknown-linux-musl
110+
runner: linux-arm64-cpu8
111+
dev_shell: .#devShells.aarch64-linux.musl
112+
- triple: aarch64-apple-darwin
113+
runner: macos-15-xlarge
114+
dev_shell: .#devShells.aarch64-darwin.default
84115
uses: ./.github/workflows/build-binaries.yml
116+
with:
117+
binary: openshell
118+
triple: ${{ matrix.triple }}
119+
runner: ${{ matrix.runner }}
120+
dev-shell: ${{ matrix.dev_shell }}
121+
cargo-version: ${{ needs.version.outputs.cargo }}
85122
secrets: inherit
86123

87-
build-images:
88-
needs: [pr_metadata, build-binaries]
124+
build-sandbox:
125+
needs: version
126+
permissions:
127+
contents: read
128+
strategy:
129+
matrix:
130+
include:
131+
- triple: x86_64-unknown-linux-musl
132+
runner: linux-amd64-cpu8
133+
dev_shell: .#devShells.x86_64-linux.musl
134+
- triple: aarch64-unknown-linux-musl
135+
runner: linux-arm64-cpu8
136+
dev_shell: .#devShells.aarch64-linux.musl
137+
uses: ./.github/workflows/build-binaries.yml
138+
with:
139+
binary: openshell-sandbox
140+
triple: ${{ matrix.triple }}
141+
runner: ${{ matrix.runner }}
142+
dev-shell: ${{ matrix.dev_shell }}
143+
cargo-version: ${{ needs.version.outputs.cargo }}
144+
secrets: inherit
145+
146+
build-gateway:
147+
needs: version
148+
permissions:
149+
contents: read
150+
strategy:
151+
matrix:
152+
include:
153+
- triple: x86_64-unknown-linux-gnu
154+
runner: linux-amd64-cpu8
155+
dev_shell: .#devShells.x86_64-linux.glibc-2-28
156+
interpreter: /lib64/ld-linux-x86-64.so.2
157+
- triple: aarch64-unknown-linux-gnu
158+
runner: linux-arm64-cpu8
159+
dev_shell: .#devShells.aarch64-linux.glibc-2-28
160+
interpreter: /lib/ld-linux-aarch64.so.1
161+
- triple: aarch64-apple-darwin
162+
runner: macos-15-xlarge
163+
dev_shell: .#devShells.aarch64-darwin.default
164+
uses: ./.github/workflows/build-binaries.yml
165+
with:
166+
binary: openshell-gateway
167+
triple: ${{ matrix.triple }}
168+
runner: ${{ matrix.runner }}
169+
dev-shell: ${{ matrix.dev_shell }}
170+
cargo-version: ${{ needs.version.outputs.cargo }}
171+
interpreter: ${{ matrix.interpreter }}
172+
secrets: inherit
173+
174+
build-vm-driver:
175+
needs: [pr_metadata, version, build-sandbox]
176+
if: needs.pr_metadata.outputs.run_core_e2e == 'true'
177+
permissions:
178+
contents: read
179+
uses: ./.github/workflows/build-vm-driver.yml
180+
with:
181+
cargo-version: ${{ needs.version.outputs.cargo }}
182+
secrets: inherit
183+
184+
build-gateway-image:
185+
needs: [pr_metadata, build-gateway]
89186
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_any_e2e == 'true'
90187
permissions:
91188
contents: read
92189
packages: write
93190
uses: ./.github/workflows/docker-build.yml
191+
with:
192+
component: gateway
193+
binary: openshell-gateway
194+
target-suffix: unknown-linux-gnu
195+
secrets: inherit
196+
197+
build-supervisor-image:
198+
needs: [pr_metadata, build-sandbox]
199+
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_any_e2e == 'true'
200+
permissions:
201+
contents: read
202+
packages: write
203+
uses: ./.github/workflows/docker-build.yml
204+
with:
205+
component: supervisor
206+
binary: openshell-sandbox
207+
target-suffix: unknown-linux-musl
94208
secrets: inherit
95209

96210
e2e:
97-
needs: [pr_metadata, build-binaries, build-images]
211+
needs: [pr_metadata, build-cli, build-vm-driver, build-gateway-image, build-supervisor-image]
98212
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
99213
permissions:
100214
actions: read
@@ -106,7 +220,7 @@ jobs:
106220
runner: linux-arm64-cpu8
107221

108222
gpu-e2e:
109-
needs: [pr_metadata, build-binaries, build-images]
223+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
110224
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_gpu_e2e == 'true'
111225
permissions:
112226
actions: read
@@ -117,7 +231,7 @@ jobs:
117231
image-tag: ${{ github.sha }}
118232

119233
kubernetes-e2e:
120-
needs: [pr_metadata, build-binaries, build-images]
234+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
121235
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
122236
strategy:
123237
fail-fast: false
@@ -147,7 +261,7 @@ jobs:
147261
extra-helm-values: ${{ matrix.extra_helm_values }}
148262

149263
kubernetes-workspace-managed-e2e:
150-
needs: [pr_metadata, build-binaries, build-images]
264+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
151265
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
152266
permissions:
153267
actions: read
@@ -163,7 +277,7 @@ jobs:
163277
# is not a release artifact.
164278

165279
kubernetes-workspace-operator-e2e:
166-
needs: [pr_metadata, build-binaries, build-images]
280+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
167281
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
168282
permissions:
169283
actions: read
@@ -176,7 +290,7 @@ jobs:
176290
e2e-task: e2e:kubernetes:workspace-operator
177291

178292
kubernetes-ha-e2e:
179-
needs: [pr_metadata, build-binaries, build-images]
293+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
180294
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true'
181295
permissions:
182296
actions: read
@@ -190,7 +304,7 @@ jobs:
190304
external-postgres-secret: openshell-ha-pg
191305

192306
kubernetes-credential-drivers-e2e:
193-
needs: [pr_metadata, build-binaries, build-images]
307+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image]
194308
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true'
195309
permissions:
196310
actions: read
@@ -204,14 +318,16 @@ jobs:
204318

205319
core-e2e-result:
206320
name: Core E2E result
207-
needs: [pr_metadata, build-binaries, build-images, e2e, kubernetes-e2e, kubernetes-workspace-managed-e2e, kubernetes-workspace-operator-e2e]
321+
needs: [pr_metadata, build-cli, build-vm-driver, build-gateway-image, build-supervisor-image, e2e, kubernetes-e2e, kubernetes-workspace-managed-e2e, kubernetes-workspace-operator-e2e]
208322
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
209323
runs-on: ubuntu-latest
210324
steps:
211325
- name: Verify core E2E jobs
212326
env:
213-
BUILD_BINARIES_RESULT: ${{ needs.build-binaries.result }}
214-
BUILD_IMAGES_RESULT: ${{ needs.build-images.result }}
327+
BUILD_CLI_RESULT: ${{ needs.build-cli.result }}
328+
BUILD_VM_DRIVER_RESULT: ${{ needs.build-vm-driver.result }}
329+
BUILD_GATEWAY_IMAGE_RESULT: ${{ needs.build-gateway-image.result }}
330+
BUILD_SUPERVISOR_IMAGE_RESULT: ${{ needs.build-supervisor-image.result }}
215331
E2E_RESULT: ${{ needs.e2e.result }}
216332
KUBERNETES_E2E_RESULT: ${{ needs.kubernetes-e2e.result }}
217333
KUBERNETES_WORKSPACE_MANAGED_E2E_RESULT: ${{ needs.kubernetes-workspace-managed-e2e.result }}
@@ -220,8 +336,10 @@ jobs:
220336
set -euo pipefail
221337
failed=0
222338
for item in \
223-
"build-binaries:$BUILD_BINARIES_RESULT" \
224-
"build-images:$BUILD_IMAGES_RESULT" \
339+
"build-cli:$BUILD_CLI_RESULT" \
340+
"build-vm-driver:$BUILD_VM_DRIVER_RESULT" \
341+
"build-gateway-image:$BUILD_GATEWAY_IMAGE_RESULT" \
342+
"build-supervisor-image:$BUILD_SUPERVISOR_IMAGE_RESULT" \
225343
"e2e:$E2E_RESULT" \
226344
"kubernetes-e2e:$KUBERNETES_E2E_RESULT" \
227345
"kubernetes-workspace-managed-e2e:$KUBERNETES_WORKSPACE_MANAGED_E2E_RESULT" \
@@ -237,21 +355,23 @@ jobs:
237355
238356
gpu-e2e-result:
239357
name: GPU E2E result
240-
needs: [pr_metadata, build-binaries, build-images, gpu-e2e]
358+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image, gpu-e2e]
241359
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_gpu_e2e == 'true'
242360
runs-on: ubuntu-latest
243361
steps:
244362
- name: Verify GPU E2E jobs
245363
env:
246-
BUILD_BINARIES_RESULT: ${{ needs.build-binaries.result }}
247-
BUILD_IMAGES_RESULT: ${{ needs.build-images.result }}
364+
BUILD_CLI_RESULT: ${{ needs.build-cli.result }}
365+
BUILD_GATEWAY_IMAGE_RESULT: ${{ needs.build-gateway-image.result }}
366+
BUILD_SUPERVISOR_IMAGE_RESULT: ${{ needs.build-supervisor-image.result }}
248367
GPU_E2E_RESULT: ${{ needs.gpu-e2e.result }}
249368
run: |
250369
set -euo pipefail
251370
failed=0
252371
for item in \
253-
"build-binaries:$BUILD_BINARIES_RESULT" \
254-
"build-images:$BUILD_IMAGES_RESULT" \
372+
"build-cli:$BUILD_CLI_RESULT" \
373+
"build-gateway-image:$BUILD_GATEWAY_IMAGE_RESULT" \
374+
"build-supervisor-image:$BUILD_SUPERVISOR_IMAGE_RESULT" \
255375
"gpu-e2e:$GPU_E2E_RESULT"; do
256376
name="${item%%:*}"
257377
result="${item#*:}"
@@ -264,21 +384,23 @@ jobs:
264384
265385
kubernetes-ha-e2e-result:
266386
name: Kubernetes HA E2E result
267-
needs: [pr_metadata, build-binaries, build-images, kubernetes-ha-e2e]
387+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image, kubernetes-ha-e2e]
268388
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true'
269389
runs-on: ubuntu-latest
270390
steps:
271391
- name: Verify Kubernetes HA E2E jobs
272392
env:
273-
BUILD_BINARIES_RESULT: ${{ needs.build-binaries.result }}
274-
BUILD_IMAGES_RESULT: ${{ needs.build-images.result }}
393+
BUILD_CLI_RESULT: ${{ needs.build-cli.result }}
394+
BUILD_GATEWAY_IMAGE_RESULT: ${{ needs.build-gateway-image.result }}
395+
BUILD_SUPERVISOR_IMAGE_RESULT: ${{ needs.build-supervisor-image.result }}
275396
KUBERNETES_HA_E2E_RESULT: ${{ needs.kubernetes-ha-e2e.result }}
276397
run: |
277398
set -euo pipefail
278399
failed=0
279400
for item in \
280-
"build-binaries:$BUILD_BINARIES_RESULT" \
281-
"build-images:$BUILD_IMAGES_RESULT" \
401+
"build-cli:$BUILD_CLI_RESULT" \
402+
"build-gateway-image:$BUILD_GATEWAY_IMAGE_RESULT" \
403+
"build-supervisor-image:$BUILD_SUPERVISOR_IMAGE_RESULT" \
282404
"kubernetes-ha-e2e:$KUBERNETES_HA_E2E_RESULT"; do
283405
name="${item%%:*}"
284406
result="${item#*:}"
@@ -291,21 +413,23 @@ jobs:
291413
292414
kubernetes-credential-drivers-e2e-result:
293415
name: Kubernetes Credential Drivers E2E result
294-
needs: [pr_metadata, build-binaries, build-images, kubernetes-credential-drivers-e2e]
416+
needs: [pr_metadata, build-cli, build-gateway-image, build-supervisor-image, kubernetes-credential-drivers-e2e]
295417
if: always() && needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true'
296418
runs-on: ubuntu-latest
297419
steps:
298420
- name: Verify Kubernetes credential drivers E2E jobs
299421
env:
300-
BUILD_BINARIES_RESULT: ${{ needs.build-binaries.result }}
301-
BUILD_IMAGES_RESULT: ${{ needs.build-images.result }}
422+
BUILD_CLI_RESULT: ${{ needs.build-cli.result }}
423+
BUILD_GATEWAY_IMAGE_RESULT: ${{ needs.build-gateway-image.result }}
424+
BUILD_SUPERVISOR_IMAGE_RESULT: ${{ needs.build-supervisor-image.result }}
302425
KUBERNETES_CREDENTIAL_DRIVERS_E2E_RESULT: ${{ needs.kubernetes-credential-drivers-e2e.result }}
303426
run: |
304427
set -euo pipefail
305428
failed=0
306429
for item in \
307-
"build-binaries:$BUILD_BINARIES_RESULT" \
308-
"build-images:$BUILD_IMAGES_RESULT" \
430+
"build-cli:$BUILD_CLI_RESULT" \
431+
"build-gateway-image:$BUILD_GATEWAY_IMAGE_RESULT" \
432+
"build-supervisor-image:$BUILD_SUPERVISOR_IMAGE_RESULT" \
309433
"kubernetes-credential-drivers-e2e:$KUBERNETES_CREDENTIAL_DRIVERS_E2E_RESULT"; do
310434
name="${item%%:*}"
311435
result="${item#*:}"

0 commit comments

Comments
 (0)