Repository navigation
Stable release ships the rc's packages OCI artifact — platformSourceRef points at an rc-built bundle, so the dashboard reports vX.Y.Z-rc.N on a stable install #3477
Description
Summary
On a stable v1.6.0 install the dashboard UI reports v1.6.0-rc.4, and every platform component runs an image tagged :v1.6.0-rc.4. The operator itself correctly reports v1.6.0. The cause is a source↔artifact divergence in the rc→stable promotion: the cozystack-packages OCI artifact that the stable installer's platformSourceRef points at was built from the rc source tree, so its in-values image references still carry the :vX.Y.Z-rc.N tag even though the container images were retagged to the stable tag by digest and the git release tree was restamped to :vX.Y.Z. The images are byte-identical to the stable release (same digests); this is a cosmetic/labeling defect, but it affects every stable install and undermines the stated goal of the rc→stable promotion work.
Environment
- Cozystack
v1.6.0, upgraded fromv1.5.2viahelm upgrade cozystack oci://ghcr.io/cozystack/cozystack/cozy-installer --version 1.6.0. cozystack-operatorimage:v1.6.0, envCOZYSTACK_VERSION=v1.6.0, platform PackageReady, migrations completed.
What I observed
- Dashboard footer shows
v1.6.0-rc.4. kubectl get deploy -Ashows the console, API, controller, kamaji, kube-ovn, linstor, metallb, backup controllers, etc. all on:v1.6.0-rc.4-tagged images; onlycozystack-operatoris:v1.6.0.- Nothing relevant is suspended; the platform is fully reconciled.
Evidence
The stable git tree and the stable installer disagree with the artifact the installer actually pulls.
Git tag v1.6.0 and main — restamped to the stable tag:
packages/system/dashboard/values.yaml
console.image: ghcr.io/cozystack/cozystack/cozystack-ui:v1.6.0@sha256:ad0e132c...
packages/core/installer/values.yaml
platformSourceRef: digest=sha256:bf68208730860fa8e47f378a0260e79a0262e0783fa63ba4f7f97f57a48b2d23
The published artifact at that digest, pulled with flux pull artifact:
revision v1.6.0-rc.4:cc66e2295297543381b1dd40cb9f4cb91fede01d
system/dashboard/values.yaml
console.image: ghcr.io/cozystack/cozystack/cozystack-ui:v1.6.0-rc.4@sha256:ad0e132c...
Same image digest (ad0e132c...), different tag string. grep inside the pulled artifact finds 33 image references carrying :v1.6.0-rc.4. For comparison, the v1.6.0-rc.4 git tag pins platformSourceRef to a different digest (e2e7bc76...), so promotion did publish a new artifact for the stable release — but that new artifact still carries the rc revision and rc tag strings.
The displayed version comes from the image tag, not from the operator: packages/system/dashboard/templates/configmap.yaml derives the console's version by splitting the .Values.console.image tag, and the console prefers that config.json version over the build-time VITE_APP_VERSION. Because the artifact's console.image is :v1.6.0-rc.4, the ConfigMap gets version: v1.6.0-rc.4.
Root cause
The finalize workflow (.github/workflows/pull-requests-release.yaml) retags the rc images to the stable tag by digest (hack/promote-retag.sh) and publishes the stable cozy-installer chart, but it does not rebuild the cozystack-packages OCI artifact from the tag-rewritten release tree. The release commit rewrites the :rc tag strings in packages/**/values.yaml to :vX.Y.Z and sets platformSourceRef to bf68..., but that artifact was built from the rc tree, so the rewrite never lands in the artifact the installer consumes. Net: container images (registry) and the git tree are stable-tagged, while the shipped packages artifact remains rc-tagged.
Why this is a regression from 1.5.x
In v1.5.2, packages/system/dashboard/templates/configmap.yaml had no version field — it only emitted branding — so the console fell back to the build-time VITE_APP_VERSION baked into an image that was built directly as a stable tag. There was no rc→stable promotion, so no rc tag could exist in a stable release. v1.6.0 introduced two new things at once: the build-once, promote-by-retag release flow, and version derivation from the in-bundle console.image tag. The new derivation reads the rc tag the promotion leaves in the artifact, so the rc version surfaces where 1.5.x showed a clean stable version.
Impact and recurrence
- Cosmetic: images are byte-identical to the stable release by digest; functionality is unaffected.
- It affects every
v1.6.0install, because bothmainand thev1.6.0tag pinplatformSourceRefto the rc-content artifact. - The version-derivation logic and the promotion workflow are unchanged on
mainafter thev1.6.0release, so the next stable (v1.6.1) would repeat this and reportv1.6.1-rc.Nunless the pipeline is fixed.
Suggested fixes (either resolves it)
- Rebuild and re-push the
cozystack-packagesOCI artifact from the promotion (tag-rewritten) tree, and pinplatformSourceRefto that digest, so the artifact's in-values image references carry the stable tag. - Decouple the console's reported version from the in-bundle image tag: source the
versioninpackages/system/dashboard/templates/configmap.yamlfromCOZYSTACK_VERSION/cozystackOperator.platformVersion(as the operator already does) rather than parsingconsole.image. This makes the footer correct regardless of the tag string baked into the artifact.
Related
- RFC: immutable release tags & rc-promotion flow #2677 — RFC: immutable release tags & rc-promotion flow (the mechanism this defect lives in).
Activity
dosubot commentedon Jul 28, 2026
Good write-up — I can confirm the root cause from the code.
The promotion workflow (
pull-requests-release.yaml) retags the rc's cozystack-packages OCI artifact to the stable tag by digest [1], but never rebuilds it from the tag-rewritten source tree.hack/promote-retag.shexplicitly states its purpose is to retag "with no rebuild" [2]. Meanwhile,hack/promote-rewrite-tags.shdoes rewrite the:rc→:vX.Y.Ztags in the git tree [3], but that rewritten tree is never used to produce a new packages artifact — only to create the stable git tag and the cozy-installer chart.The dashboard version extraction confirms the symptom path: the configmap template splits
.Values.console.imageon:and@to derive the tag string [4], so whatever tag is baked into the artifact's values is what the UI shows.Of the two suggested fixes, option 2 (decoupling the displayed version) is likely the safer incremental fix — it doesn't require changing the promotion pipeline's no-rebuild guarantee, and the operator already has
COZYSTACK_VERSION/platformVersionavailable. Option 1 (rebuilding the artifact) is the more thorough fix but reintroduces a build step into the promotion path, which the design intentionally avoided to preserve bit-for-bit identity between the rc and stable artifact [5].A middle-ground variant of option 1 would be to do a content-level rewrite inside the OCI artifact (sed the tag strings, re-push, pin
platformSourceRefto the new digest) rather than a fullmake build— it's still a new artifact, but there's no source compilation involved.To reply, just mention @dosu.
Docs are dead. Just use Dosu.
fix(release): publish rewritten packages during RC promotion (#3795)