diff --git a/scripts/verify-release-artifacts.sh b/scripts/verify-release-artifacts.sh index 8b0f154..3e7c845 100644 --- a/scripts/verify-release-artifacts.sh +++ b/scripts/verify-release-artifacts.sh @@ -22,6 +22,70 @@ artifact_version() { esac } +archive_contains() { + artifact="$1" + member="$2" + case "$artifact" in + *.tar.gz) + tar -tzf "$artifact" "$member" >/dev/null 2>&1 + ;; + *.zip) + unzip -Z1 "$artifact" 2>/dev/null | grep -Fx "$member" >/dev/null 2>&1 + ;; + *) + return 1 + ;; + esac +} + +expected_members() { + artifact_name="$(basename -- "$1")" + case "$artifact_name" in + dosh-windows-*.zip) + cat </dev/null 2>&1; then + sha256sum "$artifact" | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$artifact" | awk '{print $1}' + else + return 1 + fi +} + +verify_checksum() { + artifact="$1" + checksum="$artifact.sha256" + expected="$(awk '{print $1; exit}' "$checksum")" + actual="$(checksum_value "$artifact" || true)" + [ -n "$actual" ] && [ "$actual" = "$expected" ] +} + if [ "$#" -gt 0 ]; then artifacts="$*" else @@ -38,12 +102,21 @@ for artifact in $artifacts; do if [ ! -f "$artifact.sha256" ]; then echo "missing release checksum: $artifact.sha256" >&2 failed=1 + elif ! verify_checksum "$artifact"; then + echo "release checksum mismatch: $artifact" >&2 + failed=1 fi actual="$(artifact_version "$artifact" || true)" if [ "$actual" != "$version" ]; then echo "artifact version mismatch: $artifact has ${actual:-unknown}, expected $version" >&2 failed=1 fi + for member in $(expected_members "$artifact"); do + if ! archive_contains "$artifact" "$member"; then + echo "artifact missing expected member: $artifact:$member" >&2 + failed=1 + fi + done done exit "$failed" diff --git a/tests/release_scripts.rs b/tests/release_scripts.rs index 9eda2e8..9a69c94 100644 --- a/tests/release_scripts.rs +++ b/tests/release_scripts.rs @@ -244,6 +244,29 @@ fn complete_release_verifier_requires_both_macos_architectures() { assert!(verify.contains("dosh-windows-x86_64.zip")); } +#[test] +fn release_verifier_checks_checksums_and_expected_binaries() { + let verify = include_str!("../scripts/verify-release-artifacts.sh"); + assert!(verify.contains("verify_checksum()")); + assert!(verify.contains("release checksum mismatch")); + for member in [ + "dosh/bin/dosh", + "dosh/bin/dosh-client", + "dosh/bin/dosh-server", + "dosh/bin/dosh-auth", + "dosh/bin/dosh-bench", + "dosh/bin/dosh.exe", + "dosh/bin/dosh-client.exe", + "dosh/bin/dosh-bench.exe", + ] { + assert!( + verify.contains(member), + "release verifier must require archive member {member}" + ); + } + assert!(verify.contains("artifact missing expected member")); +} + #[test] fn package_release_stamps_git_build_info() { let package = include_str!("../scripts/package-release.sh");