From 34b29610e744c102f5f9747a2a7e985c99e381db Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 11 Nov 2025 20:31:15 +0000 Subject: [PATCH] Generate both checksums.txt and .sha256 files for backward compatibility Following best practices for release format transitions: - build-release.sh now generates both formats from same sha256sum run - Workflow uploads both checksums.txt and individual .sha256 files - Validation ensures both formats exist and match This provides a safe transition period for users with older install scripts while maintaining the cleaner checksums.txt format going forward. After 2-3 releases when most users have updated scripts, we can remove .sha256 generation. Related: Install script already supports both formats (falls back gracefully). --- .github/workflows/release.yml | 4 ++++ scripts/build-release.sh | 11 +++++++++-- scripts/validate-release.sh | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 51b22e8..f4967cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -244,6 +244,10 @@ jobs: echo "Uploading checksums.txt..." gh release upload "${TAG}" release/checksums.txt + # Upload individual .sha256 files for backward compatibility + echo "Uploading .sha256 checksum files..." + gh release upload "${TAG}" release/*.sha256 + - name: Upload release assets env: GH_TOKEN: ${{ github.token }} diff --git a/scripts/build-release.sh b/scripts/build-release.sh index b0e0bfc..ae6d9c9 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -321,8 +321,15 @@ fi if [ ${#checksum_files[@]} -eq 0 ]; then echo "Warning: no release artifacts found to checksum." else - # Generate checksums.txt with sorted output for deterministic results (prevents #671 checksum mismatches) - sha256sum "${checksum_files[@]}" | sort -k 2 > checksums.txt + # Generate checksums from a single sha256sum run for deterministic results (prevents #671 checksum mismatches) + checksum_output="$(sha256sum "${checksum_files[@]}" | sort -k 2)" + printf '%s\n' "$checksum_output" > checksums.txt + + # Emit per-file .sha256 artifacts for backward compatibility while legacy installers transition off them + while IFS= read -r checksum filename; do + printf '%s %s\n' "$checksum" "$filename" > "${filename}.sha256" + done <<< "$checksum_output" + if [ -n "${SIGNING_KEY_ID:-}" ]; then if command -v gpg >/dev/null 2>&1; then echo "Signing checksums with GPG key ${SIGNING_KEY_ID}..." diff --git a/scripts/validate-release.sh b/scripts/validate-release.sh index 8e81d89..ba123c7 100755 --- a/scripts/validate-release.sh +++ b/scripts/validate-release.sh @@ -200,6 +200,28 @@ info "Validating checksums..." sha256sum -c checksums.txt >/dev/null 2>&1 || { error "checksums.txt validation failed"; exit 1; } success "checksums.txt validated" +# Validate individual .sha256 files exist and match checksums.txt +info "Validating individual .sha256 files..." +while IFS= read -r line; do + checksum=$(echo "$line" | awk '{print $1}') + filename=$(echo "$line" | awk '{print $2}') + + # Check .sha256 file exists + if [ ! -f "${filename}.sha256" ]; then + error "Missing ${filename}.sha256" + exit 1 + fi + + # Check .sha256 file content matches checksums.txt + sha256_content=$(cat "${filename}.sha256") + expected_content="${checksum} ${filename}" + if [ "$sha256_content" != "$expected_content" ]; then + error "${filename}.sha256 content mismatch" + exit 1 + fi +done < checksums.txt +success "Individual .sha256 files validated" + popd >/dev/null echo ""