#!/usr/bin/env bash # 一个组件在所有平台、所有架构的发布压缩包里的可执行文件的 SHA-256(逗号分隔,输出到标准输出)。 # ci/release-binary-hashes.sh <版本,不带 v> 环境变量:GITEA_BASE、NETRC(curl 的 netrc 文件) # 签名的发布清单里的 binaries 就是它:节点握手时上报正在运行的可执行文件的哈希,Backend 凭 CI 签名的清单认「官方二进制」—— # 容器、Linux glibc/musl 压缩包、macOS、Windows 的 x64/arm64 都一样,不只是容器镜像里的那两个。 set -euo pipefail component="${1:?usage: release-binary-hashes.sh }"; version="${2:?version}" [[ "$component" =~ ^(agent|probe)$ ]] || { echo "component must be agent or probe" >&2; exit 2; } gitea_base="${GITEA_BASE:?GITEA_BASE is required}"; gitea_base="${gitea_base%/}" netrc=(); [[ -n "${NETRC:-}" ]] && netrc=(--netrc-file "$NETRC") work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT # 和 ci/publish-gitea-release.sh 里发布的那 8 种一样(每个组件) targets=(linux-amd64 linux-arm64 linux-musl-amd64 linux-musl-arm64 macos-x64 macos-arm64 windows-amd64 windows-arm64) hashes=() for target in "${targets[@]}"; do if [[ "$target" == windows-* ]]; then archive="moshiro-$component-v$version-$target.zip"; member="moshiro-$component.exe" else archive="moshiro-$component-v$version-$target.tar.gz"; member="moshiro-$component"; fi curl --fail --silent --show-error --retry 3 ${netrc[@]+"${netrc[@]}"} "$gitea_base/api/packages/justme/generic/moshiro-node/$version/$archive" -o "$work/$archive" if [[ "$archive" == *.zip ]]; then hash="$(cd "$work" && python3 -c 'import hashlib,sys,zipfile; print(hashlib.sha256(zipfile.ZipFile(sys.argv[1]).read(sys.argv[2])).hexdigest())' "$archive" "$member")" else hash="$(tar -xzOf "$work/$archive" "$member" | sha256sum | cut -d' ' -f1)" fi [[ "$hash" =~ ^[0-9a-f]{64}$ ]] || { echo "could not hash $member in $archive" >&2; exit 1; } hashes+=("$hash") rm -f "$work/$archive" done # 不同平台的二进制哈希不会相同;去重只是防御 printf '%s\n' "${hashes[@]}" | sort -u | paste -sd,