diff --git a/.githooks/pre-commit b/.githooks/pre-commit old mode 100644 new mode 100755 diff --git a/.githooks/pre-push b/.githooks/pre-push index 2f08a7f..09ecefa 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -7,10 +7,19 @@ cd "$repo_root" cargo fmt --check cargo check cargo test -./scripts/generate-sbom.sh spdx +# SBOM freshness is advisory, not a hard gate: the SBOM is not checked in CI or +# at release time, and `cargo sbom` output varies between tool versions (e.g. the +# set of per-target dependencies it enumerates), so a byte-exact diff would fail +# spuriously for anyone whose cargo-sbom differs from whoever last committed it. +# Warn (and restore the working tree) instead of blocking the push. +./scripts/generate-sbom.sh spdx if ! git diff --quiet -- sbom/rusty-wire.spdx.json; then - echo "error: sbom/rusty-wire.spdx.json was updated. Commit the refreshed SPDX SBOM before pushing." >&2 - git --no-pager diff -- sbom/rusty-wire.spdx.json >&2 || true - exit 1 + echo "warning: the regenerated SPDX SBOM differs from the committed one." >&2 + echo " If this reflects a real dependency change (Cargo.lock), run" >&2 + echo " 'make sbom' with the pinned cargo-sbom version and commit the" >&2 + echo " refreshed sbom/ files. If it is only a cargo-sbom version" >&2 + echo " difference, no action is needed. (Not blocking the push.)" >&2 + # Don't leave the developer's tree dirty with the regenerated file. + git checkout -- sbom/rusty-wire.spdx.json 2>/dev/null || true fi diff --git a/scripts/generate-sbom.sh b/scripts/generate-sbom.sh index de80292..776ed4c 100755 --- a/scripts/generate-sbom.sh +++ b/scripts/generate-sbom.sh @@ -9,12 +9,24 @@ fi format="${1:-spdx}" out_file="${2:-}" +# Pin the cargo-sbom version so the committed SBOM is reproducible. Different +# cargo-sbom releases enumerate different per-target dependency sets, which would +# otherwise make the SBOM churn between contributors' machines. +PINNED_SBOM_VERSION="0.10.0" + if ! cargo --list | grep -q '^ sbom'; then echo "error: cargo-sbom is not installed." >&2 - echo "install it with: cargo install cargo-sbom" >&2 + echo "install the pinned version with: cargo install cargo-sbom --version $PINNED_SBOM_VERSION --locked" >&2 exit 1 fi +installed_sbom_version="$(cargo sbom --version 2>/dev/null | awk 'NR==1{print $NF}')" +if [[ -n "$installed_sbom_version" && "$installed_sbom_version" != "$PINNED_SBOM_VERSION" ]]; then + echo "warning: cargo-sbom $installed_sbom_version differs from the pinned $PINNED_SBOM_VERSION;" >&2 + echo " the generated SBOM may differ from the committed one. To match, run:" >&2 + echo " cargo install cargo-sbom --version $PINNED_SBOM_VERSION --locked" >&2 +fi + case "$format" in spdx) jsonq=""