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 <noreply@anthropic.com>
This commit is contained in:
mirivlad 2026-08-18 19:10:07 +08:00
parent 878f7b4472
commit 59b57a4970
1 changed files with 8 additions and 1 deletions

View File

@ -71,7 +71,14 @@ build_zip() {
GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED=0 go build -trimpath -ldflags "${LDFLAGS}" -o "${package_dir}/${APP}.exe" . GOOS="${goos}" GOARCH="${goarch}" CGO_ENABLED=0 go build -trimpath -ldflags "${LDFLAGS}" -o "${package_dir}/${APP}.exe" .
package_docs "${package_dir}" package_docs "${package_dir}"
normalize_package "${package_dir}" "${APP}.exe" 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}" rm -rf "${package_dir}"
} }