igneum/tools/ci/commit-string-check.sh

33 lines
2.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# The empty-commit class (6 October 2026, found on igneum-build-1): the fork's kaspa-build-info embeds the git commit in
# igneumd and igneum-miner only when the source tree's .git is a DIRECTORY whose HEAD is a symbolic ref to a branch file,
# and once its build script has found nothing it emits no rerun-if-changed, so a persistent target dir keeps the empty hash
# for ever. Every Mac worktree build (.git is a file there) and every PC job build (the zip has no .git) shipped with no
# commit string while the release plans' "commit in its strings" line was being ticked from main-checkout builds.
# Rule: an igneumd binary whose strings do not contain its short commit fails (igneum-miner has no kaspa-build-info
# dependency and never carried one; checked 6 October 2026). tools/build-remote.sh, tools/cross-remote.sh and
# proto-cuda/windows-node/cross-build.sh run this on every igneumd they produce; the shipper's preflight should too.
#
# tools/ci/commit-string-check.sh <binary> <commit sha, 7 to 40 hex> exit 0 when the binary carries the commit
# tools/ci/commit-string-check.sh --self-test fires on a known-bad and passes a known-good case
set -euo pipefail
if [ "${1:-}" = --self-test ]; then
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
printf 'igneumd v2.1.0-3bfe346f\0junk\0' > "$tmp/good"; printf 'igneumd v2.1.0\0junk\0' > "$tmp/bad"
"$0" "$tmp/good" 3bfe346f4de0d9a982627270c791b7855abc5af6 >/dev/null || { echo "commit-string self-test: the good case FAILED"; exit 1; }
if "$0" "$tmp/bad" 3bfe346f4de0d9a982627270c791b7855abc5af6 >/dev/null 2>&1; then echo "commit-string self-test: the bad case PASSED (the gate is blind)"; exit 1; fi
echo "commit-string self-test: fires on the empty binary, passes the stamped one"; exit 0
fi
bin="${1:-}"; sha="${2:-}"
[ -f "$bin" ] && [ -n "$sha" ] || { echo "usage: commit-string-check.sh <binary> <commit sha> | --self-test" >&2; exit 2; }
printf '%s' "$sha" | grep -qE '^[0-9a-f]{7,40}$' || { echo "commit-string: '$sha' is not a commit sha" >&2; exit 2; }
short="${sha:0:7}" # build-info's fallback embeds 7 characters; git rev-parse --short gives 7 or more, all starting the same
# grep -c, not grep -q: -q closes the pipe at the first match, strings dies with SIGPIPE and pipefail turns a hit into a miss
# (the first version of this gate failed a stamped binary that way, 6 October 2026)
hits=$(strings "$bin" | grep -c "$short" || true)
if [ "${hits:-0}" -gt 0 ]; then
echo "commit-string: $(basename "$bin") carries $short"
else
echo "commit-string: $(basename "$bin") does NOT carry its commit $short (kaspa-build-info found no .git directory on a branch; see the header)" >&2
exit 1
fi