Skip to content

Commit dfdbd62

Browse files
committed
feat(ci): add shadow-rust-native-build workflow for OS-49 Phase 4 (PR 4a)
Builds openshell-gateway and openshell-sandbox natively per-arch on the nv-gha-runners shared CPU pool with a GHA-backed sccache, and uploads the resulting binaries as artifacts shaped for Dockerfile.images' BINARY_SOURCE=prebuilt path (added in #945). Dispatch manually 4-5 times after merge to collect cold + warm numbers and compare against the Rust portion of docker-build.yml's ARC baseline. PR 4c will wire these artifacts into the real pipeline once numbers land. Refs OS-128. Signed-off-by: Jonas Toelke <jtoelke@nvidia.com>
1 parent 55b0266 commit dfdbd62

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: Shadow — Rust Native Build (openshell-gateway / openshell-sandbox)
5+
6+
# OS-49 Phase 4 / PR 4a — non-blocking shadow that builds openshell-gateway
7+
# and openshell-sandbox natively per-arch on the nv-gha-runners shared CPU
8+
# pool (`linux-{amd64,arm64}-cpu8`) with a GHA-backed sccache, and uploads
9+
# the resulting binaries as artifacts. Reuses the pattern from PR #853's
10+
# release-dev.yml "Build standalone {gateway,supervisor} binaries" jobs.
11+
#
12+
# The artifacts match the layout PR 4c expects when consuming `BINARY_SOURCE=
13+
# prebuilt` (wired up in #945): one binary per (component, arch), staged to
14+
# `deploy/docker/.build/prebuilt-binaries/<arch>/openshell-{gateway,sandbox}`.
15+
#
16+
# Dispatch 4-5 times after merge to collect cold + warm numbers and compare
17+
# against the Rust portion of docker-build.yml's 17.5 m ARC baseline. Success
18+
# criteria, gotchas, and dependency graph live on the OS-128 Linear issue.
19+
20+
on:
21+
push:
22+
branches: [main]
23+
workflow_dispatch:
24+
25+
permissions:
26+
contents: read
27+
packages: read
28+
29+
env:
30+
CARGO_TERM_COLOR: always
31+
CARGO_INCREMENTAL: "0"
32+
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
# Route sccache (already RUSTC_WRAPPER in mise.toml) to the GHA cache
34+
# backend instead of the EKS memcached used by ARC.
35+
SCCACHE_GHA_ENABLED: "true"
36+
37+
jobs:
38+
rust-native-build:
39+
name: ${{ matrix.component }} (${{ matrix.arch }})
40+
strategy:
41+
fail-fast: false
42+
matrix:
43+
component: [gateway, sandbox]
44+
arch: [amd64, arm64]
45+
include:
46+
- component: gateway
47+
crate: openshell-server
48+
binary: openshell-gateway
49+
- component: sandbox
50+
crate: openshell-sandbox
51+
binary: openshell-sandbox
52+
- arch: amd64
53+
runner: linux-amd64-cpu8
54+
target: x86_64-unknown-linux-gnu
55+
- arch: arm64
56+
runner: linux-arm64-cpu8
57+
target: aarch64-unknown-linux-gnu
58+
runs-on: ${{ matrix.runner }}
59+
env:
60+
# Partition the GHA sccache cache per (component, arch). Without this,
61+
# concurrent matrix jobs collide on the same cache key and later-starting
62+
# writers hit 409 Conflict (PR #961 fix for shadow-shared-cpu-spike).
63+
SCCACHE_GHA_VERSION: ${{ matrix.component }}-${{ matrix.arch }}
64+
container:
65+
image: ghcr.io/nvidia/openshell/ci:latest
66+
credentials:
67+
username: ${{ github.actor }}
68+
password: ${{ secrets.GITHUB_TOKEN }}
69+
timeout-minutes: 60
70+
steps:
71+
- uses: actions/checkout@v4
72+
with:
73+
fetch-depth: 0
74+
75+
- name: Mark workspace safe for git
76+
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
77+
78+
- name: Fetch tags
79+
run: git fetch --tags --force
80+
81+
- name: Install tools
82+
run: mise install
83+
84+
- name: Configure GHA sccache backend
85+
# Exposes ACTIONS_CACHE_URL / ACTIONS_RUNTIME_TOKEN so sccache (wrapped
86+
# around rustc via mise's RUSTC_WRAPPER) can initialize the GHA cache.
87+
uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9
88+
89+
- name: Cache Rust target and registry
90+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
91+
with:
92+
shared-key: shadow-rust-native-${{ matrix.component }}-${{ matrix.arch }}
93+
cache-directories: .cache/sccache
94+
cache-targets: "true"
95+
96+
- name: Compute cargo version
97+
id: version
98+
run: |
99+
set -euo pipefail
100+
echo "cargo_version=$(uv run python tasks/scripts/release.py get-version --cargo)" >> "$GITHUB_OUTPUT"
101+
102+
- name: Patch workspace version
103+
if: steps.version.outputs.cargo_version != ''
104+
run: |
105+
set -euo pipefail
106+
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ steps.version.outputs.cargo_version }}"'"/}' Cargo.toml
107+
108+
- name: Build ${{ matrix.binary }} (${{ matrix.target }})
109+
# Matches docker-build.yml's default EXTRA_CARGO_FEATURES so the
110+
# binary content is byte-comparable to what Dockerfile.images produces
111+
# today (precondition for PR 4c's drop-in swap).
112+
run: |
113+
set -euo pipefail
114+
mise x -- cargo build \
115+
--release \
116+
--target ${{ matrix.target }} \
117+
-p ${{ matrix.crate }} \
118+
--bin ${{ matrix.binary }} \
119+
--features openshell-core/dev-settings
120+
121+
- name: Verify packaged binary
122+
run: |
123+
set -euo pipefail
124+
BIN="target/${{ matrix.target }}/release/${{ matrix.binary }}"
125+
OUTPUT="$("$BIN" --version)"
126+
echo "$OUTPUT"
127+
grep -q "^${{ matrix.binary }} " <<<"$OUTPUT"
128+
# Record glibc linkage so drift from the Ubuntu noble runtime base
129+
# image is visible in logs (not asserted — the runtime check lands
130+
# when PR 4c builds images on top of these artifacts).
131+
ldd --version | head -1
132+
ldd "$BIN" | head -20 || true
133+
134+
- name: sccache stats
135+
if: always()
136+
run: mise x -- sccache --show-stats
137+
138+
- name: Stage binary for prebuilt layout
139+
# Shape mirrors `deploy/docker/.build/prebuilt-binaries/<arch>/<bin>`
140+
# so PR 4c can download the artifact directly into the build context.
141+
run: |
142+
set -euo pipefail
143+
STAGE="prebuilt-binaries/${{ matrix.arch }}"
144+
mkdir -p "$STAGE"
145+
install -m 0755 "target/${{ matrix.target }}/release/${{ matrix.binary }}" "$STAGE/${{ matrix.binary }}"
146+
ls -lh "$STAGE/"
147+
148+
- name: Upload artifact
149+
uses: actions/upload-artifact@v4
150+
with:
151+
name: rust-binary-${{ matrix.component }}-linux-${{ matrix.arch }}
152+
path: prebuilt-binaries/${{ matrix.arch }}/${{ matrix.binary }}
153+
retention-days: 5
154+
if-no-files-found: error

0 commit comments

Comments
 (0)