ci: carry tags NEWER than the forge, not every tag it lacks
image / test (push) Successful in 5m1s
image / build (push) Successful in 1m3s

This job has failed on every run for days, and the failure was its own safety cap
firing correctly against a precondition that was never true.

The tag step collected "every v* tag not on the forge". The forge repo was created
without history's tags, so ~160 of them — the whole v1.0.0 … v1.31.x line — are
permanently missing and always in that set. The cap ("refusing to dispatch that
many builds at once", >5) therefore tripped on EVERY run and exited 1, so the step
never reached a real release. That is why v1.34.5 and v1.34.8 exist as tags with no
image: starved behind 160 ancient tags nobody wanted rebuilt, in a queue that could
never drain. A guard that cannot be satisfied is not a guard, it is an outage.

The set is now anchored on the forge's OWN highest release tag, so it converges:
empty in the steady state, and exactly the new tags after a release. The cap stays
— it is still the right answer to a genuine tag storm — but it is now reachable.

Backfilling the ~160 historical tags is deliberately NOT done: pushing them fires
image.yml once per tag on `on: push: tags`, which is precisely the storm the cap
exists to stop. They are history; nothing needs them rebuilt.

Verified the filter against the real ladder — v1.0.0, v1.14.9, v1.31.37, v1.34.5,
v1.34.9 and v1.34.10 all skip against a forge high of v1.34.10; v1.34.11 and
v1.35.0 carry.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
zooqueen
2026-08-03 19:27:00 -07:00
co-authored by hanzo-dev
parent c842b92d12
commit a219187da1
+24 -2
View File
@@ -99,11 +99,33 @@ jobs:
run: |
set -euo pipefail
git fetch --quiet --tags "https://x-access-token:${GH_PAT}@github.com/hanzoai/iam.git" 'refs/tags/v*:refs/tags/v*' || true
# ONLY tags NEWER than the forge's highest — not every tag it lacks.
#
# "Every tag the forge lacks" is unreachable as an invariant and wedged
# this job for days. The forge repo was created without history's tags,
# so ~160 of them (v1.0.0 … v1.31.x) are permanently "unpushed"; the cap
# below saw 160, exited 1 on EVERY run, and the tag step never reached a
# real release. That is why v1.34.5 and v1.34.8 were tagged and never
# built — starved behind ancient tags nobody wanted rebuilt.
#
# Anchoring on the forge's own highest tag makes the set converge: it is
# empty in the steady state, and after a release it holds exactly the new
# ones. Backfilling the history is deliberately NOT done here — pushing
# those tags would fire image.yml once per tag, which is the tag storm the
# cap exists to prevent.
high=$(git ls-remote --tags --refs origin 'refs/tags/v*' 2>/dev/null \
| sed 's#.*refs/tags/##' | sort -V | tail -1)
echo "forge's highest release tag: ${high:-<none>}"
new=""
for t in $(git tag --list 'v*' | sort -V); do
if ! git ls-remote --exit-code --tags origin "refs/tags/$t" >/dev/null 2>&1; then
new="$new $t"
if git ls-remote --exit-code --tags origin "refs/tags/$t" >/dev/null 2>&1; then
continue # already on the forge
fi
if [ -n "$high" ] && [ "$(printf '%s\n%s\n' "$high" "$t" | sort -V | tail -1)" = "$high" ]; then
continue # older than the forge's highest — history, not a release
fi
new="$new $t"
done
new=$(echo $new)
if [ -z "$new" ]; then echo "no unpushed release tags"; exit 0; fi