chore: consolidate on one TLS stack, ship static musl binaries#79
Merged
Conversation
submod linked two TLS stacks. git2/libgit2-sys/libssh2-sys use openssl-sys;
gix used blocking-http-transport-curl-rustls, which pulled curl-sys ->
rustls-ffi -> {rustls -> aws-lc-rs -> aws-lc-sys, paste}. That second stack
was the sole source of three ignored RUSTSEC advisories (2024-0436 paste,
2026-0044 and 2026-0048 aws-lc X.509) and of an unallowed OpenSSL license
clause on aws-lc-sys that was failing `cargo deny check licenses`.
Switching gix to blocking-http-transport-curl-openssl makes curl share the
openssl-sys that is already linked, removing rustls, aws-lc-sys and paste
from the graph entirely: 368 -> 294 crates. The three ignores are deleted
rather than left in place, so a re-entry of any of them fails the build
instead of being silently absorbed.
This is the -openssl variant deliberately. Bare blocking-http-transport-curl
enables no TLS crate at all and defers HTTPS to whatever system libcurl the
host happens to provide.
Verified against a real remote, not just the dependency graph: an HTTPS
submodule add against github.com and a subsequent `update --verbose` showing
gix's curl transport completing the TLS handshake and returning the full ref
advertisement. 569/569 tests pass.
Static musl binaries
--------------------
The release matrix built no musl target, so every Linux artifact linked
glibc dynamically. Adds x86_64- and aarch64-unknown-linux-musl via cross.
The existing git2/vendored-libgit2,vendored-openssl features now cover curl
too, since both consume the same openssl-sys.
LIBCURL_NO_PKG_CONFIG=1 forces curl-sys to build libcurl from source rather
than probing pkg-config for the build image's copy — a release binary that
dynamically links the builder's libcurl is not portable, and a glibc-linked
one would not work on musl at all. It is set for the whole job rather than
per-target because the variable is presence-checked: a
`${{ ... && '1' || '' }}` expression would still read as set everywhere. It
only affects Linux regardless, as curl-sys returns early with the system
libcurl on Apple targets and uses vcpkg on Windows.
deny.toml's target list had drifted from what is actually built: musl,
x86_64-apple-darwin and x86_64-pc-windows-gnu were checked but never built,
while aarch64-pc-windows-msvc was built but never checked. Both lists now
match.
Release safety
--------------
workflow_dispatch only gated the create-release step. `publish` and
`github_release` had no condition, so a manual dispatch ran
`cargo publish --allow-dirty` against crates.io and cut a real GitHub
release, while the build job treated the same event as a dry run. Both jobs
are now gated, making dispatch an actual dry run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XocU6NjgZricrRWMLyLXDn
bashandbone
force-pushed
the
chore/consolidate-tls-static-musl
branch
from
July 26, 2026 03:11
134c120 to
2343beb
Compare
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XocU6NjgZricrRWMLyLXDn
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two TLS stacks, one of them load-bearing for every ignored advisory
git2/libgit2-sys/libssh2-syslinkopenssl-sys.gixusedblocking-http-transport-curl-rustls, which pulled a second, entirely separate stack:Every advisory
deny.tomlwas ignoring except one came from that subtree —RUSTSEC-2024-0436(paste),RUSTSEC-2026-0044andRUSTSEC-2026-0048(aws-lc X.509). So did an unallowedOpenSSLlicense clause onaws-lc-systhat was failingcargo deny check licensesonmain.Switching to
blocking-http-transport-curl-opensslmakes curl share theopenssl-systhat is already being linked. rustls, aws-lc-sys and paste leave the graph entirely: 368 → 294 crates.The three ignores are deleted, not left dormant — if any of them reappears, the build fails rather than silently absorbing it. Only
RUSTSEC-2024-0364(gitoxide-core terminal escapes, no patched version) remains.Verified against a real remote
Dependency-graph reasoning isn't enough here, so this was checked end to end: an HTTPS submodule add against
github.com, thenupdate --verboseshowing gix's curl transport completing the handshake and returning the full ref advertisement.569/569 tests pass,
cargo deny check advisoriesclean,cargo fmt --checkclean.Static musl binaries
The release matrix built no musl target at all — every Linux artifact linked glibc dynamically. Adds
x86_64-andaarch64-unknown-linux-muslviacross.The existing
git2/vendored-libgit2,git2/vendored-opensslfeatures now cover curl too, precisely because both consume the sameopenssl-sys— that only became true with this change.LIBCURL_NO_PKG_CONFIG=1forcescurl-systo build libcurl from source instead of probing pkg-config for the build image's copy. A release binary that dynamically links the builder's libcurl isn't portable, and a glibc-linked one wouldn't work on musl at all. It's set job-wide rather than per-target because the variable is presence-checked — a${{ ... && '1' || '' }}expression evaluates to'', which still reads as set. It only affects Linux either way:curl-sysreturns early with the system libcurl on Apple targets and uses vcpkg on Windows.deny.toml's target list had drifted from reality — musl,x86_64-apple-darwinandx86_64-pc-windows-gnuwere checked but never built, whileaarch64-pc-windows-msvcwas built but never checked. Both lists now match.Release safety
workflow_dispatchonly gated thecreate-releasestep.publishandgithub_releasehad no condition, so a manual dispatch rancargo publish --allow-dirtyagainst crates.io and cut a real GitHub release — while thebuildjob treated that same event as a dry run. Both are now gated, so dispatch is an actual dry run.Not verified locally
There's no Docker/
crosson this machine, so the musl builds themselves are unproven. Now that dispatch is safe, aworkflow_dispatchrun on this branch will exercise all seven targets without publishing — worth doing before merge.Flagged, not fixed
cargo deny checkalso surfacesRUSTSEC-2026-0184—git20.20.4Blame::blame_buffer()null-pointer deref, fixed in 0.21.0. It doesn't fail CI (the advisories step allowsunsound) and submod never calls blame, but it wants a follow-up bump. I left it out to keep a dependency-graph change from also carrying agit2major bump.🤖 Generated with Claude Code
https://claude.ai/code/session_01XocU6NjgZricrRWMLyLXDn