Skip to content

ci(release): tag/chart-version guard + strict stability rule (release train) - #460

Open
LukasWodka wants to merge 2 commits into
developfrom
ci/release-train-guards
Open

ci(release): tag/chart-version guard + strict stability rule (release train)#460
LukasWodka wants to merge 2 commits into
developfrom
ci/release-train-guards

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What (backend#1301, Q5 — approved by Lukas)

Two guards in release-helm-chart.yaml, running before lint/package on every published release:

  1. tag ↔ chart version: the tag's base X.Y.Z must equal client/Chart.yaml's version — train-cut or manual — so the chart version can never go silently stale after an out-of-train release.
  2. Strict stability: any non-plain-semver tag (e.g. v1.9.7-rc.1, or a malformed v1.9.7rc1) must be marked pre-release — otherwise it would become latest (what the installer bootstrap resolves) and enter the helm index as stable.

Tag reaches the script via env, never interpolated (R8, backend#889).

Context

client is joining the release train: staging hop → train creates pre-release v1.X.Y-rc.N (rc numbering strictly numeric) → FR from the rc's own stamped installer; prod hop → stable v1.X.Y. The stamped-installer flow needs zero changes — the fail-closed guard is placeholder-based, so rc-stamped installers verify at their own tag as-is. Helm-side safety: helm install excludes pre-release chart versions unless --devel/explicit --version.

Test plan

  • actionlint clean
  • First rc after merge+App-install: verify the guard passes, the release is marked pre-release, releases/latest still points at the last stable, and helm search repo tracebloc -l --devel shows the rc

🤖 Generated with Claude Code


Note

Medium Risk
Changes the release gate for Helm and installer assets; misconfiguration could block releases or alter which tag is latest, but behavior is mostly fail-closed with an explicit self-heal for mis-marked stable pre-releases.

Overview
Adds a shared verify job that runs before Helm packaging and installer manifest signing, so a bad release can no longer still publish charts or stamped installers (fix for a guard that lived only inside release).

Tag ↔ chart version: On publish, the release tag’s base X.Y.Z must match client/Chart.yaml version; mismatch fails the workflow so the chart cannot drift after an out-of-train cut.

Stability: Tags that are not plain vX.Y.Z (e.g. -rc.N) but were published as stable are auto-demoted to prerelease via gh release edit, so GitHub latest (installer bootstrap) stays on the last real stable. The tag is passed through TAG env, not interpolated into the shell script (R8).

Both release and sign-installer-manifest now needs: verify.

Reviewed by Cursor Bugbot for commit c61982c. Bugbot is set up for automated code reviews on this repo. Configure here.

…#1301 Q5)

The tag's base X.Y.Z must equal client/Chart.yaml's version (train-cut or
manual), and any non-plain-semver tag must be a PRE-release -- otherwise
it would become 'latest' (the installer bootstrap) and enter the helm
index as stable. Tag passed via env per R8 (backend#889).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodka
LukasWodka requested a review from saadqbal as a code owner July 28, 2026 15:37
Comment thread .github/workflows/release-helm-chart.yaml Outdated
The guard lived only inside the release job; sign-installer-manifest has
no needs and kept stamping + attaching installers for a bad release --
which, left marked stable, already IS 'latest' (what the bootstrap
resolves). Restructured: a dedicated verify job gates both jobs. And
instead of fail-and-strand, an unmarked non-final tag is DEMOTED to
prerelease ('latest' snaps back to the previous stable) and publishing
continues as a proper pre-release. Chart-version mismatch stays a hard
fail -- nothing to auto-fix without a bump.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c61982c. Configure here.

if ! printf '%s' "$TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$' && [ "$IS_PRERELEASE" != "true" ]; then
echo "::warning::non-final tag '$TAG' was published as a STABLE release - demoting to prerelease so 'latest' (the installer bootstrap) snaps back to the previous stable."
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --prerelease
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demotion skipped on version mismatch

High Severity

The chart-version hard-fail runs before the stability demotion, so a non-final tag published as stable with a mismatched Chart.yaml version exits without calling gh release edit --prerelease. Downstream jobs are skipped, leaving that release as latest with no installer assets, so the bootstrap URL 404s until someone fixes it by hand.

Fix in Cursor Fix in Web

Triggered by project rule: Bugbot guide — tracebloc/client

Reviewed by Cursor Bugbot for commit c61982c. Configure here.

Sign up for free to 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