Use cargo auditable to include SBOM in uv builds (#18276)

Inspired by #18252 

This required an upstream change
https://github.com/rust-secure-code/cargo-auditable/pull/245 which is
now released.

This increases binary sizes slightly, ~4KB.

The cargo wrapper implementation will be extended in #18280 to code sign
binaries.
This commit is contained in:
Zanie Blue
2026-03-06 11:38:02 -06:00
committed by GitHub
parent 12caaf3160
commit 9345450b4c
6 changed files with 243 additions and 13 deletions
+88 -10
View File
@@ -97,6 +97,9 @@ jobs:
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Install cargo extensions"
shell: bash
run: scripts/install-cargo-extensions.sh
# uv
- name: "Build wheels - x86_64"
@@ -105,6 +108,8 @@ jobs:
maturin-version: v1.12.6
target: x86_64
args: --release --locked --out dist --features self-update --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Upload wheels"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
@@ -136,6 +141,8 @@ jobs:
maturin-version: v1.12.6
target: x86_64
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
@@ -156,6 +163,9 @@ jobs:
architecture: arm64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Install cargo extensions"
shell: bash
run: scripts/install-cargo-extensions.sh
# uv
- name: "Build wheels - aarch64"
@@ -165,6 +175,8 @@ jobs:
target: aarch64
manylinux: 2_17
args: --release --locked --out dist --features self-update --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel - aarch64"
run: |
pip install ${PACKAGE_NAME} --no-index --find-links dist/ --force-reinstall
@@ -202,6 +214,8 @@ jobs:
maturin-version: v1.12.6
target: aarch64
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel - aarch64"
run: |
pip install ${PACKAGE_NAME}_build --no-index --find-links crates/uv-build/dist --force-reinstall
@@ -239,6 +253,9 @@ jobs:
architecture: ${{ matrix.platform.arch }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Install cargo extensions"
shell: bash
run: scripts/install-cargo-extensions.sh
# uv
- name: "Build wheels"
@@ -247,6 +264,8 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
args: --release --locked --out dist --features self-update,windows-gui-bin --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.cmd
- name: "Test wheel"
shell: bash
run: |
@@ -285,6 +304,8 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
env:
CARGO: ${{ github.workspace }}/scripts/cargo.cmd
- name: "Test wheel uv-build"
shell: bash
run: |
@@ -328,6 +349,7 @@ jobs:
# from 64-bit version of the container, breaking the pattern from other builds.
container: quay.io/pypa/manylinux2014
manylinux: 2_17
docker-options: -e CARGO
args: --release --locked --out dist --features self-update --compatibility pypi
# See: https://github.com/sfackler/rust-openssl/issues/2036#issuecomment-1724324145
before-script-linux: |
@@ -349,8 +371,11 @@ jobs:
# If we're running on debian-based system.
apt update -y && apt-get install -y libssl-dev openssl pkg-config
fi
# Install cargo extensions as a static musl binary so it runs in any container.
scripts/install-cargo-extensions.sh
env:
CC: ${{ matrix.cc }}
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel"
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
@@ -391,7 +416,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.target }}
manylinux: 2_17
docker-options: -e CARGO
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel uv-build"
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
@@ -445,8 +475,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: ${{ matrix.platform.manylinux }}
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --release --locked --out dist --features self-update --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel"
with:
@@ -498,8 +532,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: ${{ matrix.platform.manylinux }}
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel uv-build"
with:
@@ -552,9 +590,13 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_17
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --release --locked --out dist --features self-update --compatibility pypi
rust-toolchain: ${{ matrix.platform.toolchain || null }}
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel"
with:
@@ -606,8 +648,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_17
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel uv-build"
with:
@@ -661,7 +707,7 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_17
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --release --locked --out dist --features self-update --compatibility pypi
before-script-linux: |
if command -v yum &> /dev/null; then
@@ -670,6 +716,9 @@ jobs:
yum repolist
yum install -y gcc-powerpc64-linux-gnu
fi
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
# TODO(charlie): Re-enable testing for PPC wheels.
# - uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
# name: "Test wheel"
@@ -719,7 +768,7 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_17
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
if command -v yum &> /dev/null; then
@@ -728,6 +777,9 @@ jobs:
yum repolist
yum install -y gcc-powerpc64-linux-gnu
fi
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
# TODO(charlie): Re-enable testing for PPC wheels.
- name: "Upload wheels uv-build"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
@@ -764,8 +816,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_31
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --release --locked --out dist --features self-update --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel"
with:
@@ -818,8 +874,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.platform.target }}
manylinux: 2_31
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel uv-build"
with:
@@ -871,7 +931,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.target }}
manylinux: musllinux_1_1
docker-options: -e CARGO
args: --release --locked --out dist --features self-update --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel"
if: matrix.target == 'x86_64-unknown-linux-musl'
run: |
@@ -918,7 +983,12 @@ jobs:
maturin-version: v1.12.6
target: ${{ matrix.target }}
manylinux: musllinux_1_1
docker-options: -e CARGO
args: --profile minimal-size --locked --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- name: "Test wheel uv-build"
if: matrix.target == 'x86_64-unknown-linux-musl'
run: |
@@ -970,8 +1040,12 @@ jobs:
manylinux: musllinux_1_1
# Tag the musl builds as manylinux 2_17 fallback cause the aarch64 build only support 2_28
args: --release --locked --out dist --features self-update --compatibility 2_17 --compatibility pypi
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
rust-toolchain: ${{ matrix.platform.toolchain || null }}
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel"
with:
@@ -1043,8 +1117,12 @@ jobs:
target: ${{ matrix.platform.target }}
manylinux: musllinux_1_1
args: --profile minimal-size --locked ${{ matrix.platform.arch == 'aarch64' && '--compatibility 2_17' || ''}} --out crates/uv-build/dist -m crates/uv-build/Cargo.toml --compatibility pypi
docker-options: ${{ matrix.platform.maturin_docker_options }}
docker-options: -e CARGO ${{ matrix.platform.maturin_docker_options }}
rust-toolchain: ${{ matrix.platform.toolchain || null }}
before-script-linux: |
scripts/install-cargo-extensions.sh
env:
CARGO: ${{ github.workspace }}/scripts/cargo.sh
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: "Test wheel"
with:
+2 -3
View File
@@ -50,11 +50,10 @@ COPY crates crates
COPY ./Cargo.toml Cargo.toml
COPY ./Cargo.lock Cargo.lock
# Install patched cargo-auditable with Zig linker support
# Install cargo-auditable
RUN cargo install \
--git https://github.com/rust-secure-code/cargo-auditable.git \
--rev caa964b714d8da6b1139b8e7a0a2ba5979235f22 \
--locked \
--version 0.7.4 \
cargo-auditable
RUN case "${TARGETPLATFORM}" in \
+15
View File
@@ -0,0 +1,15 @@
@echo off
REM Wrapper script that invokes `cargo auditable` instead of plain `cargo`.
REM
REM Use `scripts/install-cargo-extensions.sh` to install the dependencies.
REM
REM Usage:
REM
REM set CARGO=%CD%\scripts\cargo.cmd
REM cargo build --release
if defined REAL_CARGO (
"%REAL_CARGO%" auditable %*
) else (
cargo.exe auditable %*
)
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env sh
## Wrapper script that invokes `cargo auditable` instead of plain `cargo`.
##
## Use `scripts/install-cargo-extensions.sh` to install the dependencies.
##
## Usage:
##
## CARGO="$PWD/scripts/cargo.sh" cargo build --release
set -eu
if [ -n "${REAL_CARGO:-}" ]; then
exec "$REAL_CARGO" auditable "$@"
else
exec cargo auditable "$@"
fi
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env bash
## Verify that all release artifacts contain cargo-auditable SBOM data.
##
## Requires:
## cargo install rust-audit-info --locked
##
## Usage:
## scripts/check-release-artifact-sboms.sh <run-id>
set -euo pipefail
if [ $# -ne 1 ]; then
echo "Usage: $0 <github-actions-run-id>" >&2
exit 1
fi
missing=""
command -v gh >/dev/null 2>&1 || missing="$missing gh"
command -v rust-audit-info >/dev/null 2>&1 || missing="$missing rust-audit-info"
if [ -n "$missing" ]; then
echo "error: missing required tools:$missing" >&2
exit 1
fi
RUN_ID="$1"
WORKDIR="$(mktemp -d)"
trap 'rm -rf "$WORKDIR"' EXIT
PASS=0
FAIL=0
pass() { echo "PASS $1"; PASS=$((PASS + 1)); }
fail() { echo "FAIL $1"; FAIL=$((FAIL + 1)); }
check() {
local binary="$1"
local label="$2"
if rust-audit-info "$binary" >/dev/null 2>&1; then
pass "$label"
else
fail "$label"
fi
}
echo "Fetching artifacts for run $RUN_ID..."
ALL_ARTIFACTS=$(gh api "repos/{owner}/{repo}/actions/runs/$RUN_ID/artifacts" \
--paginate --jq '.artifacts[].name')
echo ""
for artifact in $ALL_ARTIFACTS; do
case "$artifact" in
artifacts-*) ;;
*) continue ;;
esac
dest="$WORKDIR/$artifact"
gh run download "$RUN_ID" -n "$artifact" -D "$dest"
# Extract the archive.
for tarball in "$dest"/*.tar.gz; do
[ -f "$tarball" ] || continue
tar xzf "$tarball" -C "$dest"
done
for zip in "$dest"/*.zip; do
[ -f "$zip" ] || continue
unzip -qo "$zip" -d "$dest"
done
# Find the archive name for labeling.
archive=""
for f in "$dest"/*.tar.gz "$dest"/*.zip; do
[ -f "$f" ] && archive=$(basename "$f") && break
done
# Check uv and uvx binaries.
for bin in uv uvx; do
binary=$(find "$dest" \( -name "$bin" -o -name "$bin.exe" \) -type f | head -1)
if [ -n "$binary" ]; then
check "$binary" "${archive:-$artifact} / $(basename "$binary")"
fi
done
done
echo ""
echo "PASS $PASS / FAIL $FAIL"
if [ "$FAIL" -gt 0 ]; then
exit 1
fi
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env sh
## Install cargo extensions for release builds.
##
## Installs cargo-auditable for SBOM embedding.
##
## Includes handling for cross-build containers in our release workflow.
##
## Usage:
##
## $ scripts/install-cargo-extensions.sh
##
## Expected to be used with `scripts/cargo.sh`.
set -eu
CARGO_AUDITABLE_INSTALL="cargo install cargo-auditable \
--locked \
--version 0.7.4"
# In Linux containers running on x86_64, build a static musl binary so the installed tool works in
# musl-based environments (Alpine, etc.).
#
# On i686 containers the 32-bit linker can't produce 64-bit musl binaries, so we fall back to a
# default build.
if [ "$(uname -m 2>/dev/null)" = "x86_64" ] && [ "$(uname -s 2>/dev/null)" = "Linux" ]; then
MUSL_TARGET="x86_64-unknown-linux-musl"
rustup target add "$MUSL_TARGET"
CC=gcc $CARGO_AUDITABLE_INSTALL --target "$MUSL_TARGET"
else
$CARGO_AUDITABLE_INSTALL
fi