Files
dingtalk-workspace-cli/scripts/release/verify-release-artifacts.sh
T

108 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
set -eu
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/../.." && pwd)"
DIST_DIR="${DWS_PACKAGE_DIST_DIR:-$ROOT/dist}"
VERSION="${1:-${DWS_PACKAGE_VERSION:-}}"
[ -n "$VERSION" ] || { printf 'expected release version is required\n' >&2; exit 2; }
SEMVER="${VERSION#v}"
CHECKSUMS="$DIST_DIR/checksums.txt"
EXPECTED_PLATFORM_ASSETS="
dws-darwin-amd64.tar.gz
dws-darwin-arm64.tar.gz
dws-linux-amd64.tar.gz
dws-linux-arm64.tar.gz
dws-windows-amd64.zip
dws-windows-arm64.zip
"
EXPECTED_ASSETS="$EXPECTED_PLATFORM_ASSETS
dws-skills.zip
"
[ -f "$CHECKSUMS" ] || { printf 'missing checksums.txt in %s\n' "$DIST_DIR" >&2; exit 1; }
tmp="$(mktemp -d "${TMPDIR:-/tmp}/dws-release-binary.XXXXXX")"
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
# The public asset namespace is an exact set. GoReleaser may also leave local
# metadata files (artifacts.json/config.yaml/metadata.json), but the upload and
# npm staging globs never publish them.
printf '%s\nchecksums.txt\n' "$EXPECTED_ASSETS" | sed '/^$/d' | LC_ALL=C sort > "$tmp/expected-root"
for path in "$DIST_DIR"/dws-*.tar.gz "$DIST_DIR"/dws-*.zip "$CHECKSUMS"; do
[ -f "$path" ] || continue
basename "$path"
done | LC_ALL=C sort > "$tmp/actual-root"
if ! diff -u "$tmp/expected-root" "$tmp/actual-root"; then
printf 'public release assets must contain exactly the supported files\n' >&2
exit 1
fi
checksum_format_ok=1
awk '
NF != 2 { bad = 1; next }
$1 !~ /^[0-9a-fA-F]{64}$/ { bad = 1; next }
{ print $2 }
END { if (bad) exit 1 }
' "$CHECKSUMS" > "$tmp/checksum-assets" || checksum_format_ok=0
[ "$checksum_format_ok" -eq 1 ] || {
printf 'checksums.txt must contain only SHA-256 and filename pairs\n' >&2
exit 1
}
skills_checksum_count="$(awk '$2 == "dws-skills.zip" { count++ } END { print count + 0 }' "$CHECKSUMS")"
[ "$skills_checksum_count" -eq 1 ] || {
printf 'checksums.txt must contain dws-skills.zip exactly once (found %s)\n' "$skills_checksum_count" >&2
exit 1
}
printf '%s\n' "$EXPECTED_ASSETS" | sed '/^$/d' | LC_ALL=C sort > "$tmp/expected-checksums"
LC_ALL=C sort "$tmp/checksum-assets" > "$tmp/actual-checksums"
if ! diff -u "$tmp/expected-checksums" "$tmp/actual-checksums"; then
printf 'checksums.txt must describe exactly the supported release assets\n' >&2
exit 1
fi
if command -v sha256sum >/dev/null 2>&1; then
(cd "$DIST_DIR" && sha256sum --check checksums.txt)
elif command -v shasum >/dev/null 2>&1; then
(cd "$DIST_DIR" && shasum -a 256 --check checksums.txt)
else
printf 'sha256sum or shasum is required\n' >&2
exit 1
fi
verify_binary_version() {
asset="$1"
extract_dir="$tmp/extract-${asset}"
mkdir -p "$extract_dir"
case "$asset" in
*.tar.gz)
tar -xzf "$DIST_DIR/$asset" -C "$extract_dir"
binary="$extract_dir/dws"
;;
*.zip)
unzip -q "$DIST_DIR/$asset" -d "$extract_dir"
binary="$extract_dir/dws.exe"
;;
*)
printf 'unsupported release archive: %s\n' "$asset" >&2
return 1
;;
esac
[ -f "$binary" ] || {
printf '%s does not contain the expected dws binary\n' "$asset" >&2
return 1
}
LC_ALL=C grep -aFq "v$SEMVER" "$binary" || {
printf '%s binary does not embed expected version v%s\n' "$asset" "$SEMVER" >&2
return 1
}
}
for asset in $EXPECTED_PLATFORM_ASSETS; do
verify_binary_version "$asset"
done
printf 'Release artifacts verified for v%s.\n' "$SEMVER"