fix(builder): 版本时间格式改回 YYYYMMDDTHHMM

按要求保留字母分隔符:20260918T1722。分钟精度不变,同一分支同日多次
构建仍能正确排序。

记录切换边界:Debian 里字母排在标点之前,YYYYMMDDT… 小于旧格式的
YYYYMMDD.…,切换当天同日的旧格式包会压住新包,需要在仓库里把那些旧包
移除或停用;次日新格式始终更大。回归测试显式断言这行边界。
This commit is contained in:
2026-09-19 13:32:16 +08:00
parent eb2d0ce651
commit e60755f280
4 changed files with 58 additions and 47 deletions
+17 -18
View File
@@ -11,19 +11,20 @@ With --docker, print the Docker tag rendering of that version.
Derivation (builder contract «版本号»):
official HEAD exact-match of vX.Y.Z → X.Y.Z
test nearest ancestor stable tag vX.Y.Z → X.Y.(Z+1)~YYYYMMDDHHMM.branch.n+gSHA
no tag no stable tag reachable from HEAD → 0.0.0~YYYYMMDDHHMM.branch+gSHA
test nearest ancestor stable tag vX.Y.Z → X.Y.(Z+1)~YYYYMMDDTHHMM.branch.n+gSHA
no tag no stable tag reachable from HEAD → 0.0.0~YYYYMMDDTHHMM.branch+gSHA
YYYYMMDDHHMM is the build minute (day plus time of day), with no separator:
the digits must stay in one run so Debian compares them numerically. A letter
separator (YYYYMMDDTHHMM) would compare *below* the bare date, because Debian
orders letters before punctuation — same-day packages built with the old
date-only scheme would outrank the new ones. SOURCE_DATE_EPOCH, if set, is
that instant in UTC; otherwise the local date and time. Official X.Y.Z never
gets a date. Minute precision is required for apt: Debian version comparison
ignores upload order, so same-day rebuilds that differ only in +gSHA compare
as arbitrary text (a newer build can sort below an older one). With the minute
in the version, later builds always compare greater.
YYYYMMDDTHHMM is the build minute (day plus time of day). SOURCE_DATE_EPOCH,
if set, is that instant in UTC; otherwise the local date and time. Official
X.Y.Z never gets a date. Minute precision is required for apt: Debian version
comparison ignores upload order, so same-day rebuilds that differ only in
+gSHA compare as arbitrary text (a newer build can sort below an older one).
Switching from the date-only scheme: Debian orders letters below punctuation,
so 'YYYYMMDDT…' compares *below* the old 'YYYYMMDD.…' form. Packages built on
the switch day therefore rank under that day's date-only packages until those
are removed or disabled in the repository; from the next day on, the new form
always ranks higher.
Stable tags match v<major>.<minor>.<patch> only. Baseline is ancestry, not
the highest version in the repository. This script does not fetch tags.
@@ -120,17 +121,15 @@ short_sha() {
gitc rev-parse HEAD | cut -c1-7
}
# Build-minute YYYYMMDDHHMM. SOURCE_DATE_EPOCH (UTC) wins when set, for
# Build-minute YYYYMMDDTHHMM. SOURCE_DATE_EPOCH (UTC) wins when set, for
# reproducible test packages; otherwise the machine's current local time.
# The minute is not decoration: it is what keeps same-day rebuilds ordered in
# Debian version comparison (0.0.0~202609181036… < 0.0.0~202609181722…). It is
# glued to the date with no 'T' so the whole stamp stays one numeric run;
# '20260918T1722' would sort below '20260918.dev-…' and lose to old packages.
# Debian version comparison (0.0.0~20260918T1036… < 0.0.0~20260918T1722…).
build_stamp() {
if [[ -n "${SOURCE_DATE_EPOCH:-}" ]]; then
date -u -d "@${SOURCE_DATE_EPOCH}" +%Y%m%d%H%M
date -u -d "@${SOURCE_DATE_EPOCH}" +%Y%m%dT%H%M
else
date +%Y%m%d%H%M
date +%Y%m%dT%H%M
fi
}