From 4a138e27fa92b988924344f7390a26002e105557 Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Thu, 28 May 2026 19:33:38 -0400 Subject: [PATCH] feat(helm): roll-forward upgrades for pinned releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit install_only=false now warns and upgrades across a pinned version change instead of erroring "refusing to upgrade/downgrade", unblocking the CD path (helm upgrade --install of a newly published chart). Roll-forward only — helm fails loudly, no auto-rollback (ADR-012-2). --- harmony/src/modules/helm/chart.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/harmony/src/modules/helm/chart.rs b/harmony/src/modules/helm/chart.rs index 03371e44..273960d1 100644 --- a/harmony/src/modules/helm/chart.rs +++ b/harmony/src/modules/helm/chart.rs @@ -223,18 +223,18 @@ impl Interpret for HelmChartInterpret { self.score.release_name ))); } - // Pinned-version safety net: if the score pins a *different* - // version than what's installed, refuse to silently - // upgrade/downgrade — that's a manual decision. + // install_only=false is explicit upgrade mode; a pinned + // version change is an intentional roll-forward (ADR-012-2). + // Apply it — helm fails loudly if convergence fails; no + // auto-rollback. if let Some(expected) = self.expected_chart_field() && Self::normalize_chart_field(&expected) != Self::normalize_chart_field(&installed_chart) { - return Err(InterpretError::new(format!( - "Helm release '{}' already installed as '{}', but score requests '{}'. \ - Refusing to upgrade/downgrade; resolve manually.", + warn!( + "Helm release '{}' installed as '{}'; rolling forward to '{}'.", self.score.release_name, installed_chart, expected - ))); + ); } // Otherwise (no pin, or pinned and matching) fall through to // `helm upgrade --install`. Helm is the source of truth on -- 2.39.5