Skip to content

ci(dev-image): propagate to GHCR and ECR with registry-state re-entry - #297

Open
robinnsc wants to merge 1 commit into
mainfrom
ci/dev-image-propagate
Open

ci(dev-image): propagate to GHCR and ECR with registry-state re-entry#297
robinnsc wants to merge 1 commit into
mainfrom
ci/dev-image-propagate

Conversation

@robinnsc

Copy link
Copy Markdown
Collaborator

What

release-dev-image now covers all three registries in its single dispatch:
after the existing publish+sign job (dockerhub environment, approval 1), a
new propagate job (ghcr environment, approval 2) carries the version
tag, a state-derivedlatest, and the signature to GHCR and ECR Public
through the promote-registry composite action — signature verified at
each destination before any tag is placed, forward-only latest re-guarded
per destination, three-way fail-closed probes throughout.

The publish job also becomes re-entrant on registry state: an existing
version tag whose signature verifies is treated as authoritative (skip
push, skip sign); existing-but-unsigned proceeds to signing only; and only
a definite manifest-unknown proceeds to push. Signing is additionally
guarded by a signature-existence check, so a re-dispatch never double-signs.

move-latest for the mirrors is derived from Docker Hub state (does
latest point at this digest?) rather than re-deciding, so mirrors always
converge on what the canonical registry serves.

Why

Release-owner decision 2026-08-20: the dev image lands on the same three
registries as the Postgres image (superseding the 08-15 Docker Hub-only
scoping — and matching the three-registry expectation from the #283 review).
The AWS side is already live and read-back-verified: extenddb-dev exists
on ECR Public with catalog metadata, and both ECR role policies cover it.

Re-entry has to be registry-state-based rather than #284-style artifact
comparison because this workflow rebuilds on every dispatch and the build
is not bit-reproducible — comparing a fresh build against the released
artifact would refuse every time. An existing version tag with a verifying
signature is the release; immutability says never to touch it anyway.

Immediate use — the v0.1.7 backfill: dev 0.1.7 is Docker Hub-only
today. After this merges, re-dispatching v0.1.7 no-ops publish and
signing (tag exists, signature verifies) and runs the propagate wave,
putting the already-released artifact on GHCR and ECR. The first GHCR push
auto-creates the package: verify repo linkage and visibility per runbook
10.6 (the summary reminds the operator).

Testing done

  • yaml.safe_load passes.
  • The propagate legs are the promote-registry action reviewed and merged
    in ci(promote): fan out promotion to GHCR and ECR in one approved run #283 (four hostile rounds), pointed at the dev repositories; the AWS
    prerequisites were verified by read-back and the policy diffs archived.
  • Re-entry decision table traced against live state: v0.1.7 on Docker Hub
    (exists + signed → skip to propagate ✓); a fresh version (absent →
    normal path ✓); the interrupted case (exists + unsigned → sign only ✓);
    probe failure (abort ✓).
  • Not executable pre-merge (main-only environment). The v0.1.7 backfill
    dispatch is the live verification, and every gate fails closed.

Checklist

  • Tests / fmt / clippy — not applicable, workflow-only change
  • I have added or updated tests for new functionality — the re-entry decision table and per-destination gates are the checks; live verification plan above
  • I have updated documentation if behavior changed — header rewritten; runbook records the decision and completed AWS work
  • Breaking changes are noted below (if any)

ADR / RFC: n/a — CI tooling only.

Breaking changes

None. A normal first-time dispatch behaves as before, plus the propagate wave.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache License 2.0 and I agree to the Developer Certificate of Origin (DCO). See CONTRIBUTING.md for details.

Adds the propagate wave (ghcr environment, approval 2): version,
state-derived latest, and the signature go to GHCR and ECR Public
through the promote-registry composite action — signature verified
at each destination before any tag, forward-only latest re-guarded
per destination. The publish job becomes re-entrant on registry
state: an existing version tag with a verifying signature is
authoritative (a rebuild is not bit-reproducible, so artifact
comparison would always refuse), signing is skipped when the .sig
already exists (never double-sign), and only a definite absence
proceeds to push. Enables interrupted-release recovery and the
v0.1.7 mirror backfill. Supersedes the Docker Hub-only scoping
(release owner decision 2026-08-20; AWS side already live).
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@robinnsc