Skip to content

fix(release): build musl via cargo-zigbuild + make release resilient#46

Merged
amondnet merged 2 commits into
mainfrom
fix/musl-zigbuild-release-resilience
Jun 22, 2026
Merged

fix(release): build musl via cargo-zigbuild + make release resilient#46
amondnet merged 2 commits into
mainfrom
fix/musl-zigbuild-release-resilience

Conversation

@amondnet

@amondnet amondnet commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

v0.1.1 built 5/6 targets; the musl leg failed:

error: failed to run custom build command for `esaxx-rs v0.1.10`
cc-rs: failed to find tool "x86_64-linux-musl-g++"

esaxx-rs is C++ (via tokenizersmodel2vec-rs); musl-tools ships musl-gcc but not musl-g++. Because release-rust.yml required all builds before upload, this one failure blocked the entire release (no assets, no npm publish).

Dependency audit (musl-relevant native deps)

Crate Lang Source
esaxx-rs C++ tokenizers ← model2vec-rs
onig_sys C onig ← tokenizers ← model2vec-rs
zstd-sys C zstd ← tree-sitter-language-pack
ring C+asm rustls ← ureq ← tree-sitter-language-pack

No onnxruntime/ort — model2vec uses pure-Rust static embeddings. The native surface is bounded, so one C/C++ cross toolchain (zig) covers all of it.

Fix

  1. musl → cargo-zigbuild: zig provides a complete C/C++ cross toolchain (clang + musl + libc++), installed from the official tarball (no extra pinned action). Other targets keep plain cargo build.
  2. Release resilience: upload-release-assets, publish-npm, and the Homebrew job now run with always(), so a single failed build leg no longer blocks the whole release — the targets that built still publish (the npm generator is already partial-matrix-tolerant). Upload fails loudly only if nothing built.

Recovery

Merging this fix: cuts 0.1.2; with zigbuild all 6 targets should build and publish cleanly via OIDC. Even if musl regresses, resilience lets the other 5 ship.

Test plan

  • YAML validated
  • CI green
  • musl build succeeds in the 0.1.2 release run

Summary by cubic

Switch *-musl builds to cargo-zigbuild with zig and harden the release so successful targets still publish. Adds signature verification and strict checksum downloads for safer releases.

  • Bug Fixes
    • Build *-musl with cargo zigbuild; install zig 0.13.0 and cargo-zigbuild ^0.19 from the official tarball, verifying the Zig download with minisign before use.
    • Make publishing resilient: run upload-release-assets, publish-npm, and Homebrew with always(); the uploader fails only if no artifacts are staged, and Homebrew checksum downloads use curl -fLsS to hard-fail when a core asset is missing.

Written for commit c681d35. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • Improved release workflow resilience so npm publishing and Homebrew formula updates can proceed as long as required release targets/assets are available, even when some build steps fail.
    • Enhanced Rust cross-compilation for musl targets using a verified Zig-based build approach.
    • Improved release asset handling: uploads run when a valid tag exists, artifact staging now logs staged output and fails explicitly if nothing is produced.
    • Hardened checksum downloads to fail cleanly on missing resources.

The v0.1.1 release built 5/6 targets; the musl leg failed because esaxx-rs
(C++, via tokenizers -> model2vec-rs) needs a musl C++ cross compiler and
musl-tools only ships musl-gcc, not musl-g++. A dependency audit found the
native build surface is bounded (esaxx-rs C++, onig/zstd C, ring) with NO
onnxruntime, so a single C/C++ cross toolchain covers it.

- musl target now builds with cargo-zigbuild (zig = clang + musl + libc++),
  installed from the official zig tarball (no extra pinned action). Other
  targets keep plain cargo build.
- Release resilience: upload-release-assets, publish-npm, and the Homebrew job
  now run with always(), so a single failed build leg no longer blocks the
  whole release — the targets that built still publish. The npm generator is
  already partial-matrix-tolerant; upload fails loudly only if nothing built.
@gemini-code-assist

Copy link
Copy Markdown

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d6dbb363-7050-4256-b0c8-83c64f801aa8

📥 Commits

Reviewing files that changed from the base of the PR and between 8591629 and c681d35.

📒 Files selected for processing (2)
  • .github/workflows/release-please.yml
  • .github/workflows/release-rust.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/release-please.yml
  • .github/workflows/release-rust.yml

📝 Walkthrough

Walkthrough

Two release workflow files are updated to tolerate partial matrix build failures. The Rust workflow switches musl target builds from musl-tools to a Zig-based cargo-zigbuild setup, adds a zero-artifact guard in the staging step, and sets always() on the upload job. The npm publish and Homebrew formula update jobs also gain always() so they proceed when a release exists regardless of build outcomes; Homebrew checksum downloads use defensive curl flags to fail fast on missing assets.

Changes

Release Workflow Resilience

Layer / File(s) Summary
musl cross-compilation via cargo-zigbuild
.github/workflows/release-rust.yml
Adds a Zig tarball download verified with minisign, installs cargo-zigbuild, and switches the build step to run cargo zigbuild conditionally for musl targets while keeping cargo build for all others, replacing the former musl-tools path.
Defensive artifact staging and always() upload job
.github/workflows/release-rust.yml
Staging block now copies artifacts with suppressed per-file errors, counts staged files, logs the listing, and exits non-zero when the count is zero. The upload-release-assets job condition is changed to always() && inputs.tag != ''.
always() guards on npm publish and Homebrew with defensive curl
.github/workflows/release-please.yml
publish-npm and update-homebrew-formula job if conditions each gain always() so they run despite upstream build failures. Checksum downloads switch from curl -L to curl -fLsS to hard-fail on missing assets rather than writing corrupted content.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • pleaseai/code-search#42: Directly modifies the same release-please.yml and release-rust.yml workflow files around npm publish, Homebrew formula update, and Rust artifact staging/upload logic.

Poem

🐇 A rabbit once built, but some targets would fail,
The musl cross-compile had gone off the rail.
Now Zig takes the wheel and the staging counts files,
always() kicks in and publishes smiles,
With curl's -f flag, no corrupted avails!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and concisely summarizes the two main changes: fixing musl builds via cargo-zigbuild and making the release workflow resilient to partial failures.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/musl-zigbuild-release-resilience

Comment @coderabbitai help to get the list of available commands and usage tips.

@codacy-production

codacy-production Bot commented Jun 22, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-please.yml:
- Around line 155-157: The `always()` condition in the Homebrew job allows it to
proceed even with partial build failures, but the current asset download
mechanism using curl without the `-f` flag silently succeeds even when assets
are missing, causing corrupt formula generation. Add the `-f` flag to all curl
commands downloading checksum assets to make them fail on missing resources, and
add explicit validation logic before the formula generation step to verify that
all required core assets (darwin and linux-gnu checksums) are present and
hard-fail the job if any are missing, while keeping the `always()` condition to
permit musl build failures that shouldn't block the release.

In @.github/workflows/release-rust.yml:
- Around line 85-89: The workflow downloads and extracts a Zig tarball without
verifying its integrity, which is a security risk. Modify the Zig installation
step to download the minisign signature file for the tarball (typically with a
.sig extension), retrieve the official Zig public key from
ziglang.org/download/, and use minisign to verify the tarball signature before
extracting it. Only proceed with the tar extraction if the minisign verification
succeeds. Reference the ZIG_VERSION variable in the download URLs for both the
tarball and signature file to ensure consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6d7e9380-a555-4621-b113-49fc883689e6

📥 Commits

Reviewing files that changed from the base of the PR and between cb93ce6 and 8591629.

📒 Files selected for processing (2)
  • .github/workflows/release-please.yml
  • .github/workflows/release-rust.yml

Comment thread .github/workflows/release-please.yml
Comment thread .github/workflows/release-rust.yml

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread .github/workflows/release-rust.yml Outdated
- homebrew: use 'curl -fLsS' for checksum downloads so a missing core asset
  hard-fails the job under always() instead of baking a corrupt sha256 into
  the formula (coderabbit)
- musl zig setup: verify the Zig tarball with minisign against the official
  ziglang.org public key before extracting/executing it (coderabbit)
@amondnet amondnet merged commit ec7fbb3 into main Jun 22, 2026
7 checks passed
@amondnet amondnet deleted the fix/musl-zigbuild-release-resilience branch June 22, 2026 12:28
@pleaseai-bot pleaseai-bot Bot mentioned this pull request Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant