From 59b57a4970e4ffddb0eed1cd280d5a9b0aaed044 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Tue, 18 Aug 2026 19:10:07 +0800 Subject: [PATCH] fix: make the windows zip independent of locale and timezone With file modes normalized, the four tarballs reproduced byte for byte across hosts but the Windows zip still did not. Two host properties were leaking into it: - Entry order. The archive is fed by `find | sort`, and sort honours the locale. A ru_RU.UTF-8 host emits docs/ before LICENSE; a C locale emits the reverse. Same files, different archive. - Timestamps. zip records DOS local time with no zone attached, so building at UTC+08 embedded 19:06 where ubuntu-latest embedded 11:06 for the same commit. Pin LC_ALL=C and TZ=UTC for the packaging subshell. Building the same commit under ru_RU.UTF-8/Asia-Shanghai and under C/UTC now yields one hash. The tarballs never had either problem: tar sorts internally by byte value and stores Unix epochs, so neither locale nor zone reaches the output. Co-Authored-By: Claude Opus 5 --- release.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/release.sh b/release.sh index 524f93f..312b6bb 100755 --- a/release.sh +++ b/release.sh @@ -71,7 +71,14 @@ build_zip() { GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED=0 go build -trimpath -ldflags "${LDFLAGS}" -o "${package_dir}/${APP}.exe" . package_docs "${package_dir}" normalize_package "${package_dir}" "${APP}.exe" - (cd "${DIST_DIR}" && find "$(basename "${package_dir}")" -print | sort | zip -X -q "$(basename "${archive}")" -@) + # LC_ALL=C: `sort` is locale-sensitive, and it decides the entry order here. + # A ru_RU.UTF-8 host orders docs/ before LICENSE where a C locale does the + # reverse, producing a different archive from identical files. + # + # TZ=UTC: zip records DOS local time with no zone, so the same build in + # +08:00 and in UTC would embed different timestamps. tar needs neither — + # it sorts internally and stores Unix epochs. + (cd "${DIST_DIR}" && export LC_ALL=C TZ=UTC && find "$(basename "${package_dir}")" -print | sort | zip -X -q "$(basename "${archive}")" -@) rm -rf "${package_dir}" }