feat(base-images): immutable per-publish image tags (#4607)

Every publish now also pushes an immutable per-publish tag alongside the
mutable one, named after the snapshot date and commit (e.g.
`22-bookworm-20260812-45444a7`), so previously published digests stay
tag-referenced after republishes. Shipped CLI releases pin those
digests, so they must remain resolvable indefinitely.

Merging triggers a republish; the fresh tag-protected digests will then
be pinned by #4602 before it merges.
This commit is contained in:
Saadi Myftija
2026-08-13 18:22:50 +02:00
committed by GitHub
parent eefe0a378d
commit 035e71010d
2 changed files with 15 additions and 3 deletions
+11 -2
View File
@@ -39,6 +39,7 @@ jobs:
build_packages: ${{ steps.config.outputs.build_packages }}
suite: ${{ steps.config.outputs.suite }}
snapshot: ${{ steps.config.outputs.snapshot }}
publish_id: ${{ steps.config.outputs.publish_id }}
source_date_epoch: ${{ steps.config.outputs.source_date_epoch }}
push: ${{ steps.config.outputs.push }}
steps:
@@ -52,6 +53,7 @@ jobs:
SNAPSHOT_INPUT: ${{ inputs.debian_snapshot }}
EVENT_NAME: ${{ github.event_name }}
REF: ${{ github.ref }}
SHA: ${{ github.sha }}
run: |
PACKAGES="$(jq -er '.packages' base-images/images.json)"
BUILD_PACKAGES="$(jq -er '.buildPackages' base-images/images.json)"
@@ -89,6 +91,7 @@ jobs:
echo "build_packages=$BUILD_PACKAGES"
echo "suite=$SUITE"
echo "snapshot=$SNAPSHOT"
echo "publish_id=${SNAPSHOT:0:8}-${SNAPSHOT:9:6}-${SHA:0:7}"
echo "source_date_epoch=$EPOCH"
echo "push=$PUSH"
} >> "$GITHUB_OUTPUT"
@@ -164,7 +167,11 @@ jobs:
platforms: linux/amd64,linux/arm64
provenance: false
outputs: type=image,push=true,rewrite-timestamp=true
tags: triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}
# The dated tag is immutable and keeps every published digest
# tag-referenced forever; shipped CLI releases pin these digests
tags: |
triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}
triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}-${{ needs.setup.outputs.publish_id }}
build-args: |
BASE_IMAGE=${{ matrix.image.base }}
DEBIAN_SNAPSHOT=${{ needs.setup.outputs.snapshot }}
@@ -187,7 +194,9 @@ jobs:
platforms: linux/amd64,linux/arm64
provenance: false
outputs: type=image,push=true,rewrite-timestamp=true
tags: triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}-build
tags: |
triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}-build
triggerdotdev/${{ matrix.image.repo }}:${{ matrix.image.tag }}-build-${{ needs.setup.outputs.publish_id }}
build-args: |
BASE_IMAGE=${{ matrix.image.base }}
DEBIAN_SNAPSHOT=${{ needs.setup.outputs.snapshot }}
+4 -1
View File
@@ -14,7 +14,10 @@ images derived from these behave like their upstream bases.
## Tags and pinning
Tags are mutable and rebuilt in place on demand; each rebuild picks up Debian
security updates published up to its snapshot date. The
security updates published up to its snapshot date. Every publish also pushes
an immutable per-publish tag (snapshot timestamp plus commit, e.g. `22-bookworm-20260812-000000-45444a7`) so previously
published digests stay tag-referenced; never delete these, since shipped CLI
releases pin their digests. The
runtime itself (the node or bun binaries from the upstream base) only moves
when the base digests in `images.json` are bumped. When bumping a base
digest, keep the snapshot at least as new as the upstream image's own archive