Let a release be what a bare pull answers

`docker pull ghcr.io/hanzoai/base` asks for :latest, which no lane writes, so
it still served 1.5.22 -- sixty-nine patches behind, amd64 alone. A branch
build still writes none; the leading v already tells the two apart.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-09-10 21:52:45 -07:00
co-authored by Hanzo Dev
parent 500a9e63d8
commit 445ea7171c
2 changed files with 18 additions and 5 deletions
+13 -2
View File
@@ -36,8 +36,15 @@
# A tag-suffix (hanzo.yml `tag-suffix`, e.g. ce/ee) qualifies every one of them.
# There is no `<version>-amd64` alias: no CR in the fleet pinned one.
#
# NO `latest`: it names whatever finished most recently, so two digests wear it
# within a day and a pull is a race rather than a choice.
# latest ON A RELEASE ONLY. `docker pull <name>` with no tag asks for
# it, so a repository that writes it nowhere answers a bare
# pull with whatever wore it last -- ghcr.io/hanzoai/base:latest
# was 1.5.22, sixty-nine patches and five weeks behind, amd64
# alone, and a contributor typing the bare name got that.
# Branch builds still write none: they are the case the old rule
# was about, where several finish in a day and the tag becomes a
# race rather than a choice. A release is deliberate and
# ascending, so the newest one is what `latest` should mean.
set -euo pipefail
repo="${1:?usage: imgtags <image-repo> <version> <short-sha> <platforms> [tag-suffix]}"
@@ -66,6 +73,10 @@ else
fi
echo "${repo}:${ver}${sfx:+-$sfx}"
# The leading v IS the discriminator, and it already exists: a release passes the
# git tag verbatim (v1.26.19), a branch build passes bin/imgver's bare number
# (1.5.96). So `latest` needs no new argument and no lane has to remember to ask.
if [ "${ver#v}" != "$ver" ]; then
echo "${repo}:${ver#v}${sfx:+-$sfx}"
echo "${repo}:latest${sfx:+-$sfx}"
fi
+5 -3
View File
@@ -26,19 +26,21 @@ t "single-arch: sha carries the architecture" \
t "multi-arch: the arch-neutral manifest list" \
"$R:sha-abc1234 $R:1.2.3" $R 1.2.3 abc1234 linux/amd64,linux/arm64
t "release build: the git tag, plus its v-stripped alias" \
"$R:sha-abc1234-amd64 $R:v1.2.3 $R:1.2.3" $R v1.2.3 abc1234 linux/amd64
"$R:sha-abc1234-amd64 $R:v1.2.3 $R:1.2.3 $R:latest" $R v1.2.3 abc1234 linux/amd64
t "a tag with no v publishes one version, not two" \
"$R:sha-abc1234-amd64 $R:1.2.3" $R 1.2.3 abc1234 linux/amd64
t "tag-suffix qualifies every tag" \
"$R:sha-abc1234-amd64-ce $R:1.2.3-ce" $R 1.2.3 abc1234 linux/amd64 ce
t "suffix on a release build too" \
"$R:sha-abc1234-ee $R:v2.0.0-ee $R:2.0.0-ee" $R v2.0.0 abc1234 linux/amd64,linux/arm64 ee
"$R:sha-abc1234-ee $R:v2.0.0-ee $R:2.0.0-ee $R:latest-ee" $R v2.0.0 abc1234 linux/amd64,linux/arm64 ee
t "a branch build writes no latest, whatever the platforms" \
"$R:sha-abc1234 $R:1.2.3" $R 1.2.3 abc1234 linux/amd64,linux/arm64
t "arm64-only names arm64, not amd64" \
"$R:sha-abc1234-arm64 $R:1.2.3" $R 1.2.3 abc1234 linux/arm64
t "space-separated platforms read the same as commas" \
"$R:sha-abc1234 $R:1.2.3" $R 1.2.3 abc1234 "linux/amd64 linux/arm64"
t "the sha- ref is always first" \
"$R:sha-abc1234-amd64 $R:v9.9.9 $R:9.9.9" $R v9.9.9 abc1234 linux/amd64
"$R:sha-abc1234-amd64 $R:v9.9.9 $R:9.9.9 $R:latest" $R v9.9.9 abc1234 linux/amd64
# --- the refusals ------------------------------------------------------------
t "no version: refuse, never fall back to the sha" "ERROR" $R "" abc1234 linux/amd64