feat: add support for helm 4 --server-side upgrade flag (#2641)

* feat: add support for helm 4 --server-side upgrade flag

Add support for the helm 4 upgrade flag --server-side which accepts
"true", "false", or "auto" (default "auto"). This allows users to
explicitly control server-side apply behavior, which is needed for
releases originally installed with Helm 3 and being managed with Helm 4.

The flag can be configured via:
- CLI: --server-side flag on sync, apply, and diff commands
- helmDefaults.serverSide in helmfile.yaml
- releases[].serverSide per-release override

Precedence: release-level > CLI flag > helmDefaults.
Errors are returned when serverSide is set but running Helm 3, or when
an invalid value is provided.

Closes #2640

Signed-off-by: yxxhero <aiopsclub@163.com>

* test: update TestGenerateID expected hashes for new ServerSide field

Adding ServerSide *string to ReleaseSpec changes spew's %#v output and
shifts the FNV hash used by generateValuesID. Update the hard-coded want
values to the new deterministic hashes.

Signed-off-by: yxxhero <aiopsclub@163.com>

---------

Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
yxxhero
2026-06-16 08:24:47 +08:00
committed by GitHub
parent 047fdcd17d
commit a94fdf4194
15 changed files with 265 additions and 6 deletions
+38
View File
@@ -354,6 +354,44 @@ func (st *HelmState) appendTakeOwnershipFlagsForUpgrade(flags []string, helm hel
return flags
}
// validServerSideValues are the allowed values for the helm 4 --server-side flag.
var validServerSideValues = map[string]struct{}{"true": {}, "false": {}, "auto": {}}
// appendServerSideFlagsForUpgrade appends the helm 4 --server-side flag when appropriate.
// Precedence: release-level > CLI flag > helmDefaults.
func (st *HelmState) appendServerSideFlagsForUpgrade(flags []string, helm helmexec.Interface, release *ReleaseSpec, serverSide string) ([]string, error) {
if !helm.IsHelm4() {
// --server-side with a string value is helm 4 only. Guard against misconfiguration
// when the user is running helm 3.
if release.ServerSide != nil && *release.ServerSide != "" {
return nil, fmt.Errorf("serverSide requires Helm 4 or greater (set via releases[].serverSide)")
}
if st.HelmDefaults.ServerSide != nil && *st.HelmDefaults.ServerSide != "" {
return nil, fmt.Errorf("serverSide requires Helm 4 or greater (set via helmDefaults.serverSide)")
}
return flags, nil
}
var value string
switch {
case release.ServerSide != nil && *release.ServerSide != "":
value = *release.ServerSide
case serverSide != "":
value = serverSide
case st.HelmDefaults.ServerSide != nil && *st.HelmDefaults.ServerSide != "":
value = *st.HelmDefaults.ServerSide
default:
return flags, nil
}
if _, ok := validServerSideValues[value]; !ok {
return nil, fmt.Errorf("invalid serverSide value %q: must be \"true\", \"false\", or \"auto\"", value)
}
flags = append(flags, "--server-side", value)
return flags, nil
}
// append show-only flags to helm flags
func (st *HelmState) appendShowOnlyFlags(flags []string, showOnly []string) []string {
showOnlyFlags := []string{}