diff --git a/internal/version/clientgo.go b/internal/version/clientgo.go index 50a4fd5cb..7ae5184c5 100644 --- a/internal/version/clientgo.go +++ b/internal/version/clientgo.go @@ -21,7 +21,7 @@ import ( "runtime/debug" "slices" - _ "k8s.io/client-go/kubernetes" // Force k8s.io/client-go to be included in the build + _ "k8s.io/client-go/pkg/version" // Force the k8s.io/client-go module version into build info ) func K8sIOClientGoModVersion() (string, error) { diff --git a/internal/version/clientgo_test.go b/internal/version/clientgo_test.go index 624c669af..33a21f222 100644 --- a/internal/version/clientgo_test.go +++ b/internal/version/clientgo_test.go @@ -17,6 +17,10 @@ limitations under the License. package version import ( + "os/exec" + "path/filepath" + "runtime" + "strings" "testing" "github.com/stretchr/testify/require" @@ -28,3 +32,36 @@ func TestK8sClientGoModVersion(t *testing.T) { _, err := K8sIOClientGoModVersion() require.ErrorContains(t, err, "k8s.io/client-go not found in build info") } + +func TestK8sClientGoModVersionFromBuiltBinary(t *testing.T) { + cmd := exec.CommandContext(t.Context(), "go", "list", "-m", "-f={{.Version}}", "k8s.io/client-go") + expectedVersion, err := cmd.CombinedOutput() + require.NoError(t, err, string(expectedVersion)) + + binary := filepath.Join(t.TempDir(), "clientgo-version") + if runtime.GOOS == "windows" { + binary += ".exe" + } + + cmd = exec.CommandContext(t.Context(), "go", "build", "-o", binary, "./testdata/clientgo-version") + output, err := cmd.CombinedOutput() + require.NoError(t, err, string(output)) + + cmd = exec.CommandContext(t.Context(), binary) + output, err = cmd.CombinedOutput() + require.NoError(t, err, string(output)) + require.Equal(t, strings.TrimSpace(string(expectedVersion)), strings.TrimSpace(string(output))) +} + +func TestK8sClientGoDependencyIsLightweight(t *testing.T) { + cmd := exec.CommandContext(t.Context(), "go", "list", "-deps", ".") + output, err := cmd.CombinedOutput() + require.NoError(t, err, string(output)) + + dependencies := strings.Fields(string(output)) + require.Contains(t, dependencies, "k8s.io/client-go/pkg/version") + for _, dependency := range dependencies { + require.NotEqual(t, "k8s.io/client-go/kubernetes", dependency) + require.NotContains(t, dependency, "k8s.io/client-go/kubernetes/") + } +} diff --git a/internal/version/testdata/clientgo-version/main.go b/internal/version/testdata/clientgo-version/main.go new file mode 100644 index 000000000..81650bb64 --- /dev/null +++ b/internal/version/testdata/clientgo-version/main.go @@ -0,0 +1,34 @@ +/* +Copyright The Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "fmt" + "os" + + "helm.sh/helm/v4/internal/version" +) + +func main() { + clientGoVersion, err := version.K8sIOClientGoModVersion() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + fmt.Print(clientGoVersion) +}