From ee2563c79035a79c41dc179b2364c6a8a65e0e4e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 12:38:35 +0200 Subject: [PATCH 1/6] feat: integrate with `cargo auditable` --- .github/workflows/ci.yml | 3 +++ README.md | 2 ++ action.yml | 5 +++++ main.sh | 37 +++++++++++++++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2dfa9493..b0c96284 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,9 +51,11 @@ jobs: target: aarch64-unknown-linux-gnu build-tool: cargo package: test-crate,test-crate + auditable: true - os: ubuntu-24.04 target: x86_64-unknown-linux-gnu.2.17 build-tool: cargo-zigbuild + auditable: true - os: macos-latest checksums: sha256,sha512,sha1,md5 - os: macos-latest @@ -101,6 +103,7 @@ jobs: bin: test-crate target: ${{ matrix.target }} build-tool: ${{ matrix.build-tool }} + auditable: ${{ matrix.auditable || 'false' }} no-default-features: true all-features: true package: ${{ matrix.package }} diff --git a/README.md b/README.md index 9044d873..e072a3a1 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Currently, this action is basically intended to be used in combination with an a | leading-dir | | Whether to create the leading directory in the archive or not | Boolean | `false` | | bin-leading-dir | | Create extra leading directory(s) for binary file(s) specified by `bin` option | String | | | build-tool | | Tool to build binaries (cargo, cross, or cargo-zigbuild, see [cross-compilation example](#example-workflow-cross-compilation) for more) | String | | +| auditable | | Embed a dependency SBOM into binaries via [cargo-auditable] (cargo and cargo-zigbuild only; not supported with cross) | Boolean | `true` | | ref | | Fully-formed tag ref for this release (see [action.yml](action.yml) for more) | String | | | manifest-path | | Path to Cargo.toml | String | `Cargo.toml` | | profile | | The cargo profile to build. This defaults to the release profile. | String | `release` | @@ -755,6 +756,7 @@ Note that what this action installs for its setup (such as above tools) is consi - [checkout-action]: GitHub Action for checking out a repository. (Simplified actions/checkout alternative that does not depend on Node.js.) [cache-cargo-install-action]: https://github.com/taiki-e/cache-cargo-install-action +[cargo-auditable]: https://github.com/rust-secure-code/cargo-auditable [cargo-zigbuild]: https://github.com/rust-cross/cargo-zigbuild [checkout-action]: https://github.com/taiki-e/checkout-action [create-gh-release-action]: https://github.com/taiki-e/create-gh-release-action diff --git a/action.yml b/action.yml index 5050f887..5991695f 100644 --- a/action.yml +++ b/action.yml @@ -83,6 +83,10 @@ inputs: build_tool: description: Alias for 'build-tool' required: false + auditable: + description: Embed dependency SBOM into binaries using cargo-auditable (cargo and cargo-zigbuild only) + required: false + default: 'true' checksum: description: > Algorithms to be used for checksum (sha256, sha512, b2, sha1, or md5) (whitespace or comma separated list) @@ -195,6 +199,7 @@ runs: INPUT_LEADING_DIR: ${{ inputs.leading-dir || inputs.leading_dir }} INPUT_BIN_LEADING_DIR: ${{ inputs.bin-leading-dir }} INPUT_BUILD_TOOL: ${{ inputs.build-tool || inputs.build_tool }} + INPUT_AUDITABLE: ${{ inputs.auditable }} INPUT_CHECKSUM: ${{ inputs.checksum }} INPUT_TOKEN: ${{ (inputs.dry-run || inputs.dry_run) != 'true' && inputs.token || '' }} INPUT_REF: ${{ inputs.ref }} diff --git a/main.sh b/main.sh index 484b69b8..19fa38e0 100755 --- a/main.sh +++ b/main.sh @@ -228,6 +228,12 @@ if [[ "${build_tool}" == "cargo-zigbuild" ]]; then zigbuild_target="${target}" target="${target%%.*}" fi +auditable="${INPUT_AUDITABLE:-}" +case "${auditable}" in + true) auditable=1 ;; + false | '') auditable='' ;; + *) bail "'auditable' input option must be 'true' or 'false': '${auditable}'" ;; +esac case "${target}" in wasm*) exe=.wasm ;; *-windows*) exe=.exe ;; @@ -288,6 +294,13 @@ if [[ -z "${build_tool}" ]]; then fi fi +if [[ -n "${auditable}" ]] && [[ "${build_tool}" == "cross" ]]; then + # cargo-auditable does not work with cross because cross does not support + # custom cargo subcommands. https://github.com/cross-rs/cross/issues/716 + warn "cargo-auditable is not supported with cross (see https://github.com/cross-rs/cross/issues/716); building without an embedded SBOM" + auditable='' +fi + if [[ "${build_tool}" == "cargo" ]]; then case "${target}" in universal-apple-darwin) retry rustup target add aarch64-apple-darwin x86_64-apple-darwin ;; @@ -386,9 +399,21 @@ if [[ "${rustc_minor_version}" -ge 59 ]] && [[ -z "${CARGO_PROFILE_RELEASE_STRIP fi fi +install_auditable() { + if ! type -P cargo-auditable >/dev/null; then + x cargo install cargo-auditable --locked + fi +} build() { case "${build_tool}" in - cargo) x cargo build "${build_options[@]}" "$@" ;; + cargo) + if [[ -n "${auditable}" ]]; then + install_auditable + x cargo auditable build "${build_options[@]}" "$@" + else + x cargo build "${build_options[@]}" "$@" + fi + ;; cross) if ! type -P cross >/dev/null; then x cargo install cross --locked @@ -404,7 +429,15 @@ build() { universal2-apple-darwin) retry rustup target add aarch64-apple-darwin x86_64-apple-darwin ;; *) retry rustup target add "${target}" ;; esac - x cargo zigbuild "${build_options[@]}" "$@" + if [[ -n "${auditable}" ]]; then + install_auditable + # cargo-auditable must be invoked directly with CARGO pointing at + # cargo-zigbuild; invoking it via cargo would reset the CARGO env. + # https://github.com/rust-cross/cargo-zigbuild/issues/192 + x env CARGO=cargo-zigbuild cargo-auditable auditable build "${build_options[@]}" "$@" + else + x cargo zigbuild "${build_options[@]}" "$@" + fi ;; *) bail "unrecognized build tool '${build_tool}'" ;; esac From 4e8f64aed634e320348894229316ba2478ad003e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 12:56:36 +0200 Subject: [PATCH 2/6] fix: build cargo-auditable for the host --- main.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.sh b/main.sh index 19fa38e0..61ea36a1 100755 --- a/main.sh +++ b/main.sh @@ -401,7 +401,11 @@ fi install_auditable() { if ! type -P cargo-auditable >/dev/null; then - x cargo install cargo-auditable --locked + # Build for the host explicitly: CARGO_BUILD_TARGET may be set in the + # environment (e.g. by setup-cross-toolchain-action), which would otherwise + # cross-compile cargo-auditable for the build target and produce a binary + # that cannot run on the host runner. + x cargo install cargo-auditable --locked --target "${host}" fi } build() { From 08e52c53de035dc28fa88a885b03229be9c0b458 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 13:01:37 +0200 Subject: [PATCH 3/6] ci: verify SBOM gets embedded --- .github/workflows/ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0c96284..39662864 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,6 +116,17 @@ jobs: codesign: '-' codesign-prefix: 'com.example.' codesign-options: 'runtime' + - name: Verify embedded SBOM + if: matrix.auditable + run: | + cargo install rust-audit-info --locked + target="${MATRIX_TARGET%%.*}" # strip cargo-zigbuild . suffix + bin="test-crate/target/${target:+${target}/}release/test-crate" + # rust-audit-info exits non-zero (and prints "No audit data found") if + # the binary does not contain a cargo-auditable SBOM. + rust-audit-info "${bin}" + env: + MATRIX_TARGET: ${{ matrix.target }} - name: Check action outputs run: | printf 'outputs.archive should not be empty\n' From 1eab488a35e7106afa6b51e5da3d47bd7af9785c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 13:29:40 +0200 Subject: [PATCH 4/6] ci: also test windows and macos --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39662864..f68361d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,6 +69,7 @@ jobs: - os: macos-latest checksums: sha256 sha512 sha1 md5 target: aarch64-apple-darwin + auditable: true - os: macos-latest checksums: sha256, sha512, sha1, md5 target: universal-apple-darwin @@ -77,6 +78,7 @@ jobs: target: universal-apple-darwin build-tool: cargo - os: windows-latest + auditable: true - os: windows-latest target: x86_64-pc-windows-gnu - os: windows-latest From b307fc71c4d7066fcc06160496fd5ecf275e7d25 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 13:33:48 +0200 Subject: [PATCH 5/6] ci: build rust-audit-info for the host --- .github/workflows/ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f68361d8..987e01ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,7 +121,11 @@ jobs: - name: Verify embedded SBOM if: matrix.auditable run: | - cargo install rust-audit-info --locked + # Install the reader for the host: CARGO_BUILD_TARGET may be set (e.g. + # by setup-cross-toolchain-action), which would otherwise cross-compile + # rust-audit-info for the build target so it could not run here. + host=$(rustc -vV | grep -E '^host:' | cut -d' ' -f2) + cargo install rust-audit-info --locked --target "${host}" target="${MATRIX_TARGET%%.*}" # strip cargo-zigbuild . suffix bin="test-crate/target/${target:+${target}/}release/test-crate" # rust-audit-info exits non-zero (and prints "No audit data found") if From 2531dc4738530043d37c15a03a5a8b05dc722089 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 2 Jun 2026 13:40:34 +0200 Subject: [PATCH 6/6] ci: append extension on windows --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 987e01ed..b3092345 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,7 +127,9 @@ jobs: host=$(rustc -vV | grep -E '^host:' | cut -d' ' -f2) cargo install rust-audit-info --locked --target "${host}" target="${MATRIX_TARGET%%.*}" # strip cargo-zigbuild . suffix - bin="test-crate/target/${target:+${target}/}release/test-crate" + exe='' + case "${target:-${host}}" in *-windows*) exe=.exe ;; esac + bin="test-crate/target/${target:+${target}/}release/test-crate${exe}" # rust-audit-info exits non-zero (and prints "No audit data found") if # the binary does not contain a cargo-auditable SBOM. rust-audit-info "${bin}"