Skip to content

Commit 382b7b0

Browse files
committed
fix(ci): use zig as musl C/C++ compiler for Linux CLI builds
Replace the Alpine Docker-in-Docker approach (Dockerfile.cli-musl) with direct-on-host builds using zig cc/c++ to target musl. This eliminates: - Docker-in-Docker overhead and cache mount complexity - The libclang dlopen failure in Alpine (static musl binaries cannot dlopen) - ~15 min z3 C++ compilation without sccache Zig provides a first-class musl-targeting C/C++ toolchain that avoids glibc contamination (no _FORTIFY_SOURCE symbols) while running natively on the glibc CI host where bindgen/libclang and sccache work normally.
1 parent fec94eb commit 382b7b0

File tree

4 files changed

+101
-145
lines changed

4 files changed

+101
-145
lines changed

.github/workflows/release-dev.yml

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ jobs:
149149

150150
# ---------------------------------------------------------------------------
151151
# Build CLI binaries (Linux musl — static, native on each arch)
152+
#
153+
# Builds run directly on the CI host (glibc Ubuntu). Zig provides a
154+
# musl-targeting C/C++ compiler so that bundled-z3 produces musl-compatible
155+
# objects without glibc contamination. This avoids Docker-in-Docker and
156+
# lets sccache work normally.
152157
# ---------------------------------------------------------------------------
153158
build-cli-linux:
154159
name: Build CLI (Linux ${{ matrix.arch }})
@@ -157,13 +162,13 @@ jobs:
157162
matrix:
158163
include:
159164
- arch: amd64
160-
docker_platform: linux/amd64
161165
runner: build-amd64
162166
target: x86_64-unknown-linux-musl
167+
zig_target: x86_64-linux-musl
163168
- arch: arm64
164-
docker_platform: linux/arm64
165169
runner: build-arm64
166170
target: aarch64-unknown-linux-musl
171+
zig_target: aarch64-linux-musl
167172
runs-on: ${{ matrix.runner }}
168173
timeout-minutes: 60
169174
container:
@@ -172,8 +177,6 @@ jobs:
172177
username: ${{ github.actor }}
173178
password: ${{ secrets.GITHUB_TOKEN }}
174179
options: --privileged
175-
volumes:
176-
- /var/run/docker.sock:/var/run/docker.sock
177180
env:
178181
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179182
SCCACHE_MEMCACHED_ENDPOINT: ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
@@ -189,29 +192,58 @@ jobs:
189192
- name: Fetch tags
190193
run: git fetch --tags --force
191194

192-
- name: Set up Docker Buildx
193-
uses: ./.github/actions/setup-buildx
195+
- name: Install tools
196+
run: mise install
197+
198+
- name: Cache Rust target and registry
199+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
200+
with:
201+
shared-key: cli-musl-${{ matrix.arch }}
202+
cache-directories: .cache/sccache
203+
cache-targets: "true"
194204

195-
- name: Build ${{ matrix.target }} via Docker
205+
- name: Add Rust musl target
206+
run: mise x -- rustup target add ${{ matrix.target }}
207+
208+
- name: Set up zig-musl toolchain
196209
run: |
197210
set -euo pipefail
198-
docker buildx build \
199-
--platform "${{ matrix.docker_platform }}" \
200-
--file deploy/docker/Dockerfile.cli-musl \
201-
--build-arg TARGET_TRIPLE="${{ matrix.target }}" \
202-
--build-arg OPENSHELL_CARGO_VERSION="${{ needs.compute-versions.outputs.cargo_version }}" \
203-
--build-arg OPENSHELL_IMAGE_TAG=dev \
204-
--build-arg CARGO_TARGET_CACHE_SCOPE="${{ github.sha }}" \
205-
--target binary \
206-
--output type=local,dest=out/ \
207-
.
211+
ZIG="$(mise which zig)"
212+
mkdir -p /tmp/zig-musl
213+
printf '#!/bin/sh\nexec "%s" cc --target=${{ matrix.zig_target }} "$@"\n' "$ZIG" > /tmp/zig-musl/cc
214+
printf '#!/bin/sh\nexec "%s" c++ --target=${{ matrix.zig_target }} "$@"\n' "$ZIG" > /tmp/zig-musl/cxx
215+
chmod +x /tmp/zig-musl/cc /tmp/zig-musl/cxx
216+
217+
# Tell cargo / cc-rs / cmake to use zig for the musl target
218+
TARGET_ENV=$(echo "${{ matrix.target }}" | tr '-' '_')
219+
echo "CC_${TARGET_ENV}=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
220+
echo "CXX_${TARGET_ENV}=/tmp/zig-musl/cxx" >> "$GITHUB_ENV"
221+
echo "CARGO_TARGET_${TARGET_ENV^^}_LINKER=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
222+
223+
- name: Scope workspace to CLI crates
224+
run: |
225+
set -euo pipefail
226+
sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-cli", "crates/openshell-core", "crates/openshell-bootstrap", "crates/openshell-policy", "crates/openshell-prover", "crates/openshell-providers", "crates/openshell-tui"]|' Cargo.toml
227+
228+
- name: Patch workspace version
229+
if: needs.compute-versions.outputs.cargo_version != ''
230+
run: |
231+
set -euo pipefail
232+
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ needs.compute-versions.outputs.cargo_version }}"'"/}' Cargo.toml
233+
234+
- name: Build ${{ matrix.target }}
235+
run: mise x -- cargo build --release --target ${{ matrix.target }} -p openshell-cli --features bundled-z3
236+
237+
- name: sccache stats
238+
if: always()
239+
run: mise x -- sccache --show-stats
208240

209241
- name: Package binary
210242
run: |
211243
set -euo pipefail
212244
mkdir -p artifacts
213245
tar -czf artifacts/openshell-${{ matrix.target }}.tar.gz \
214-
-C out openshell
246+
-C target/${{ matrix.target }}/release openshell
215247
ls -lh artifacts/
216248
217249
- name: Upload artifact

.github/workflows/release-tag.yml

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ jobs:
170170

171171
# ---------------------------------------------------------------------------
172172
# Build CLI binaries (Linux musl — static, native on each arch)
173+
#
174+
# Builds run directly on the CI host (glibc Ubuntu). Zig provides a
175+
# musl-targeting C/C++ compiler so that bundled-z3 produces musl-compatible
176+
# objects without glibc contamination. This avoids Docker-in-Docker and
177+
# lets sccache work normally.
173178
# ---------------------------------------------------------------------------
174179
build-cli-linux:
175180
name: Build CLI (Linux ${{ matrix.arch }})
@@ -178,13 +183,13 @@ jobs:
178183
matrix:
179184
include:
180185
- arch: amd64
181-
docker_platform: linux/amd64
182186
runner: build-amd64
183187
target: x86_64-unknown-linux-musl
188+
zig_target: x86_64-linux-musl
184189
- arch: arm64
185-
docker_platform: linux/arm64
186190
runner: build-arm64
187191
target: aarch64-unknown-linux-musl
192+
zig_target: aarch64-linux-musl
188193
runs-on: ${{ matrix.runner }}
189194
timeout-minutes: 60
190195
container:
@@ -193,8 +198,6 @@ jobs:
193198
username: ${{ github.actor }}
194199
password: ${{ secrets.GITHUB_TOKEN }}
195200
options: --privileged
196-
volumes:
197-
- /var/run/docker.sock:/var/run/docker.sock
198201
env:
199202
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
200203
SCCACHE_MEMCACHED_ENDPOINT: ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
@@ -211,29 +214,58 @@ jobs:
211214
- name: Fetch tags
212215
run: git fetch --tags --force
213216

214-
- name: Set up Docker Buildx
215-
uses: ./.github/actions/setup-buildx
217+
- name: Install tools
218+
run: mise install
219+
220+
- name: Cache Rust target and registry
221+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
222+
with:
223+
shared-key: cli-musl-${{ matrix.arch }}
224+
cache-directories: .cache/sccache
225+
cache-targets: "true"
216226

217-
- name: Build ${{ matrix.target }} via Docker
227+
- name: Add Rust musl target
228+
run: mise x -- rustup target add ${{ matrix.target }}
229+
230+
- name: Set up zig-musl toolchain
218231
run: |
219232
set -euo pipefail
220-
docker buildx build \
221-
--platform "${{ matrix.docker_platform }}" \
222-
--file deploy/docker/Dockerfile.cli-musl \
223-
--build-arg TARGET_TRIPLE="${{ matrix.target }}" \
224-
--build-arg OPENSHELL_CARGO_VERSION="${{ needs.compute-versions.outputs.cargo_version }}" \
225-
--build-arg OPENSHELL_IMAGE_TAG="${{ needs.compute-versions.outputs.semver }}" \
226-
--build-arg CARGO_TARGET_CACHE_SCOPE="${{ github.sha }}" \
227-
--target binary \
228-
--output type=local,dest=out/ \
229-
.
233+
ZIG="$(mise which zig)"
234+
mkdir -p /tmp/zig-musl
235+
printf '#!/bin/sh\nexec "%s" cc --target=${{ matrix.zig_target }} "$@"\n' "$ZIG" > /tmp/zig-musl/cc
236+
printf '#!/bin/sh\nexec "%s" c++ --target=${{ matrix.zig_target }} "$@"\n' "$ZIG" > /tmp/zig-musl/cxx
237+
chmod +x /tmp/zig-musl/cc /tmp/zig-musl/cxx
238+
239+
# Tell cargo / cc-rs / cmake to use zig for the musl target
240+
TARGET_ENV=$(echo "${{ matrix.target }}" | tr '-' '_')
241+
echo "CC_${TARGET_ENV}=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
242+
echo "CXX_${TARGET_ENV}=/tmp/zig-musl/cxx" >> "$GITHUB_ENV"
243+
echo "CARGO_TARGET_${TARGET_ENV^^}_LINKER=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
244+
245+
- name: Scope workspace to CLI crates
246+
run: |
247+
set -euo pipefail
248+
sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-cli", "crates/openshell-core", "crates/openshell-bootstrap", "crates/openshell-policy", "crates/openshell-prover", "crates/openshell-providers", "crates/openshell-tui"]|' Cargo.toml
249+
250+
- name: Patch workspace version
251+
if: needs.compute-versions.outputs.cargo_version != ''
252+
run: |
253+
set -euo pipefail
254+
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ needs.compute-versions.outputs.cargo_version }}"'"/}' Cargo.toml
255+
256+
- name: Build ${{ matrix.target }}
257+
run: mise x -- cargo build --release --target ${{ matrix.target }} -p openshell-cli --features bundled-z3
258+
259+
- name: sccache stats
260+
if: always()
261+
run: mise x -- sccache --show-stats
230262

231263
- name: Package binary
232264
run: |
233265
set -euo pipefail
234266
mkdir -p artifacts
235267
tar -czf artifacts/openshell-${{ matrix.target }}.tar.gz \
236-
-C out openshell
268+
-C target/${{ matrix.target }}/release openshell
237269
ls -lh artifacts/
238270
239271
- name: Upload artifact

deploy/docker/Dockerfile.cli-musl

Lines changed: 0 additions & 109 deletions
This file was deleted.

mise.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ helm = "4.1.1"
2323
"ubi:mozilla/sccache" = { version = "0.14.0", matching = "sccache-v" }
2424
"ubi:anchore/syft" = { version = "1.42.3", matching = "syft_" }
2525
"ubi:EmbarkStudios/cargo-about" = "0.8.4"
26+
zig = "0.14.1"
2627

2728
[env]
2829
_.path = ["{{config_root}}/scripts/bin"]

0 commit comments

Comments
 (0)