From 919cbfaac90aeaa26842e9f057d00b9023ec38a1 Mon Sep 17 00:00:00 2001 From: Baptiste ROUX Date: Thu, 16 Apr 2026 11:58:55 +0200 Subject: [PATCH] fix(install): use compatible version range for dependency check Previously, the dependency check used exact version matching, which caused false positives when a compatible version was already installed. Now it uses `chartutil.IsCompatibleRange` to respect semantic versioning constraints. - Update install logic to check version compatibility instead of equality - Adjust test case to include a version in the dependency - Add thread-safe mutex for WaitOptions recording in fake kube client Signed-off-by: Baptiste ROUX --- pkg/action/install.go | 2 +- pkg/action/install_test.go | 2 +- pkg/cmd/testdata/output/install-with-outdated-deps.txt | 6 ------ .../testcharts/chart-with-outdated-dependency/.gitignore | 1 + pkg/kube/fake/failing_kube_client.go | 4 ++++ 5 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 pkg/cmd/testdata/testcharts/chart-with-outdated-dependency/.gitignore diff --git a/pkg/action/install.go b/pkg/action/install.go index c6c803744..ef10b9b71 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -840,7 +840,7 @@ OUTER: if err != nil { return err } - if dac.Name() == rac.Name() && dac.Version() == rac.Version() { + if dac.Name() == rac.Name() && chartutil.IsCompatibleRange(rac.Version(), dac.Version()) { continue OUTER } } diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 05ca9a75e..301fc688e 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -1224,7 +1224,7 @@ func TestInstallCRDs_WaiterError(t *testing.T) { } func TestCheckDependencies(t *testing.T) { - dependency := chart.Dependency{Name: "hello"} + dependency := chart.Dependency{Name: "hello", Version: "0.1.0"} mockChart := buildChart(withDependency()) assert.Nil(t, CheckDependencies(mockChart, []ci.Dependency{&dependency})) diff --git a/pkg/cmd/testdata/output/install-with-outdated-deps.txt b/pkg/cmd/testdata/output/install-with-outdated-deps.txt index 90823aa91..9e3d6f83a 100644 --- a/pkg/cmd/testdata/output/install-with-outdated-deps.txt +++ b/pkg/cmd/testdata/output/install-with-outdated-deps.txt @@ -1,9 +1,3 @@ -Hang tight while we grab the latest from your chart repositories... -...Successfully got an update from the "test" chart repository -Update Complete. ⎈Happy Helming!⎈ -Saving 1 charts -Downloading oci-dependent-chart from repo {{ .repoUrl }} -Deleting outdated charts NAME: updeps LAST DEPLOYED: Fri Sep 2 22:04:05 1977 NAMESPACE: default diff --git a/pkg/cmd/testdata/testcharts/chart-with-outdated-dependency/.gitignore b/pkg/cmd/testdata/testcharts/chart-with-outdated-dependency/.gitignore new file mode 100644 index 000000000..68d93c64f --- /dev/null +++ b/pkg/cmd/testdata/testcharts/chart-with-outdated-dependency/.gitignore @@ -0,0 +1 @@ +requirements.lock diff --git a/pkg/kube/fake/failing_kube_client.go b/pkg/kube/fake/failing_kube_client.go index 0f7787f79..1289b35c6 100644 --- a/pkg/kube/fake/failing_kube_client.go +++ b/pkg/kube/fake/failing_kube_client.go @@ -19,6 +19,7 @@ package fake import ( "io" + "sync" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -49,6 +50,7 @@ type FailingKubeClient struct { WaitDuration time.Duration // RecordedWaitOptions stores the WaitOptions passed to GetWaiter for testing RecordedWaitOptions []kube.WaitOption + mu sync.Mutex } var _ kube.Interface = &FailingKubeClient{} @@ -160,7 +162,9 @@ func (f *FailingKubeClient) GetWaiter(ws kube.WaitStrategy) (kube.Waiter, error) func (f *FailingKubeClient) GetWaiterWithOptions(ws kube.WaitStrategy, opts ...kube.WaitOption) (kube.Waiter, error) { // Record the WaitOptions for testing + f.mu.Lock() f.RecordedWaitOptions = append(f.RecordedWaitOptions, opts...) + f.mu.Unlock() waiter, _ := f.PrintingKubeClient.GetWaiterWithOptions(ws, opts...) printingKubeWaiter, _ := waiter.(*PrintingKubeWaiter) return &FailingKubeWaiter{