ci: publish a per-artifact date tag on main builds (milestone 313 step 3)
CI / lint (push) Successful in 3s
Build images / sign-extension (push) Successful in 4s
CI / extension-version (push) Successful in 3s
Build images / build-ml (push) Successful in 6s
Build images / build-agent (push) Successful in 6s
Build images / build-web (push) Successful in 5s
extension / lint (push) Successful in 17s
CI / frontend-build (push) Successful in 17s
CI / backend-lint-and-test (push) Successful in 29s
CI / integration (push) Successful in 3m44s
CI / lint (push) Successful in 3s
Build images / sign-extension (push) Successful in 4s
CI / extension-version (push) Successful in 3s
Build images / build-ml (push) Successful in 6s
Build images / build-agent (push) Successful in 6s
Build images / build-web (push) Successful in 5s
extension / lint (push) Successful in 17s
CI / frontend-build (push) Successful in 17s
CI / backend-lint-and-test (push) Successful in 29s
CI / integration (push) Successful in 3m44s
Each main build now also publishes <image>:YYYY.M.D — the date of the
commit that artifact's shipped files last changed in. Purely additive;
:main, :latest, :c-<sha> and the dev path are untouched, so reverting this
commit reverts the behaviour.
main push -> :main, :latest, :c-<sha>, :2026.8.27
dev push -> :dev
Per artifact, so an image whose files did not change keeps the tag it
already had. On this commit the agent reads 2026.7.17 while web and ml
read 2026.8.27 — six weeks apart, from one push. Step 4 turns that into
not rebuilding it.
Day precision, and a second main build the same day replaces the first.
Operator's call, and the reasoning is theirs: same-day work is not
something worth pinning. A rollback goes to a day, not to the fourth merge
of a Tuesday afternoon. It also makes retention mean "the last N days"
rather than "the last N pushes".
CALVER is computed inside the main branch rather than at the top of the
step, and hard-fails when empty. There is no `set -e` here, so an
unconditional assignment that failed would have left it empty and published
the tag `fabledcurator:` — an invalid name, from a step that still reported
success. It is also simply unused on the dev and tag paths.
Fixed a stale comment while in this block rather than leaving it for step
7: it claimed release tags carry "no `.N` per family release-posture rule".
Rule 148 was amended on 2026-08-24 to REQUIRE the suffix, after the ban
caused a same-day tag to be retargeted and a release deleted to make room
(note 2813). FC's own tags already carry suffixes; only the comment was
asserting the superseded rule.
Verified before pushing: the derivation holds across 200 commits of real
history — a derived revision always touches its own path set, the version
never decreases along any parent->child edge, and web tracks all three
extension-only commits in the log. That last one is the direction that
would serve stale bytes on a pin.
This commit is contained in:
@@ -446,7 +446,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# Three trigger shapes:
|
# Three trigger shapes:
|
||||||
# refs/tags/v… → tag-push: opt-in milestone label (vYY.MM.DD,
|
# refs/tags/v… → tag-push: opt-in milestone label (vYY.MM.DD,
|
||||||
# no `.N` per family release-posture rule).
|
# plus `.N` when the day already carries a tag —
|
||||||
|
# family rule 148, amended 2026-08-24 after a
|
||||||
|
# same-day tag was retargeted and a release
|
||||||
|
# deleted to make room, note 2813).
|
||||||
# Publish ONLY the immutable version tag;
|
# Publish ONLY the immutable version tag;
|
||||||
# don't touch :latest (the main-push build
|
# don't touch :latest (the main-push build
|
||||||
# for the merge commit already did that).
|
# for the merge commit already did that).
|
||||||
@@ -468,6 +471,15 @@ jobs:
|
|||||||
# everywhere). Operator-flagged 2026-06-01 after first :c-<sha>
|
# everywhere). Operator-flagged 2026-06-01 after first :c-<sha>
|
||||||
# main-push build failed at this step.
|
# main-push build failed at this step.
|
||||||
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
||||||
|
# The pinnable tag (milestone 313 step 3): YYYY.M.D of the commit
|
||||||
|
# THIS artifact's shipped files last changed in. Day precision is
|
||||||
|
# deliberate — same-day work is not something worth pinning, so a
|
||||||
|
# second main build the same day replaces the first rather than
|
||||||
|
# accumulating a tag nobody would roll back to.
|
||||||
|
#
|
||||||
|
# Derived per artifact, so an image whose files did not change keeps
|
||||||
|
# the tag it already had: the agent reads 2026.7.17 today while web
|
||||||
|
# reads 2026.8.27. Step 4 uses that to stop rebuilding it at all.
|
||||||
# `channel` is baked into the image as FC_CHANNEL and reported by
|
# `channel` is baked into the image as FC_CHANNEL and reported by
|
||||||
# /api/extension/manifest (milestone 271 step 7). A tag-push counts as
|
# /api/extension/manifest (milestone 271 step 7). A tag-push counts as
|
||||||
# `main`: a vYY.MM.DD tag is cut from main, so that image is a
|
# `main`: a vYY.MM.DD tag is cut from main, so that image is a
|
||||||
@@ -477,7 +489,17 @@ jobs:
|
|||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
echo "channel=main" >> "$GITHUB_OUTPUT"
|
echo "channel=main" >> "$GITHUB_OUTPUT"
|
||||||
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:main,git.fabledsword.com/bvandeusen/fabledcurator:latest,git.fabledsword.com/bvandeusen/fabledcurator:c-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
CALVER=$(sh scripts/artifacts.sh tag web)
|
||||||
|
# Guarded, and computed only on this path. There is no `set -e` in
|
||||||
|
# this step, so a failed derivation would otherwise leave CALVER
|
||||||
|
# empty and publish the tag `fabledcurator:` — an invalid
|
||||||
|
# name, from a green step. An empty pin must never reach the
|
||||||
|
# registry.
|
||||||
|
if [ -z "$CALVER" ]; then
|
||||||
|
echo "ERROR: could not derive a web version tag" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:main,git.fabledsword.com/bvandeusen/fabledcurator:latest,git.fabledsword.com/bvandeusen/fabledcurator:c-${SHORT_SHA},git.fabledsword.com/bvandeusen/fabledcurator:${CALVER}" >> "$GITHUB_OUTPUT"
|
||||||
echo "channel=main" >> "$GITHUB_OUTPUT"
|
echo "channel=main" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:dev" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator:dev" >> "$GITHUB_OUTPUT"
|
||||||
@@ -569,11 +591,30 @@ jobs:
|
|||||||
# everywhere). Operator-flagged 2026-06-01 after first :c-<sha>
|
# everywhere). Operator-flagged 2026-06-01 after first :c-<sha>
|
||||||
# main-push build failed at this step.
|
# main-push build failed at this step.
|
||||||
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
||||||
|
# The pinnable tag (milestone 313 step 3): YYYY.M.D of the commit
|
||||||
|
# THIS artifact's shipped files last changed in. Day precision is
|
||||||
|
# deliberate — same-day work is not something worth pinning, so a
|
||||||
|
# second main build the same day replaces the first rather than
|
||||||
|
# accumulating a tag nobody would roll back to.
|
||||||
|
#
|
||||||
|
# Derived per artifact, so an image whose files did not change keeps
|
||||||
|
# the tag it already had: the agent reads 2026.7.17 today while web
|
||||||
|
# reads 2026.8.27. Step 4 uses that to stop rebuilding it at all.
|
||||||
if [ "${GITHUB_REF#refs/tags/}" != "${GITHUB_REF}" ]; then
|
if [ "${GITHUB_REF#refs/tags/}" != "${GITHUB_REF}" ]; then
|
||||||
TAG_NAME="${GITHUB_REF#refs/tags/}"
|
TAG_NAME="${GITHUB_REF#refs/tags/}"
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:main,git.fabledsword.com/bvandeusen/fabledcurator-ml:latest,git.fabledsword.com/bvandeusen/fabledcurator-ml:c-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
CALVER=$(sh scripts/artifacts.sh tag ml)
|
||||||
|
# Guarded, and computed only on this path. There is no `set -e` in
|
||||||
|
# this step, so a failed derivation would otherwise leave CALVER
|
||||||
|
# empty and publish the tag `fabledcurator-ml:` — an invalid
|
||||||
|
# name, from a green step. An empty pin must never reach the
|
||||||
|
# registry.
|
||||||
|
if [ -z "$CALVER" ]; then
|
||||||
|
echo "ERROR: could not derive a ml version tag" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:main,git.fabledsword.com/bvandeusen/fabledcurator-ml:latest,git.fabledsword.com/bvandeusen/fabledcurator-ml:c-${SHORT_SHA},git.fabledsword.com/bvandeusen/fabledcurator-ml:${CALVER}" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:dev" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-ml:dev" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
@@ -636,11 +677,30 @@ jobs:
|
|||||||
id: tag
|
id: tag
|
||||||
run: |
|
run: |
|
||||||
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
SHORT_SHA=$(printf '%s' "$GITHUB_SHA" | cut -c1-7)
|
||||||
|
# The pinnable tag (milestone 313 step 3): YYYY.M.D of the commit
|
||||||
|
# THIS artifact's shipped files last changed in. Day precision is
|
||||||
|
# deliberate — same-day work is not something worth pinning, so a
|
||||||
|
# second main build the same day replaces the first rather than
|
||||||
|
# accumulating a tag nobody would roll back to.
|
||||||
|
#
|
||||||
|
# Derived per artifact, so an image whose files did not change keeps
|
||||||
|
# the tag it already had: the agent reads 2026.7.17 today while web
|
||||||
|
# reads 2026.8.27. Step 4 uses that to stop rebuilding it at all.
|
||||||
if [ "${GITHUB_REF#refs/tags/}" != "${GITHUB_REF}" ]; then
|
if [ "${GITHUB_REF#refs/tags/}" != "${GITHUB_REF}" ]; then
|
||||||
TAG_NAME="${GITHUB_REF#refs/tags/}"
|
TAG_NAME="${GITHUB_REF#refs/tags/}"
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:${TAG_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
elif [ "${GITHUB_REF##*/}" = "main" ]; then
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:main,git.fabledsword.com/bvandeusen/fabledcurator-agent:latest,git.fabledsword.com/bvandeusen/fabledcurator-agent:c-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
CALVER=$(sh scripts/artifacts.sh tag agent)
|
||||||
|
# Guarded, and computed only on this path. There is no `set -e` in
|
||||||
|
# this step, so a failed derivation would otherwise leave CALVER
|
||||||
|
# empty and publish the tag `fabledcurator-agent:` — an invalid
|
||||||
|
# name, from a green step. An empty pin must never reach the
|
||||||
|
# registry.
|
||||||
|
if [ -z "$CALVER" ]; then
|
||||||
|
echo "ERROR: could not derive a agent version tag" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:main,git.fabledsword.com/bvandeusen/fabledcurator-agent:latest,git.fabledsword.com/bvandeusen/fabledcurator-agent:c-${SHORT_SHA},git.fabledsword.com/bvandeusen/fabledcurator-agent:${CALVER}" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:dev" >> "$GITHUB_OUTPUT"
|
echo "tags=git.fabledsword.com/bvandeusen/fabledcurator-agent:dev" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user