diff --git a/pkg/kube/resource.go b/pkg/kube/resource.go index d88b171f0..d6d08d589 100644 --- a/pkg/kube/resource.go +++ b/pkg/kube/resource.go @@ -79,7 +79,14 @@ func (r ResourceList) Intersect(rs ResourceList) ResourceList { return r.Filter(rs.Contains) } -// isMatchingInfo returns true if infos match on Name and GroupVersionKind. +// isMatchingInfo returns true if infos match on Name, Namespace, Group and Kind. +// +// IMPORTANT: Version is intentionally excluded from the comparison. Resources +// served by the same CRD at different API versions (e.g. v2beta1 vs v2beta2) +// share the same underlying storage in the Kubernetes API server. Comparing +// the full GroupVersionKind causes Difference() to treat a version change as +// a resource removal + addition, which makes Helm delete the resource it just +// created during upgrades. See https://github.com/helm/helm/issues/31768 func isMatchingInfo(a, b *resource.Info) bool { - return a.Name == b.Name && a.Namespace == b.Namespace && a.Mapping.GroupVersionKind == b.Mapping.GroupVersionKind + return a.Name == b.Name && a.Namespace == b.Namespace && a.Mapping.GroupVersionKind.GroupKind() == b.Mapping.GroupVersionKind.GroupKind() } diff --git a/pkg/kube/resource_test.go b/pkg/kube/resource_test.go index ccc613c1b..41215a878 100644 --- a/pkg/kube/resource_test.go +++ b/pkg/kube/resource_test.go @@ -72,8 +72,8 @@ func TestIsMatchingInfo(t *testing.T) { gvkDiffVersion := schema.GroupVersionKind{Group: "group1", Version: "diff", Kind: "pod"} resourceInfoDiffVersion := resource.Info{Name: "name1", Namespace: "namespace1", Mapping: &meta.RESTMapping{GroupVersionKind: gvkDiffVersion}} - if isMatchingInfo(&resourceInfo, &resourceInfoDiffVersion) { - t.Error("expected resources not equal") + if !isMatchingInfo(&resourceInfo, &resourceInfoDiffVersion) { + t.Error("expected resources with different versions but same group and kind to be equal") } gvkDiffKind := schema.GroupVersionKind{Group: "group1", Version: "version1", Kind: "deployment"}