Parent epic: #35693
Summary
Implement the build-side mechanism for Release Tracks as floating Docker tags on dotcms/dotcms, advanced across the linear GA CalVer stream by release age:
latest — newest GA (a day or so old)
standard — newest GA ≥ ~14 days old
trailing — newest GA ≥ ~28 days old
A scheduled job re-points each track tag (by digest) as releases age. Customers (and our Argo-from-GitHub manifests) pin a track tag (image: dotcms/dotcms:standard) to set their update posture; a future Cloud control plane can reuse the same tags.
Scope (this issue)
- A small Python promotion engine (
cicd/evergreen-tracks/, managed with uv): CalVer age parsing, Docker Hub listing, a pure planner, and a docker buildx imagetools-based executor.
- Registry-only state via marker tags:
<version>_tainted (forward-only block) and <track>_hold (sticky manual override).
- Two workflows: a daily
promote (cron + dispatch) and a manual admin (taint/hold).
- Customer-facing README documentation of the tracks and the design rationale.
Semantics
- Age is read from the embedded CalVer date, not build/publish date, so an emergency backport of an older release can't be swept into a future promotion.
- Forward-only promotion (never moves a track backward automatically).
- Taint blocks a release from advancing onto tracks it hasn't reached yet; a track already on a tainted release stays until a manual override.
- Hold freezes a track at a pinned version until released.
Notes / requirements
- Promotion needs only write on the registry, but
untaint/release-hold need delete scope — the CI Docker credential must be Read/Write/Delete.
- Verified end-to-end against the
dotcms/dotcms-test sandbox.
Out of scope: LTS-line tracks, Java-variant track tags, the Cloud control-plane UI, and update cadence changes (per the epic).
Parent epic: #35693
Summary
Implement the build-side mechanism for Release Tracks as floating Docker tags on
dotcms/dotcms, advanced across the linear GA CalVer stream by release age:latest— newest GA (a day or so old)standard— newest GA ≥ ~14 days oldtrailing— newest GA ≥ ~28 days oldA scheduled job re-points each track tag (by digest) as releases age. Customers (and our Argo-from-GitHub manifests) pin a track tag (
image: dotcms/dotcms:standard) to set their update posture; a future Cloud control plane can reuse the same tags.Scope (this issue)
cicd/evergreen-tracks/, managed withuv): CalVer age parsing, Docker Hub listing, a pure planner, and adocker buildx imagetools-based executor.<version>_tainted(forward-only block) and<track>_hold(sticky manual override).promote(cron + dispatch) and a manualadmin(taint/hold).Semantics
Notes / requirements
untaint/release-holdneed delete scope — the CI Docker credential must be Read/Write/Delete.dotcms/dotcms-testsandbox.Out of scope: LTS-line tracks, Java-variant track tags, the Cloud control-plane UI, and update cadence changes (per the epic).