From 1e0f702f00d5fd36c9de9448e3271787bc588273 Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Fri, 27 Feb 2026 19:10:53 +0100 Subject: [PATCH 01/30] chore: fix whitespace linter Signed-off-by: Matthieu MOREL --- .golangci.yml | 1 + internal/chart/v3/lint/lint.go | 1 - internal/chart/v3/lint/rules/template_test.go | 3 --- internal/chart/v3/loader/load_test.go | 2 -- internal/chart/v3/util/create.go | 1 - internal/chart/v3/util/dependencies_test.go | 1 - internal/chart/v3/util/validate_name.go | 1 - internal/cli/output/color_test.go | 3 --- internal/monocular/client.go | 2 -- internal/monocular/search.go | 1 - internal/monocular/search_test.go | 1 - internal/plugin/installer/base_test.go | 1 - internal/plugin/installer/extractor.go | 1 - internal/plugin/installer/http_installer_test.go | 5 ----- internal/plugin/installer/installer.go | 1 - internal/plugin/installer/vcs_installer_test.go | 1 - internal/plugin/loader.go | 5 ----- internal/plugin/loader_test.go | 1 - internal/plugin/metadata_test.go | 1 - internal/plugin/plugin_type_registry_test.go | 1 - internal/plugin/runtime_extismv1.go | 2 -- internal/plugin/subprocess_commands_test.go | 1 - internal/release/v2/util/manifest_sorter_test.go | 2 -- internal/resolver/resolver.go | 2 -- internal/third_party/dep/fs/fs_test.go | 3 --- internal/version/version.go | 1 - pkg/action/action.go | 1 - pkg/action/dependency.go | 1 - pkg/action/get_metadata.go | 1 - pkg/action/hooks.go | 4 ---- pkg/action/install_test.go | 3 --- pkg/action/package_test.go | 1 - pkg/action/resource_policy.go | 1 - pkg/action/upgrade.go | 1 - pkg/action/upgrade_test.go | 2 -- pkg/action/validate_test.go | 1 - pkg/chart/common/capabilities.go | 1 - pkg/chart/common/util/coalesce_test.go | 2 -- pkg/chart/common/util/values_test.go | 1 - pkg/chart/loader/load.go | 1 - pkg/chart/v2/lint/lint.go | 1 - pkg/chart/v2/lint/rules/template.go | 1 - pkg/chart/v2/lint/rules/template_test.go | 3 --- pkg/chart/v2/loader/load_test.go | 2 -- pkg/chart/v2/util/create.go | 1 - pkg/chart/v2/util/dependencies_test.go | 1 - pkg/chart/v2/util/validate_name.go | 1 - pkg/cmd/completion_test.go | 1 - pkg/cmd/flags.go | 1 - pkg/cmd/get_metadata.go | 1 - pkg/cmd/helpers.go | 1 - pkg/cmd/helpers_test.go | 2 -- pkg/cmd/history.go | 1 - pkg/cmd/lint_test.go | 1 - pkg/cmd/load_plugins.go | 1 - pkg/cmd/pull_test.go | 1 - pkg/cmd/repo_index_test.go | 1 - pkg/cmd/repo_remove_test.go | 1 - pkg/cmd/root.go | 2 -- pkg/cmd/search.go | 1 - pkg/cmd/search/search.go | 1 - pkg/cmd/search/search_test.go | 3 --- pkg/cmd/search_hub.go | 1 - pkg/cmd/search_hub_test.go | 2 -- pkg/cmd/template.go | 1 - pkg/cmd/uninstall.go | 1 - pkg/cmd/upgrade_test.go | 10 ---------- pkg/cmd/verify_test.go | 1 - pkg/downloader/chart_downloader.go | 2 -- pkg/downloader/manager.go | 3 --- pkg/engine/engine_test.go | 5 ----- pkg/getter/httpgetter_test.go | 1 - pkg/getter/plugingetter.go | 1 - pkg/helmpath/lazypath.go | 1 - pkg/kube/client.go | 8 -------- pkg/kube/client_test.go | 10 ---------- pkg/registry/chart.go | 6 ------ pkg/registry/chart_test.go | 9 --------- pkg/registry/client.go | 2 -- pkg/registry/registry_test.go | 1 - pkg/release/v1/util/manifest_sorter_test.go | 2 -- pkg/repo/v1/chartrepo.go | 1 - pkg/repo/v1/chartrepo_test.go | 2 -- pkg/repo/v1/index_test.go | 3 --- pkg/repo/v1/repotest/server_test.go | 2 -- pkg/storage/driver/memory_test.go | 1 - pkg/storage/driver/sql.go | 1 - pkg/strvals/parser.go | 1 - 88 files changed, 1 insertion(+), 172 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 536b4b212..fa021ade9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -36,6 +36,7 @@ linters: - unused - usestdlibvars - usetesting + - whitespace exclusions: diff --git a/internal/chart/v3/lint/lint.go b/internal/chart/v3/lint/lint.go index e98edfabe..ea8ca3d60 100644 --- a/internal/chart/v3/lint/lint.go +++ b/internal/chart/v3/lint/lint.go @@ -44,7 +44,6 @@ func WithSkipSchemaValidation(skipSchemaValidation bool) LinterOption { } func RunAll(baseDir string, values map[string]any, namespace string, options ...LinterOption) support.Linter { - chartDir, _ := filepath.Abs(baseDir) lo := linterOptions{} diff --git a/internal/chart/v3/lint/rules/template_test.go b/internal/chart/v3/lint/rules/template_test.go index b1371659f..88343b330 100644 --- a/internal/chart/v3/lint/rules/template_test.go +++ b/internal/chart/v3/lint/rules/template_test.go @@ -242,7 +242,6 @@ data: // // See https://github.com/helm/helm/issues/7483 func TestStrictTemplateParsingMapError(t *testing.T) { - ch := chart.Chart{ Metadata: &chart.Metadata{ Name: "regression7483", @@ -371,7 +370,6 @@ func TestValidateTopIndentLevel(t *testing.T) { t.Errorf("Expected %t for %q", shouldFail, doc) } } - } // TestEmptyWithCommentsManifests checks the lint is not failing against empty manifests that contains only comments @@ -463,5 +461,4 @@ func TestIsYamlFileExtension(t *testing.T) { t.Errorf("isYamlFileExtension(%s) = %v; want %v", test.filename, result, test.expected) } } - } diff --git a/internal/chart/v3/loader/load_test.go b/internal/chart/v3/loader/load_test.go index c32f79aff..0ede21cfb 100644 --- a/internal/chart/v3/loader/load_test.go +++ b/internal/chart/v3/loader/load_test.go @@ -337,7 +337,6 @@ icon: https://example.com/64x64.png if text.String() != "" { t.Errorf("Expected no message to Stderr, got %s", text.String()) } - } // Packaging the chart on a Windows machine will produce an @@ -607,7 +606,6 @@ func verifyChart(t *testing.T, c *chart.Chart) { t.Errorf("Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) } } - } func verifyDependencies(t *testing.T, c *chart.Chart) { diff --git a/internal/chart/v3/util/create.go b/internal/chart/v3/util/create.go index 48d2120e5..b3d75ac2d 100644 --- a/internal/chart/v3/util/create.go +++ b/internal/chart/v3/util/create.go @@ -702,7 +702,6 @@ func CreateFrom(chartfile *chart.Metadata, dest, src string) error { // error. In such a case, this will attempt to clean up by removing the // new chart directory. func Create(name, dir string) (string, error) { - // Sanity-check the name of a chart so user doesn't create one that causes problems. if err := validateChartName(name); err != nil { return "", err diff --git a/internal/chart/v3/util/dependencies_test.go b/internal/chart/v3/util/dependencies_test.go index c8a176725..0a0937e4a 100644 --- a/internal/chart/v3/util/dependencies_test.go +++ b/internal/chart/v3/util/dependencies_test.go @@ -459,7 +459,6 @@ func TestDependentChartAliases(t *testing.T) { if aliasChart := getAliasDependency(c.Dependencies(), req[2]); aliasChart != nil { t.Fatalf("expected no chart but got %s", aliasChart.Name()) } - } func TestDependentChartWithSubChartsAbsentInDependency(t *testing.T) { diff --git a/internal/chart/v3/util/validate_name.go b/internal/chart/v3/util/validate_name.go index 6595e085d..7d85a5b88 100644 --- a/internal/chart/v3/util/validate_name.go +++ b/internal/chart/v3/util/validate_name.go @@ -79,7 +79,6 @@ func ValidateReleaseName(name string) error { // This case is preserved for backwards compatibility if name == "" { return errMissingName - } if len(name) > maxReleaseNameLen || !validName.MatchString(name) { return errInvalidName diff --git a/internal/cli/output/color_test.go b/internal/cli/output/color_test.go index 3b8de39e8..f0484fc3a 100644 --- a/internal/cli/output/color_test.go +++ b/internal/cli/output/color_test.go @@ -24,7 +24,6 @@ import ( ) func TestColorizeStatus(t *testing.T) { - tests := []struct { name string status common.Status @@ -107,7 +106,6 @@ func TestColorizeStatus(t *testing.T) { } func TestColorizeHeader(t *testing.T) { - tests := []struct { name string header string @@ -149,7 +147,6 @@ func TestColorizeHeader(t *testing.T) { } func TestColorizeNamespace(t *testing.T) { - tests := []struct { name string namespace string diff --git a/internal/monocular/client.go b/internal/monocular/client.go index f4ef5d647..cd1a0d666 100644 --- a/internal/monocular/client.go +++ b/internal/monocular/client.go @@ -33,7 +33,6 @@ type Client struct { // New creates a new client func New(u string) (*Client, error) { - // Validate we have a URL if err := validate(u); err != nil { return nil, err @@ -46,7 +45,6 @@ func New(u string) (*Client, error) { // Validate if the base URL for monocular is valid. func validate(u string) error { - // Check if it is parsable p, err := url.Parse(u) if err != nil { diff --git a/internal/monocular/search.go b/internal/monocular/search.go index fcf04b7a4..cfae87ded 100644 --- a/internal/monocular/search.go +++ b/internal/monocular/search.go @@ -99,7 +99,6 @@ type ChartVersion struct { // Search performs a search against the monocular search API func (c *Client) Search(term string) ([]SearchResult, error) { - // Create the URL to the search endpoint // Note, this is currently an internal API for the Hub. This should be // formatted without showing how monocular operates. diff --git a/internal/monocular/search_test.go b/internal/monocular/search_test.go index fc82ef4b4..cdf67f69e 100644 --- a/internal/monocular/search_test.go +++ b/internal/monocular/search_test.go @@ -27,7 +27,6 @@ import ( var searchResult = `{"data":[{"id":"stable/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"stable","url":"https://charts.helm.sh/stable"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/stable/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T17:57:31.38Z","digest":"119c499251bffd4b06ff0cd5ac98c2ce32231f84899fb4825be6c2d90971c742","urls":["https://charts.helm.sh/stable/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/stable/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/stable/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/stable/phpmyadmin/versions/3.0.0"}}}},{"id":"bitnami/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"bitnami","url":"https://charts.bitnami.com"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/bitnami/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T18:34:13.341Z","digest":"66d77cf6d8c2b52c488d0a294cd4996bd5bad8dc41d3829c394498fb401c008a","urls":["https://charts.bitnami.com/bitnami/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/bitnami/phpmyadmin/versions/3.0.0"}}}}]}` func TestSearch(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { fmt.Fprintln(w, searchResult) })) diff --git a/internal/plugin/installer/base_test.go b/internal/plugin/installer/base_test.go index 62b77bde5..6df8ec8a1 100644 --- a/internal/plugin/installer/base_test.go +++ b/internal/plugin/installer/base_test.go @@ -35,7 +35,6 @@ func TestPath(t *testing.T) { } for _, tt := range tests { - t.Setenv("HELM_PLUGINS", tt.helmPluginsDir) baseIns := newBase(tt.source) baseInsPath := baseIns.Path() diff --git a/internal/plugin/installer/extractor.go b/internal/plugin/installer/extractor.go index b753dfbca..3af56ab56 100644 --- a/internal/plugin/installer/extractor.go +++ b/internal/plugin/installer/extractor.go @@ -90,7 +90,6 @@ func NewExtractor(source string) (Extractor, error) { // - Beginning a path with a path separator is illegal // - Rudimentary symlink protections are offered by SecureJoin. func cleanJoin(root, dest string) (string, error) { - // On Windows, this is a drive separator. On UNIX-like, this is the path list separator. // In neither case do we want to trust a TAR that contains these. if strings.Contains(dest, ":") { diff --git a/internal/plugin/installer/http_installer_test.go b/internal/plugin/installer/http_installer_test.go index 85a84ee31..9ae8fe7b5 100644 --- a/internal/plugin/installer/http_installer_test.go +++ b/internal/plugin/installer/http_installer_test.go @@ -124,7 +124,6 @@ func TestHTTPInstaller(t *testing.T) { } else if err.Error() != "plugin already exists" { t.Fatalf("expected error for plugin exists, got (%v)", err) } - } func TestHTTPInstallerNonExistentVersion(t *testing.T) { @@ -157,7 +156,6 @@ func TestHTTPInstallerNonExistentVersion(t *testing.T) { if err := Install(i); err == nil { t.Fatal("expected error from http client") } - } func TestHTTPInstallerUpdate(t *testing.T) { @@ -297,7 +295,6 @@ func TestExtract(t *testing.T) { t.Fatalf("Expected %s to have %o mode but has %o (umask: %o)", readmeFullPath, expectedReadmePerm, info.Mode().Perm(), currentUmask) } - } func TestCleanJoin(t *testing.T) { @@ -327,11 +324,9 @@ func TestCleanJoin(t *testing.T) { t.Errorf("Test %d: Expected %q but got %q", i, fixture.expect, out) } } - } func TestMediaTypeToExtension(t *testing.T) { - for mt, shouldPass := range map[string]bool{ "": false, "application/gzip": true, diff --git a/internal/plugin/installer/installer.go b/internal/plugin/installer/installer.go index f0870dcc5..54effb1cb 100644 --- a/internal/plugin/installer/installer.go +++ b/internal/plugin/installer/installer.go @@ -72,7 +72,6 @@ type VerificationResult struct { // InstallWithOptions installs a plugin with options. func InstallWithOptions(i Installer, opts Options) (*VerificationResult, error) { - if err := os.MkdirAll(filepath.Dir(i.Path()), 0755); err != nil { return nil, err } diff --git a/internal/plugin/installer/vcs_installer_test.go b/internal/plugin/installer/vcs_installer_test.go index 7fe627b59..54f94c724 100644 --- a/internal/plugin/installer/vcs_installer_test.go +++ b/internal/plugin/installer/vcs_installer_test.go @@ -185,5 +185,4 @@ func TestVCSInstallerUpdate(t *testing.T) { } else if err.Error() != "plugin repo was modified" { t.Fatalf("expected error for plugin modified, got (%v)", err) } - } diff --git a/internal/plugin/loader.go b/internal/plugin/loader.go index 2f051b99e..bd7edbc2c 100644 --- a/internal/plugin/loader.go +++ b/internal/plugin/loader.go @@ -44,7 +44,6 @@ func peekAPIVersion(r io.Reader) (string, error) { } func loadMetadataLegacy(metadataData []byte) (*Metadata, error) { - var ml MetadataLegacy d := yaml.NewDecoder(bytes.NewReader(metadataData)) // NOTE: No strict unmarshalling for legacy plugins - maintain backwards compatibility @@ -64,7 +63,6 @@ func loadMetadataLegacy(metadataData []byte) (*Metadata, error) { } func loadMetadataV1(metadataData []byte) (*Metadata, error) { - var mv1 MetadataV1 d := yaml.NewDecoder(bytes.NewReader(metadataData)) d.KnownFields(true) @@ -108,7 +106,6 @@ type prototypePluginManager struct { } func newPrototypePluginManager() (*prototypePluginManager, error) { - cc, err := wazero.NewCompilationCacheWithDir(helmpath.CachePath("wazero-build")) if err != nil { return nil, fmt.Errorf("failed to create wazero compilation cache: %w", err) @@ -212,7 +209,6 @@ func findPlugins(pluginsDirs []string, findFn findFunc, filterFn filterFunc) ([] found = append(found, p) } } - } return found, nil @@ -225,7 +221,6 @@ func makeDescriptorFilter(descriptor Descriptor) filterFunc { // If name is specified, it must match if descriptor.Name != "" && p.Metadata().Name != descriptor.Name { return false - } // If type is specified, it must match if descriptor.Type != "" && p.Metadata().Type != descriptor.Type { diff --git a/internal/plugin/loader_test.go b/internal/plugin/loader_test.go index 03ef02c85..c8531a490 100644 --- a/internal/plugin/loader_test.go +++ b/internal/plugin/loader_test.go @@ -62,7 +62,6 @@ name: "test-plugin" } func TestLoadDir(t *testing.T) { - makeMetadata := func(apiVersion string) Metadata { usage := "hello [params]..." if apiVersion == "legacy" { diff --git a/internal/plugin/metadata_test.go b/internal/plugin/metadata_test.go index 145ef5101..f59b6a78d 100644 --- a/internal/plugin/metadata_test.go +++ b/internal/plugin/metadata_test.go @@ -21,7 +21,6 @@ import ( ) func TestValidatePluginData(t *testing.T) { - // A mock plugin with no commands mockNoCommand := mockSubprocessCLIPlugin(t, "foo") mockNoCommand.metadata.RuntimeConfig = &RuntimeConfigSubprocess{ diff --git a/internal/plugin/plugin_type_registry_test.go b/internal/plugin/plugin_type_registry_test.go index 22f26262d..157c2f1d7 100644 --- a/internal/plugin/plugin_type_registry_test.go +++ b/internal/plugin/plugin_type_registry_test.go @@ -28,7 +28,6 @@ func TestMakeOutputMessage(t *testing.T) { ptm := pluginTypesIndex["getter/v1"] outputType := reflect.Zero(ptm.outputType).Interface() assert.IsType(t, schema.OutputMessageGetterV1{}, outputType) - } func TestMakeConfig(t *testing.T) { diff --git a/internal/plugin/runtime_extismv1.go b/internal/plugin/runtime_extismv1.go index cd9a02535..ffa108a08 100644 --- a/internal/plugin/runtime_extismv1.go +++ b/internal/plugin/runtime_extismv1.go @@ -99,7 +99,6 @@ type RuntimeExtismV1 struct { var _ Runtime = (*RuntimeExtismV1)(nil) func (r *RuntimeExtismV1) CreatePlugin(pluginDir string, metadata *Metadata) (Plugin, error) { - rc, ok := metadata.RuntimeConfig.(*RuntimeConfigExtismV1) if !ok { return nil, fmt.Errorf("invalid extism/v1 plugin runtime config type: %T", metadata.RuntimeConfig) @@ -139,7 +138,6 @@ func (p *ExtismV1PluginRuntime) Dir() string { } func (p *ExtismV1PluginRuntime) Invoke(ctx context.Context, input *Input) (*Output, error) { - var tmpDir string if p.rc.FileSystem.CreateTempDir { tmpDirInner, err := os.MkdirTemp(os.TempDir(), "helm-plugin-*") diff --git a/internal/plugin/subprocess_commands_test.go b/internal/plugin/subprocess_commands_test.go index df854b4ca..dbce42f6a 100644 --- a/internal/plugin/subprocess_commands_test.go +++ b/internal/plugin/subprocess_commands_test.go @@ -48,7 +48,6 @@ func TestPrepareCommand(t *testing.T) { } func TestPrepareCommandExtraArgs(t *testing.T) { - cmdMain := "sh" cmdArgs := []string{"-c", "echo \"test\""} platformCommand := []PlatformCommand{ diff --git a/internal/release/v2/util/manifest_sorter_test.go b/internal/release/v2/util/manifest_sorter_test.go index 28f0b34cc..c8851d678 100644 --- a/internal/release/v2/util/manifest_sorter_test.go +++ b/internal/release/v2/util/manifest_sorter_test.go @@ -26,7 +26,6 @@ import ( ) func TestSortManifests(t *testing.T) { - data := []struct { name []string path string @@ -183,7 +182,6 @@ metadata: if !reflect.DeepEqual(expectedHooks, out.Events) { t.Errorf("expected events: %v but got: %v", expectedHooks, out.Events) } - } } if !found { diff --git a/internal/resolver/resolver.go b/internal/resolver/resolver.go index 184c8404b..5f0c5b148 100644 --- a/internal/resolver/resolver.go +++ b/internal/resolver/resolver.go @@ -54,7 +54,6 @@ func New(chartpath, cachepath string, registryClient *registry.Client) *Resolver // Resolve resolves dependencies and returns a lock file with the resolution. func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string) (*chart.Lock, error) { - // Now we clone the dependencies, locking as we go. locked := make([]*chart.Dependency, len(reqs)) missing := []string{} @@ -146,7 +145,6 @@ func (r *Resolver) Resolve(reqs []*chart.Dependency, repoNames map[string]string Version: version, }, }} - } else { // Retrieve list of tags for repository ref := fmt.Sprintf("%s/%s", strings.TrimPrefix(d.Repository, registry.OCIScheme+"://"), d.Name) diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go index 8f28c3af7..806e33c28 100644 --- a/internal/third_party/dep/fs/fs_test.go +++ b/internal/third_party/dep/fs/fs_test.go @@ -238,7 +238,6 @@ func TestCopyDirFail_SrcIsNotDir(t *testing.T) { if !errors.Is(err, errSrcNotDir) { t.Fatalf("expected %v error for CopyDir(%s, %s), got %s", errSrcNotDir, srcdir, dstdir, err) } - } func TestCopyDirFail_DstExists(t *testing.T) { @@ -491,7 +490,6 @@ func setupInaccessibleDir(t *testing.T, op func(dir string) error) func() { } func TestIsDir(t *testing.T) { - var currentUID = os.Getuid() if currentUID == 0 { @@ -544,7 +542,6 @@ func TestIsDir(t *testing.T) { } func TestIsSymlink(t *testing.T) { - var currentUID = os.Getuid() if currentUID == 0 { diff --git a/internal/version/version.go b/internal/version/version.go index 3daf80893..f37a97425 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -77,7 +77,6 @@ func GetUserAgent() string { // Get returns build info func Get() BuildInfo { - makeKubeClientVersionString := func() string { // Test builds don't include debug info / module info // (And even if they did, we probably want a stable version during tests anyway) diff --git a/pkg/action/action.go b/pkg/action/action.go index 75b6cf8a0..550d113da 100644 --- a/pkg/action/action.go +++ b/pkg/action/action.go @@ -521,7 +521,6 @@ func GetVersionSet(client discovery.ServerResourcesInterface) (common.VersionSet var ok bool for _, r := range resources { for _, rl := range r.APIResources { - // A Kind at a GroupVersion can show up more than once. We only want // it displayed once in the final output. id = path.Join(r.GroupVersion, rl.Kind) diff --git a/pkg/action/dependency.go b/pkg/action/dependency.go index 5c87f7cba..8ceca1433 100644 --- a/pkg/action/dependency.go +++ b/pkg/action/dependency.go @@ -120,7 +120,6 @@ func (d *Dependency) dependencyStatus(chartpath string, dep *chart.Dependency, p if r := statArchiveForStatus(archive, dep); r != "" { return r } - } // End unnecessary code. diff --git a/pkg/action/get_metadata.go b/pkg/action/get_metadata.go index 5312dac7f..7d5a3f5f9 100644 --- a/pkg/action/get_metadata.go +++ b/pkg/action/get_metadata.go @@ -119,7 +119,6 @@ func (m *Metadata) FormattedDepNames() string { continue } depsNames = append(depsNames, ac.Name()) - } sort.StringSlice(depsNames).Sort() diff --git a/pkg/action/hooks.go b/pkg/action/hooks.go index a4a8da7a6..9bd5ed788 100644 --- a/pkg/action/hooks.go +++ b/pkg/action/hooks.go @@ -35,7 +35,6 @@ import ( func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent, waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption, timeout time.Duration, serverSideApply bool) error { - shutdown, err := cfg.execHookWithDelayedShutdown(rl, hook, waitStrategy, waitOptions, timeout, serverSideApply) if shutdown == nil { return err @@ -59,7 +58,6 @@ func shutdownNoOp() error { func (cfg *Configuration) execHookWithDelayedShutdown(rl *release.Release, hook release.HookEvent, waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption, timeout time.Duration, serverSideApply bool) (ExecuteShutdownFunc, error) { - executingHooks := []*release.Hook{} for _, h := range rl.Hooks { @@ -179,7 +177,6 @@ func (x hookByWeight) Less(i, j int) bool { // deleteHookByPolicy deletes a hook if the hook policy instructs it to func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.HookDeletePolicy, waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption, timeout time.Duration) error { - // Never delete CustomResourceDefinitions; this could cause lots of // cascading garbage collection. if h.Kind == "CustomResourceDefinition" { @@ -214,7 +211,6 @@ func (cfg *Configuration) deleteHookByPolicy(h *release.Hook, policy release.Hoo // deleteHooksByPolicy deletes all hooks if the hook policy instructs it to func (cfg *Configuration) deleteHooksByPolicy(hooks []*release.Hook, policy release.HookDeletePolicy, waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption, timeout time.Duration) error { - for _, h := range hooks { if err := cfg.deleteHookByPolicy(h, policy, waitStrategy, waitOptions, timeout); err != nil { return err diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index e4d2b7376..5e5c5b227 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -737,7 +737,6 @@ func TestInstallRelease_RollbackOnFailure(t *testing.T) { }) } func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) { - is := assert.New(t) instAction := installAction(t) instAction.ReleaseName = "interrupted-release" @@ -767,7 +766,6 @@ func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) { is.Equal(goroutines+1, instAction.getGoroutineCount()) // installation goroutine still is in background time.Sleep(10 * time.Second) // wait for goroutine to finish is.Equal(goroutines, instAction.getGoroutineCount()) - } func TestNameTemplate(t *testing.T) { testCases := []nameTemplateTestCase{ @@ -804,7 +802,6 @@ func TestNameTemplate(t *testing.T) { } for _, tc := range testCases { - n, err := TemplateName(tc.tpl) if err != nil { if tc.expectedErrorStr == "" { diff --git a/pkg/action/package_test.go b/pkg/action/package_test.go index 2e1d4ff07..f8a55c0e0 100644 --- a/pkg/action/package_test.go +++ b/pkg/action/package_test.go @@ -150,7 +150,6 @@ func TestValidateVersion(t *testing.T) { if !errors.Is(err, tt.wantErr) { t.Errorf("Expected {%v}, got {%v}", tt.wantErr, err) } - } }) } diff --git a/pkg/action/resource_policy.go b/pkg/action/resource_policy.go index fcea98ad6..4f4e2ff55 100644 --- a/pkg/action/resource_policy.go +++ b/pkg/action/resource_policy.go @@ -40,7 +40,6 @@ func filterManifestsToKeep(manifests []releaseutil.Manifest) (keep, remaining [] if resourcePolicyType == kube.KeepPolicy { keep = append(keep, m) } - } return keep, remaining } diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 0f360fe37..05ff171db 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -263,7 +263,6 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chartv2.Chart, vals map[str return nil, nil, false, err } } - } // determine if values will be reused diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index 393692976..48721c1ae 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -446,7 +446,6 @@ func TestUpgradeRelease_Interrupted_Wait(t *testing.T) { } func TestUpgradeRelease_Interrupted_RollbackOnFailure(t *testing.T) { - is := assert.New(t) req := require.New(t) @@ -741,7 +740,6 @@ func TestGetUpgradeServerSideValue(t *testing.T) { assert.ErrorContains(t, err, tt.expectedErrorMsg) }) } - } func TestUpgradeRun_UnreachableKubeClient(t *testing.T) { diff --git a/pkg/action/validate_test.go b/pkg/action/validate_test.go index fd59abcb1..2223f57d5 100644 --- a/pkg/action/validate_test.go +++ b/pkg/action/validate_test.go @@ -273,7 +273,6 @@ func TestValidateNameAndGenerateName(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - skip, err := validateNameAndGenerateName(tc.info) if tc.wantErr { diff --git a/pkg/chart/common/capabilities.go b/pkg/chart/common/capabilities.go index 20f4953cf..16910acaa 100644 --- a/pkg/chart/common/capabilities.go +++ b/pkg/chart/common/capabilities.go @@ -167,7 +167,6 @@ func makeDefaultCapabilities() (*Capabilities, error) { } func newCapabilities(kubeVersionMajor, kubeVersionMinor uint64) (*Capabilities, error) { - version := fmt.Sprintf("v%d.%d.0", kubeVersionMajor, kubeVersionMinor) return &Capabilities{ KubeVersion: KubeVersion{ diff --git a/pkg/chart/common/util/coalesce_test.go b/pkg/chart/common/util/coalesce_test.go index 1d0baa84d..8ccdcebcf 100644 --- a/pkg/chart/common/util/coalesce_test.go +++ b/pkg/chart/common/util/coalesce_test.go @@ -666,7 +666,6 @@ func TestMergeTables(t *testing.T) { } func TestCoalesceValuesWarnings(t *testing.T) { - c := withDeps(&chart.Chart{ Metadata: &chart.Metadata{Name: "level1"}, Values: map[string]any{ @@ -724,7 +723,6 @@ func TestCoalesceValuesWarnings(t *testing.T) { assert.Contains(t, warnings, "warning: skipped value for level1.level2.level3.boat: Not a table.") assert.Contains(t, warnings, "warning: destination for level1.level2.level3.spear.tip is a table. Ignoring non-table value (true)") assert.Contains(t, warnings, "warning: cannot overwrite table with non table for level1.level2.level3.spear.sail (map[cotton:true])") - } func TestConcatPrefix(t *testing.T) { diff --git a/pkg/chart/common/util/values_test.go b/pkg/chart/common/util/values_test.go index 1dea04132..899ce3571 100644 --- a/pkg/chart/common/util/values_test.go +++ b/pkg/chart/common/util/values_test.go @@ -25,7 +25,6 @@ import ( ) func TestToRenderValues(t *testing.T) { - chartValues := map[string]any{ "name": "al Rashid", "where": map[string]any{ diff --git a/pkg/chart/loader/load.go b/pkg/chart/loader/load.go index 3fd381825..6fe246474 100644 --- a/pkg/chart/loader/load.go +++ b/pkg/chart/loader/load.go @@ -100,7 +100,6 @@ func LoadDir(dir string) (chart.Charter, error) { default: return nil, errors.New("unsupported chart version") } - } // FileLoader loads a chart from a file diff --git a/pkg/chart/v2/lint/lint.go b/pkg/chart/v2/lint/lint.go index 7f6f26320..23a93c551 100644 --- a/pkg/chart/v2/lint/lint.go +++ b/pkg/chart/v2/lint/lint.go @@ -44,7 +44,6 @@ func WithSkipSchemaValidation(skipSchemaValidation bool) LinterOption { } func RunAll(baseDir string, values map[string]any, namespace string, options ...LinterOption) support.Linter { - chartDir, _ := filepath.Abs(baseDir) lo := linterOptions{} diff --git a/pkg/chart/v2/lint/rules/template.go b/pkg/chart/v2/lint/rules/template.go index 43665aa3a..ac5f740a0 100644 --- a/pkg/chart/v2/lint/rules/template.go +++ b/pkg/chart/v2/lint/rules/template.go @@ -62,7 +62,6 @@ func TemplateLinterSkipSchemaValidation(skipSchemaValidation bool) TemplateLinte } func newTemplateLinter(linter *support.Linter, namespace string, values map[string]any, options ...TemplateLinterOption) templateLinter { - result := templateLinter{ linter: linter, values: values, diff --git a/pkg/chart/v2/lint/rules/template_test.go b/pkg/chart/v2/lint/rules/template_test.go index b6a62e8fd..f0eb008b3 100644 --- a/pkg/chart/v2/lint/rules/template_test.go +++ b/pkg/chart/v2/lint/rules/template_test.go @@ -257,7 +257,6 @@ data: // // See https://github.com/helm/helm/issues/7483 func TestStrictTemplateParsingMapError(t *testing.T) { - ch := chart.Chart{ Metadata: &chart.Metadata{ Name: "regression7483", @@ -390,7 +389,6 @@ func TestValidateTopIndentLevel(t *testing.T) { t.Errorf("Expected %t for %q", shouldFail, doc) } } - } // TestEmptyWithCommentsManifests checks the lint is not failing against empty manifests that contains only comments @@ -486,5 +484,4 @@ func TestIsYamlFileExtension(t *testing.T) { t.Errorf("isYamlFileExtension(%s) = %v; want %v", test.filename, result, test.expected) } } - } diff --git a/pkg/chart/v2/loader/load_test.go b/pkg/chart/v2/loader/load_test.go index dad988605..e14b68dc7 100644 --- a/pkg/chart/v2/loader/load_test.go +++ b/pkg/chart/v2/loader/load_test.go @@ -390,7 +390,6 @@ icon: https://example.com/64x64.png if text.String() != "" { t.Errorf("Expected no message to Stderr, got %s", text.String()) } - } // Packaging the chart on a Windows machine will produce an @@ -660,7 +659,6 @@ func verifyChart(t *testing.T, c *chart.Chart) { t.Errorf("Expected %s version %s, got %s", dep.Name(), exp["version"], dep.Metadata.Version) } } - } func verifyDependencies(t *testing.T, c *chart.Chart) { diff --git a/pkg/chart/v2/util/create.go b/pkg/chart/v2/util/create.go index 0d7ae8d5c..36e3bfe72 100644 --- a/pkg/chart/v2/util/create.go +++ b/pkg/chart/v2/util/create.go @@ -701,7 +701,6 @@ func CreateFrom(chartfile *chart.Metadata, dest, src string) error { // error. In such a case, this will attempt to clean up by removing the // new chart directory. func Create(name, dir string) (string, error) { - // Sanity-check the name of a chart so user doesn't create one that causes problems. if err := validateChartName(name); err != nil { return "", err diff --git a/pkg/chart/v2/util/dependencies_test.go b/pkg/chart/v2/util/dependencies_test.go index 0e4df8528..90a8806ec 100644 --- a/pkg/chart/v2/util/dependencies_test.go +++ b/pkg/chart/v2/util/dependencies_test.go @@ -459,7 +459,6 @@ func TestDependentChartAliases(t *testing.T) { if aliasChart := getAliasDependency(c.Dependencies(), req[2]); aliasChart != nil { t.Fatalf("expected no chart but got %s", aliasChart.Name()) } - } func TestDependentChartWithSubChartsAbsentInDependency(t *testing.T) { diff --git a/pkg/chart/v2/util/validate_name.go b/pkg/chart/v2/util/validate_name.go index 6595e085d..7d85a5b88 100644 --- a/pkg/chart/v2/util/validate_name.go +++ b/pkg/chart/v2/util/validate_name.go @@ -79,7 +79,6 @@ func ValidateReleaseName(name string) error { // This case is preserved for backwards compatibility if name == "" { return errMissingName - } if len(name) > maxReleaseNameLen || !validName.MatchString(name) { return errInvalidName diff --git a/pkg/cmd/completion_test.go b/pkg/cmd/completion_test.go index 81c1ee2ad..399ff1f0c 100644 --- a/pkg/cmd/completion_test.go +++ b/pkg/cmd/completion_test.go @@ -51,7 +51,6 @@ func checkFileCompletion(t *testing.T, cmdName string, shouldBePerformed bool) { if shouldBePerformed { t.Errorf("Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) } else { - t.Errorf("Did not receive directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName) } t.Log(out) diff --git a/pkg/cmd/flags.go b/pkg/cmd/flags.go index 5a220d1ce..e7db3dde2 100644 --- a/pkg/cmd/flags.go +++ b/pkg/cmd/flags.go @@ -220,7 +220,6 @@ func (p *postRendererArgsSlice) Type() string { } func (p *postRendererArgsSlice) Set(val string) error { - // a post-renderer defined by a user may accept empty arguments p.options.args = append(p.options.args, val) diff --git a/pkg/cmd/get_metadata.go b/pkg/cmd/get_metadata.go index eb90b6e44..c26af646f 100644 --- a/pkg/cmd/get_metadata.go +++ b/pkg/cmd/get_metadata.go @@ -77,7 +77,6 @@ func newGetMetadataCmd(cfg *action.Configuration, out io.Writer) *cobra.Command } func (w metadataWriter) WriteTable(out io.Writer) error { - formatApplyMethod := func(applyMethod string) string { switch applyMethod { case "": diff --git a/pkg/cmd/helpers.go b/pkg/cmd/helpers.go index e555dd18b..8866b8650 100644 --- a/pkg/cmd/helpers.go +++ b/pkg/cmd/helpers.go @@ -43,7 +43,6 @@ func addDryRunFlag(cmd *cobra.Command) { // Determine the `action.DryRunStrategy` given -dry-run=` flag (or absence of) // Legacy usage of the flag: boolean values, and `--dry-run` (without value) are supported, and log warnings emitted func cmdGetDryRunFlagStrategy(cmd *cobra.Command, isTemplate bool) (action.DryRunStrategy, error) { - f := cmd.Flag("dry-run") v := f.Value.String() diff --git a/pkg/cmd/helpers_test.go b/pkg/cmd/helpers_test.go index 08065499e..8710085e6 100644 --- a/pkg/cmd/helpers_test.go +++ b/pkg/cmd/helpers_test.go @@ -157,7 +157,6 @@ func resetEnv() func() { } func TestCmdGetDryRunFlagStrategy(t *testing.T) { - type testCaseExpectedLog struct { Level string Msg string @@ -274,7 +273,6 @@ func TestCmdGetDryRunFlagStrategy(t *testing.T) { } for name, tc := range testCases { - logBuf := new(bytes.Buffer) logger := slog.New(slog.NewJSONHandler(logBuf, nil)) slog.SetDefault(logger) diff --git a/pkg/cmd/history.go b/pkg/cmd/history.go index 3349b7bc1..77b5bd9b7 100644 --- a/pkg/cmd/history.go +++ b/pkg/cmd/history.go @@ -224,7 +224,6 @@ func getReleaseHistory(rls []*release.Release) (history releaseHistory) { } if !r.Info.LastDeployed.IsZero() { rInfo.Updated = r.Info.LastDeployed - } history = append(history, rInfo) } diff --git a/pkg/cmd/lint_test.go b/pkg/cmd/lint_test.go index a13ec423b..ec6d18de8 100644 --- a/pkg/cmd/lint_test.go +++ b/pkg/cmd/lint_test.go @@ -60,7 +60,6 @@ func TestLintCmdWithQuietFlag(t *testing.T) { wantError: true, }} runTestCmd(t, tests) - } func TestLintCmdWithKubeVersionFlag(t *testing.T) { diff --git a/pkg/cmd/load_plugins.go b/pkg/cmd/load_plugins.go index 029dd04f5..b6cc38ce6 100644 --- a/pkg/cmd/load_plugins.go +++ b/pkg/cmd/load_plugins.go @@ -333,7 +333,6 @@ func loadFile(path string) (*pluginCommand, error) { // to obtain the dynamic completion choices. It must pass all the flags and sub-commands // specified in the command-line to the plugin.complete executable (except helm's global flags) func pluginDynamicComp(plug plugin.Plugin, cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - subprocessPlug, ok := plug.(*plugin.SubprocessPluginRuntime) if !ok { // Completion only supported for subprocess plugins (TODO: fix this) diff --git a/pkg/cmd/pull_test.go b/pkg/cmd/pull_test.go index f749c218c..511061dcd 100644 --- a/pkg/cmd/pull_test.go +++ b/pkg/cmd/pull_test.go @@ -260,7 +260,6 @@ func TestPullCmd(t *testing.T) { if out != outString { t.Errorf("%q: expected verification output %q, got %q", tt.name, outString, out) } - } ef := filepath.Join(outdir, tt.expectFile) diff --git a/pkg/cmd/repo_index_test.go b/pkg/cmd/repo_index_test.go index c8959f21e..68f105d6d 100644 --- a/pkg/cmd/repo_index_test.go +++ b/pkg/cmd/repo_index_test.go @@ -28,7 +28,6 @@ import ( ) func TestRepoIndexCmd(t *testing.T) { - dir := t.TempDir() comp := filepath.Join(dir, "compressedchart-0.1.0.tgz") diff --git a/pkg/cmd/repo_remove_test.go b/pkg/cmd/repo_remove_test.go index f2641ccf0..79778e75e 100644 --- a/pkg/cmd/repo_remove_test.go +++ b/pkg/cmd/repo_remove_test.go @@ -103,7 +103,6 @@ func TestRepoRemove(t *testing.T) { cacheIndex, cacheChart := createCacheFiles(rootDir, repoName) cacheFiles[repoName] = []string{cacheIndex, cacheChart} - } // Create repo remove command diff --git a/pkg/cmd/root.go b/pkg/cmd/root.go index 04ba91c1f..1fa01ca0e 100644 --- a/pkg/cmd/root.go +++ b/pkg/cmd/root.go @@ -355,7 +355,6 @@ func hookOutputWriter(_, _, _ string) io.Writer { } func checkForExpiredRepos(repofile string) { - expiredRepos := []struct { name string old string @@ -399,7 +398,6 @@ func checkForExpiredRepos(repofile string) { ) } } - } func newRegistryClient( diff --git a/pkg/cmd/search.go b/pkg/cmd/search.go index 4d110286d..eb6c6e0b5 100644 --- a/pkg/cmd/search.go +++ b/pkg/cmd/search.go @@ -29,7 +29,6 @@ Use search subcommands to search different locations for charts. ` func newSearchCmd(out io.Writer) *cobra.Command { - cmd := &cobra.Command{ Use: "search [keyword]", Short: "search for a keyword in charts", diff --git a/pkg/cmd/search/search.go b/pkg/cmd/search/search.go index 1c7bb1d06..cb630709f 100644 --- a/pkg/cmd/search/search.go +++ b/pkg/cmd/search/search.go @@ -123,7 +123,6 @@ func (i *Index) Search(term string, threshold int, regexp bool) ([]*Result, erro // calcScore calculates a score for a match. func (i *Index) calcScore(index int, matchline string) int { - // This is currently tied to the fact that sep is a single char. splits := []int{} s := rune(sep[0]) diff --git a/pkg/cmd/search/search_test.go b/pkg/cmd/search/search_test.go index b3220394f..46394e77f 100644 --- a/pkg/cmd/search/search_test.go +++ b/pkg/cmd/search/search_test.go @@ -149,7 +149,6 @@ func TestAddRepo_Sort(t *testing.T) { } func TestSearchByName(t *testing.T) { - tests := []struct { name string query string @@ -245,7 +244,6 @@ func TestSearchByName(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - charts, err := i.Search(tt.query, 100, tt.regexp) if err != nil { if tt.fail { @@ -274,7 +272,6 @@ func TestSearchByName(t *testing.T) { t.Errorf("[%d]: Expected name %q, got %q", i, ex.Name, got.Name) } } - }) } } diff --git a/pkg/cmd/search_hub.go b/pkg/cmd/search_hub.go index f9adb73f4..3081961be 100644 --- a/pkg/cmd/search_hub.go +++ b/pkg/cmd/search_hub.go @@ -196,5 +196,4 @@ func (h *hubSearchWriter) encodeByFormat(out io.Writer, format output.Format) er // WriteJSON and WriteYAML, we shouldn't get invalid types return nil } - } diff --git a/pkg/cmd/search_hub_test.go b/pkg/cmd/search_hub_test.go index 8e056f771..4826181d2 100644 --- a/pkg/cmd/search_hub_test.go +++ b/pkg/cmd/search_hub_test.go @@ -24,7 +24,6 @@ import ( ) func TestSearchHubCmd(t *testing.T) { - // Setup a mock search service var searchResult = `{"data":[{"id":"stable/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"stable","url":"https://charts.helm.sh/stable"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/stable/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T17:57:31.38Z","digest":"119c499251bffd4b06ff0cd5ac98c2ce32231f84899fb4825be6c2d90971c742","urls":["https://charts.helm.sh/stable/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/stable/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/stable/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/stable/phpmyadmin/versions/3.0.0"}}}},{"id":"bitnami/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"bitnami","url":"https://charts.bitnami.com"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/bitnami/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T18:34:13.341Z","digest":"66d77cf6d8c2b52c488d0a294cd4996bd5bad8dc41d3829c394498fb401c008a","urls":["https://charts.bitnami.com/bitnami/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/bitnami/phpmyadmin/versions/3.0.0"}}}}]}` ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { @@ -54,7 +53,6 @@ func TestSearchHubCmd(t *testing.T) { } func TestSearchHubListRepoCmd(t *testing.T) { - // Setup a mock search service var searchResult = `{"data":[{"id":"stable/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"stable","url":"https://charts.helm.sh/stable"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/stable/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T17:57:31.38Z","digest":"119c499251bffd4b06ff0cd5ac98c2ce32231f84899fb4825be6c2d90971c742","urls":["https://charts.helm.sh/stable/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/stable/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/stable/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/stable/phpmyadmin/versions/3.0.0"}}}},{"id":"bitnami/phpmyadmin","type":"chart","attributes":{"name":"phpmyadmin","repo":{"name":"bitnami","url":"https://charts.bitnami.com"},"description":"phpMyAdmin is an mysql administration frontend","home":"https://www.phpmyadmin.net/","keywords":["mariadb","mysql","phpmyadmin"],"maintainers":[{"name":"Bitnami","email":"containers@bitnami.com"}],"sources":["https://github.com/bitnami/bitnami-docker-phpmyadmin"],"icon":""},"links":{"self":"/v1/charts/bitnami/phpmyadmin"},"relationships":{"latestChartVersion":{"data":{"version":"3.0.0","app_version":"4.9.0-1","created":"2019-08-08T18:34:13.341Z","digest":"66d77cf6d8c2b52c488d0a294cd4996bd5bad8dc41d3829c394498fb401c008a","urls":["https://charts.bitnami.com/bitnami/phpmyadmin-3.0.0.tgz"],"readme":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/README.md","values":"/v1/assets/bitnami/phpmyadmin/versions/3.0.0/values.yaml"},"links":{"self":"/v1/charts/bitnami/phpmyadmin/versions/3.0.0"}}}}]}` ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { diff --git a/pkg/cmd/template.go b/pkg/cmd/template.go index 047fd60df..e5789db8b 100644 --- a/pkg/cmd/template.go +++ b/pkg/cmd/template.go @@ -142,7 +142,6 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return err } } - } } diff --git a/pkg/cmd/uninstall.go b/pkg/cmd/uninstall.go index 49f7bd19d..bfecd4741 100644 --- a/pkg/cmd/uninstall.go +++ b/pkg/cmd/uninstall.go @@ -59,7 +59,6 @@ func newUninstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command { return validationErr } for i := range args { - res, err := client.Run(args[i]) if err != nil { return err diff --git a/pkg/cmd/upgrade_test.go b/pkg/cmd/upgrade_test.go index f96f6ec0d..30188d3d9 100644 --- a/pkg/cmd/upgrade_test.go +++ b/pkg/cmd/upgrade_test.go @@ -34,7 +34,6 @@ import ( ) func TestUpgradeCmd(t *testing.T) { - tmpChart := t.TempDir() cfile := &chart.Chart{ Metadata: &chart.Metadata{ @@ -222,7 +221,6 @@ func TestUpgradeWithValue(t *testing.T) { if !strings.Contains(updatedRel.Manifest, "drink: tea") { t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) } - } func TestUpgradeWithStringValue(t *testing.T) { @@ -253,11 +251,9 @@ func TestUpgradeWithStringValue(t *testing.T) { if !strings.Contains(updatedRel.Manifest, "drink: coffee") { t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) } - } func TestUpgradeInstallWithSubchartNotes(t *testing.T) { - releaseName := "wacky-bunny-v1" relMock, ch, _ := prepareMockRelease(t, releaseName) @@ -289,11 +285,9 @@ func TestUpgradeInstallWithSubchartNotes(t *testing.T) { if !strings.Contains(upgradedRel.Info.Notes, "SUBCHART NOTES") { t.Errorf("The subchart notes are not set correctly. NOTES: %s", upgradedRel.Info.Notes) } - } func TestUpgradeWithValuesFile(t *testing.T) { - releaseName := "funny-bunny-v4" relMock, ch, chartPath := prepareMockRelease(t, releaseName) @@ -321,11 +315,9 @@ func TestUpgradeWithValuesFile(t *testing.T) { if !strings.Contains(updatedRel.Manifest, "drink: beer") { t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) } - } func TestUpgradeWithValuesFromStdin(t *testing.T) { - releaseName := "funny-bunny-v5" relMock, ch, chartPath := prepareMockRelease(t, releaseName) @@ -361,7 +353,6 @@ func TestUpgradeWithValuesFromStdin(t *testing.T) { } func TestUpgradeInstallWithValuesFromStdin(t *testing.T) { - releaseName := "funny-bunny-v6" _, _, chartPath := prepareMockRelease(t, releaseName) @@ -392,7 +383,6 @@ func TestUpgradeInstallWithValuesFromStdin(t *testing.T) { if !strings.Contains(updatedRel.Manifest, "drink: beer") { t.Errorf("The value is not set correctly. manifest: %s", updatedRel.Manifest) } - } func prepareMockRelease(t *testing.T, releaseName string) (func(n string, v int, ch *chart.Chart) *release.Release, *chart.Chart, string) { diff --git a/pkg/cmd/verify_test.go b/pkg/cmd/verify_test.go index ae373afd2..050d799c9 100644 --- a/pkg/cmd/verify_test.go +++ b/pkg/cmd/verify_test.go @@ -22,7 +22,6 @@ import ( ) func TestVerifyCmd(t *testing.T) { - statExe := "stat" statPathMsg := "no such file or directory" statFileMsg := statPathMsg diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go index 9c26f925e..22c6c71a3 100644 --- a/pkg/downloader/chart_downloader.go +++ b/pkg/downloader/chart_downloader.go @@ -282,7 +282,6 @@ func (c *ChartDownloader) DownloadToCache(ref, version string) (string, *provena // If provenance is requested, verify it. ver := &provenance.Verification{} if c.Verify > VerifyNever { - ppth, err := c.Cache.Get(digest32, CacheProv) if err == nil { slog.Debug("found provenance in cache", "id", digestString) @@ -308,7 +307,6 @@ func (c *ChartDownloader) DownloadToCache(ref, version string) (string, *provena } if c.Verify != VerifyLater { - // provenance files pin to a specific name so this needs to be accounted for // when verifying. // Note, this does make an assumption that the name/version is unique to a diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go index fd4815cc4..3a999738e 100644 --- a/pkg/downloader/manager.go +++ b/pkg/downloader/manager.go @@ -502,11 +502,9 @@ Loop: // in a known repo and attempt to ensure the data is present for steps like // version resolution. func (m *Manager) ensureMissingRepos(repoNames map[string]string, deps []*chart.Dependency) (map[string]string, error) { - var ru []*repo.Entry for _, dd := range deps { - // If the chart is in the local charts directory no repository needs // to be specified. if dd.Repository == "" { @@ -679,7 +677,6 @@ func dedupeRepos(repos []*repo.Entry) []*repo.Entry { } func (m *Manager) parallelRepoUpdate(repos []*repo.Entry) error { - var wg sync.WaitGroup localRepos := dedupeRepos(repos) diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 09edc3337..8f8d4494c 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -657,7 +657,6 @@ func TestRenderDependency(t *testing.T) { if out["outerchart/templates/outer"] != expect { t.Errorf("Expected %q, got %q", expect, out["outer"]) } - } func TestRenderNestedValues(t *testing.T) { @@ -813,7 +812,6 @@ func TestRenderBuiltinValues(t *testing.T) { t.Errorf("Expected %q, got %q", expect, out[file]) } } - } func TestAlterFuncMap_include(t *testing.T) { @@ -1009,7 +1007,6 @@ func TestAlterFuncMap_tplinclude(t *testing.T) { if got := out["TplFunction/templates/base"]; got != expect { t.Errorf("Expected %q, got %q (%v)", expect, got, out) } - } func TestRenderRecursionLimit(t *testing.T) { @@ -1068,7 +1065,6 @@ func TestRenderRecursionLimit(t *testing.T) { if got := out["overlook/templates/quote"]; got != expect { t.Errorf("Expected %q, got %q (%v)", expect, got, out) } - } func TestRenderLoadTemplateForTplFromFile(t *testing.T) { @@ -1319,7 +1315,6 @@ func TestRenderTplMissingKeyString(t *testing.T) { if !strings.Contains(errTxt, "noSuchKey") { t.Errorf("Expected error to contain 'noSuchKey', got %s", errTxt) } - } func TestNestedHelpersProducesMultilineStacktrace(t *testing.T) { diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go index 7d4581233..f3116d626 100644 --- a/pkg/getter/httpgetter_test.go +++ b/pkg/getter/httpgetter_test.go @@ -510,7 +510,6 @@ func TestDownloadInsecureSkipTLSVerify(t *testing.T) { if _, err = g.Get(u.String()); err != nil { t.Error(err) } - } func TestHTTPGetterTarDownload(t *testing.T) { diff --git a/pkg/getter/plugingetter.go b/pkg/getter/plugingetter.go index ef8b87503..c683a1090 100644 --- a/pkg/getter/plugingetter.go +++ b/pkg/getter/plugingetter.go @@ -41,7 +41,6 @@ func collectGetterPlugins(settings *cli.EnvSettings) (Providers, error) { env := plugin.FormatEnv(settings.EnvVars()) pluginConstructorBuilder := func(plg plugin.Plugin) Constructor { return func(option ...Option) (Getter, error) { - return &getterPlugin{ options: append([]Option{}, option...), plg: plg, diff --git a/pkg/helmpath/lazypath.go b/pkg/helmpath/lazypath.go index c1f868754..bf6d71aa7 100644 --- a/pkg/helmpath/lazypath.go +++ b/pkg/helmpath/lazypath.go @@ -38,7 +38,6 @@ const ( type lazypath string func (l lazypath) path(helmEnvVar, xdgEnvVar string, defaultFn func() string, elem ...string) string { - // There is an order to checking for a path. // 1. See if a Helm specific environment variable has been set. // 2. Check if an XDG environment variable is set diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 44f31cdbe..96722bcd0 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -521,7 +521,6 @@ func determineFieldValidationDirective(validate bool) FieldValidationDirective { } func buildResourceList(f Factory, namespace string, validationDirective FieldValidationDirective, reader io.Reader, transformRequest resource.RequestTransform) (ResourceList, error) { - schema, err := f.Validator(string(validationDirective)) if err != nil { return nil, err @@ -859,7 +858,6 @@ func (c *Client) Update(originals, targets ResourceList, options ...ClientUpdate slog.String("fieldValidationDirective", string(updateOptions.fieldValidationDirective)), slog.Bool("upgradeClientSideFieldManager", updateOptions.upgradeClientSideFieldManager)) return func(original, target *resource.Info) error { - logger := c.Logger().With( slog.String("namespace", target.Namespace), slog.String("name", target.Name), @@ -954,7 +952,6 @@ func isIncompatibleServerError(err error) bool { // getManagedFieldsManager returns the manager string. If one was set it will be returned. // Otherwise, one is calculated based on the name of the binary. func getManagedFieldsManager() string { - // When a manager is explicitly set use it if ManagedFieldsManager != "" { return ManagedFieldsManager @@ -1102,7 +1099,6 @@ func createPatch(original runtime.Object, target *resource.Info, threeWayMergeFo } func replaceResource(target *resource.Info, fieldValidationDirective FieldValidationDirective) error { - helper := resource.NewHelper(target.Client, target.Mapping). WithFieldValidation(string(fieldValidationDirective)). WithFieldManager(getManagedFieldsManager()) @@ -1117,11 +1113,9 @@ func replaceResource(target *resource.Info, fieldValidationDirective FieldValida } return nil - } func patchResourceClientSide(original runtime.Object, target *resource.Info, threeWayMergeForUnstructured bool) error { - patch, patchType, err := createPatch(original, target, threeWayMergeForUnstructured) if err != nil { return fmt.Errorf("failed to create patch: %w", err) @@ -1155,14 +1149,12 @@ func patchResourceClientSide(original runtime.Object, target *resource.Info, thr // that upgrade CSA managed fields to SSA apply // see: https://github.com/kubernetes/kubernetes/pull/112905 func upgradeClientSideFieldManager(info *resource.Info, dryRun bool, fieldValidationDirective FieldValidationDirective) (bool, error) { - fieldManagerName := getManagedFieldsManager() patched := false err := retry.RetryOnConflict( retry.DefaultRetry, func() error { - if err := info.Get(); err != nil { return fmt.Errorf("failed to get object %s/%s %s: %w", info.Namespace, info.Name, info.Mapping.GroupVersionKind.String(), err) } diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 31894f68e..9b47a2df2 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -282,7 +282,6 @@ func TestCreate(t *testing.T) { c := newTestClient(t) for name, tc := range testCases { t.Run(name, func(t *testing.T) { - client := NewRequestResponseLogClient(t, func(previous []RequestResponseAction, req *http.Request) (*http.Response, error) { return tc.Callback(t, tc, previous, req) }) @@ -317,7 +316,6 @@ func TestCreate(t *testing.T) { } assert.Equal(t, tc.ExpectedActions, actions) - }) } } @@ -444,7 +442,6 @@ func TestUpdate(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - listOriginal := tc.OriginalPods listTarget := tc.TargetPods @@ -1409,7 +1406,6 @@ func TestIsReachable(t *testing.T) { if !strings.Contains(err.Error(), tt.errorContains) { t.Errorf("expected error message to contain '%s', got: %v", tt.errorContains, err) } - } else { if err != nil { t.Errorf("expected no error but got: %v", err) @@ -1487,7 +1483,6 @@ func TestReplaceResource(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - testFactory := cmdtesting.NewTestFactory() t.Cleanup(testFactory.Cleanup) @@ -1610,7 +1605,6 @@ func TestPatchResourceClientSide(t *testing.T) { t.Fail() return nil, nil - }, ExpectedErrorContains: "cannot patch \"whale\" with kind Pod: the server reported a conflict", }, @@ -1632,14 +1626,12 @@ func TestPatchResourceClientSide(t *testing.T) { t.Fail() return nil, nil // newResponse(http.StatusOK, &tc.TargetPods.Items[0]) - }, }, } for name, tc := range testCases { t.Run(name, func(t *testing.T) { - testFactory := cmdtesting.NewTestFactory() t.Cleanup(testFactory.Cleanup) @@ -1806,7 +1798,6 @@ func TestPatchResourceServerSide(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - testFactory := cmdtesting.NewTestFactory() t.Cleanup(testFactory.Cleanup) @@ -1837,7 +1828,6 @@ func TestPatchResourceServerSide(t *testing.T) { } func TestDetermineFieldValidationDirective(t *testing.T) { - assert.Equal(t, FieldValidationDirectiveIgnore, determineFieldValidationDirective(false)) assert.Equal(t, FieldValidationDirectiveStrict, determineFieldValidationDirective(true)) } diff --git a/pkg/registry/chart.go b/pkg/registry/chart.go index b00fc616d..d70b7e912 100644 --- a/pkg/registry/chart.go +++ b/pkg/registry/chart.go @@ -43,14 +43,12 @@ func extractChartMeta(chartData []byte) (*chart.Metadata, error) { // generateOCIAnnotations will generate OCI annotations to include within the OCI manifest func generateOCIAnnotations(meta *chart.Metadata, creationTime string) map[string]string { - // Get annotations from Chart attributes ociAnnotations := generateChartOCIAnnotations(meta, creationTime) // Copy Chart annotations annotations: for chartAnnotationKey, chartAnnotationValue := range meta.Annotations { - // Avoid overriding key properties for _, immutableOciKey := range immutableOciAnnotations { if immutableOciKey == chartAnnotationKey { @@ -88,7 +86,6 @@ func generateChartOCIAnnotations(meta *chart.Metadata, creationTime string) map[ var maintainerSb strings.Builder for maintainerIdx, maintainer := range meta.Maintainers { - if len(maintainer.Name) > 0 { maintainerSb.WriteString(maintainer.Name) } @@ -102,11 +99,9 @@ func generateChartOCIAnnotations(meta *chart.Metadata, creationTime string) map[ if maintainerIdx < len(meta.Maintainers)-1 { maintainerSb.WriteString(", ") } - } chartOCIAnnotations = addToMap(chartOCIAnnotations, ocispec.AnnotationAuthors, maintainerSb.String()) - } return chartOCIAnnotations @@ -114,7 +109,6 @@ func generateChartOCIAnnotations(meta *chart.Metadata, creationTime string) map[ // addToMap takes an existing map and adds an item if the value is not empty func addToMap(inputMap map[string]string, newKey string, newValue string) map[string]string { - // Add item to map if its if len(strings.TrimSpace(newValue)) > 0 { inputMap[newKey] = newValue diff --git a/pkg/registry/chart_test.go b/pkg/registry/chart_test.go index 77ccdaab7..0b247601b 100644 --- a/pkg/registry/chart_test.go +++ b/pkg/registry/chart_test.go @@ -27,7 +27,6 @@ import ( ) func TestGenerateOCIChartAnnotations(t *testing.T) { - nowString := time.Now().Format(time.RFC3339) tests := []struct { @@ -147,18 +146,15 @@ func TestGenerateOCIChartAnnotations(t *testing.T) { } for _, tt := range tests { - result := generateChartOCIAnnotations(tt.chart, nowString) if !reflect.DeepEqual(tt.expect, result) { t.Errorf("%s: expected map %v, got %v", tt.name, tt.expect, result) } - } } func TestGenerateOCIAnnotations(t *testing.T) { - nowString := time.Now().Format(time.RFC3339) tests := []struct { @@ -221,18 +217,15 @@ func TestGenerateOCIAnnotations(t *testing.T) { } for _, tt := range tests { - result := generateOCIAnnotations(tt.chart, nowString) if !reflect.DeepEqual(tt.expect, result) { t.Errorf("%s: expected map %v, got %v", tt.name, tt.expect, result) } - } } func TestGenerateOCICreatedAnnotations(t *testing.T) { - nowTime := time.Now() nowTimeString := nowTime.Format(time.RFC3339) @@ -268,7 +261,5 @@ func TestGenerateOCICreatedAnnotations(t *testing.T) { if !nowTime.Before(createdTimeAnnotation) { t.Errorf("%s annotation with value '%s' not configured properly. Annotation value is not after %s", ocispec.AnnotationCreated, result[ocispec.AnnotationCreated], nowTimeString) } - } - } diff --git a/pkg/registry/client.go b/pkg/registry/client.go index 62e560dba..2f3b344aa 100644 --- a/pkg/registry/client.go +++ b/pkg/registry/client.go @@ -816,7 +816,6 @@ func (c *Client) Tags(ref string) ([]string, error) { } return tags, nil - } // Resolve a reference to a descriptor. @@ -910,7 +909,6 @@ func (c *Client) ValidateReference(ref, version string, u *url.URL) (string, *ur func (c *Client) tagManifest(ctx context.Context, memoryStore *memory.Store, configDescriptor ocispec.Descriptor, layers []ocispec.Descriptor, ociAnnotations map[string]string, parsedRef reference) (ocispec.Descriptor, error) { - manifest := ocispec.Manifest{ Versioned: specs.Versioned{SchemaVersion: 2}, Config: configDescriptor, diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index b0c08fa3c..1e944025f 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -380,7 +380,6 @@ func initFakeRegistryTestServer() string { } func testPush(suite *TestRegistry) { - testingChartCreationTime := "1977-09-02T22:04:05Z" // Bad bytes diff --git a/pkg/release/v1/util/manifest_sorter_test.go b/pkg/release/v1/util/manifest_sorter_test.go index 4360013e5..baa320be0 100644 --- a/pkg/release/v1/util/manifest_sorter_test.go +++ b/pkg/release/v1/util/manifest_sorter_test.go @@ -26,7 +26,6 @@ import ( ) func TestSortManifests(t *testing.T) { - data := []struct { name []string path string @@ -183,7 +182,6 @@ metadata: if !reflect.DeepEqual(expectedHooks, out.Events) { t.Errorf("expected events: %v but got: %v", expectedHooks, out.Events) } - } } if !found { diff --git a/pkg/repo/v1/chartrepo.go b/pkg/repo/v1/chartrepo.go index deef7474e..09b74d602 100644 --- a/pkg/repo/v1/chartrepo.go +++ b/pkg/repo/v1/chartrepo.go @@ -173,7 +173,6 @@ func WithInsecureSkipTLSVerify(insecureSkipTLSVerify bool) FindChartInRepoURLOpt // FindChartInRepoURL finds chart in chart repository pointed by repoURL // without adding repo to repositories func FindChartInRepoURL(repoURL string, chartName string, getters getter.Providers, options ...FindChartInRepoURLOption) (string, error) { - opts := findChartInRepoURLOptions{} for _, option := range options { option(&opts) diff --git a/pkg/repo/v1/chartrepo_test.go b/pkg/repo/v1/chartrepo_test.go index 7cffc04b6..fbd081e1b 100644 --- a/pkg/repo/v1/chartrepo_test.go +++ b/pkg/repo/v1/chartrepo_test.go @@ -126,7 +126,6 @@ func TestConcurrencyDownloadIndex(t *testing.T) { // 2) read index.yaml via LoadIndexFile (read operation). // This checks for race conditions and ensures correct behavior under concurrent read/write access. for range 150 { - wg.Go(func() { idx, err := repo.DownloadIndexFile() if err != nil { @@ -234,7 +233,6 @@ func TestFindChartInRepoURL(t *testing.T) { } func TestErrorFindChartInRepoURL(t *testing.T) { - g := getter.All(&cli.EnvSettings{ RepositoryCache: t.TempDir(), }) diff --git a/pkg/repo/v1/index_test.go b/pkg/repo/v1/index_test.go index 6c6bb7835..3cacc95d4 100644 --- a/pkg/repo/v1/index_test.go +++ b/pkg/repo/v1/index_test.go @@ -140,7 +140,6 @@ func TestIndexFile(t *testing.T) { } func TestLoadIndex(t *testing.T) { - tests := []struct { Name string Filename string @@ -250,7 +249,6 @@ func TestMerge(t *testing.T) { if v := vs[1]; v.Version != "0.2.0" { t.Errorf("Expected %q version to be 0.2.0, got %s", v.Name, v.Version) } - } func TestDownloadIndexFile(t *testing.T) { @@ -642,7 +640,6 @@ func TestIgnoreSkippableChartValidationError(t *testing.T) { if !errors.Is(tc.Input, result) { t.Error("expected the result equal to input") } - }) } } diff --git a/pkg/repo/v1/repotest/server_test.go b/pkg/repo/v1/repotest/server_test.go index f0e374fc0..499091a57 100644 --- a/pkg/repo/v1/repotest/server_test.go +++ b/pkg/repo/v1/repotest/server_test.go @@ -143,7 +143,6 @@ func TestNewTempServer(t *testing.T) { if res.StatusCode != http.StatusOK { t.Errorf("Expected 200, got %d", res.StatusCode) } - } { @@ -203,7 +202,6 @@ func TestNewTempServer(t *testing.T) { } }) } - } func TestNewTempServer_TLS(t *testing.T) { diff --git a/pkg/storage/driver/memory_test.go b/pkg/storage/driver/memory_test.go index 329b82b2f..da3e02f42 100644 --- a/pkg/storage/driver/memory_test.go +++ b/pkg/storage/driver/memory_test.go @@ -300,5 +300,4 @@ func TestMemoryDelete(t *testing.T) { t.Logf("Name: %s, Version: %d", rac.Name(), rac.Version()) } } - } diff --git a/pkg/storage/driver/sql.go b/pkg/storage/driver/sql.go index 21d9f6679..ea85756eb 100644 --- a/pkg/storage/driver/sql.go +++ b/pkg/storage/driver/sql.go @@ -134,7 +134,6 @@ func (s *SQL) checkAlreadyApplied(migrations []*migrate.Migration) bool { } func (s *SQL) ensureDBSetup() error { - migrations := &migrate.MemoryMigrationSource{ Migrations: []*migrate.Migration{ { diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index cecaa2453..1dbbd0e1b 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -330,7 +330,6 @@ func (t *parser) keyIndex() (int, error) { } // v should be the index return strconv.Atoi(string(v)) - } func (t *parser) listItem(list []any, i, nestedNameLevel int) ([]any, error) { From 722dd3e3a82b06fbda60ebf24edc653e7b74e3f9 Mon Sep 17 00:00:00 2001 From: Jorge Rocamora <33847633+aeroyorch@users.noreply.github.com> Date: Sat, 11 Apr 2026 21:03:12 +0200 Subject: [PATCH 02/30] Add duration functions Signed-off-by: Jorge Rocamora <33847633+aeroyorch@users.noreply.github.com> --- pkg/engine/funcs.go | 226 +++++++++++++++++++++++++++++++++++ pkg/engine/funcs_test.go | 247 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 473 insertions(+) diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index e03c13b38..431f82f63 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -19,9 +19,15 @@ package engine import ( "bytes" "encoding/json" + "errors" + "fmt" "maps" + "math" + "reflect" + "strconv" "strings" "text/template" + "time" "github.com/BurntSushi/toml" "github.com/Masterminds/sprig/v3" @@ -62,6 +68,19 @@ func funcMap() template.FuncMap { "fromJson": fromJSON, "fromJsonArray": fromJSONArray, + // Duration helpers + "mustToDuration": mustToDuration, + "durationSeconds": durationSeconds, + "durationMilliseconds": durationMilliseconds, + "durationMicroseconds": durationMicroseconds, + "durationNanoseconds": durationNanoseconds, + "durationMinutes": durationMinutes, + "durationHours": durationHours, + "durationDays": durationDays, + "durationWeeks": durationWeeks, + "durationRoundTo": durationRoundTo, + "durationTruncateTo": durationTruncateTo, + // This is a placeholder for the "include" function, which is // late-bound to a template. By declaring it here, we preserve the // integrity of the linter. @@ -249,3 +268,210 @@ func fromJSONArray(str string) []any { } return a } + +// ----------------------------------------------------------------------------- +// Duration helpers (numeric and time.Duration returns) +// ----------------------------------------------------------------------------- + +const ( + maxDurationSeconds = int64(math.MaxInt64 / int64(time.Second)) + minDurationSeconds = int64(math.MinInt64 / int64(time.Second)) + maxDurationSecondsFloat = float64(math.MaxInt64) / float64(time.Second) + minDurationSecondsFloat = float64(math.MinInt64) / float64(time.Second) +) + +func durationFromSecondsInt(seconds int64) (time.Duration, error) { + if seconds > maxDurationSeconds || seconds < minDurationSeconds { + return 0, fmt.Errorf("duration seconds overflow: %d", seconds) + } + return time.Duration(seconds) * time.Second, nil +} + +func durationFromSecondsUint(seconds uint64) (time.Duration, error) { + if seconds > uint64(maxDurationSeconds) { + return 0, fmt.Errorf("duration seconds overflow: %d", seconds) + } + return time.Duration(int64(seconds)) * time.Second, nil +} + +func durationFromSecondsFloat(seconds float64) (time.Duration, error) { + if math.IsNaN(seconds) || math.IsInf(seconds, 0) { + return 0, fmt.Errorf("invalid duration seconds: %v", seconds) + } + if seconds > maxDurationSecondsFloat || seconds < minDurationSecondsFloat { + return 0, fmt.Errorf("duration seconds overflow: %v", seconds) + } + nanos := seconds * float64(time.Second) + if nanos > float64(math.MaxInt64) || nanos < float64(math.MinInt64) { + return 0, fmt.Errorf("duration nanoseconds overflow: %v", nanos) + } + return time.Duration(nanos), nil +} + +// asDuration converts common template values into a time.Duration. +// +// Supported inputs: +// - time.Duration +// - string duration values parsed by time.ParseDuration (e.g. "1h2m3s") +// - numeric strings treated as seconds (e.g. "2.5") +// - ints and uints treated as seconds +// - floats treated as seconds +func asDuration(v any) (time.Duration, error) { + switch x := v.(type) { + case time.Duration: + return x, nil + + case string: + s := strings.TrimSpace(x) + if s == "" { + return 0, errors.New("empty duration") + } + if d, err := time.ParseDuration(s); err == nil { + return d, nil + } + if f, err := strconv.ParseFloat(s, 64); err == nil { + return durationFromSecondsFloat(f) + } + return 0, fmt.Errorf("could not parse duration %q", x) + + case nil: + return 0, errors.New("invalid duration") + } + + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return durationFromSecondsInt(rv.Int()) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return durationFromSecondsUint(rv.Uint()) + case reflect.Float32, reflect.Float64: + return durationFromSecondsFloat(rv.Float()) + default: + return 0, fmt.Errorf("unsupported duration type %T", v) + } +} + +// mustToDuration takes anything and attempts to parse as a duration returning a time.Duration. +// +// This is designed to be called from a template when need to ensure that a +// duration is valid. +func mustToDuration(v any) time.Duration { + d, err := asDuration(v) + if err != nil { + panic(err) + } + return d +} + +// durationSeconds converts a duration to seconds (float64). +// On error it returns 0. +func durationSeconds(v any) float64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Seconds() +} + +// durationMilliseconds converts a duration to milliseconds (int64). +// On error it returns 0. +func durationMilliseconds(v any) int64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Milliseconds() +} + +// durationMicroseconds converts a duration to microseconds (int64). +// On error it returns 0. +func durationMicroseconds(v any) int64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Microseconds() +} + +// durationNanoseconds converts a duration to nanoseconds (int64). +// On error it returns 0. +func durationNanoseconds(v any) int64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Nanoseconds() +} + +// durationMinutes converts a duration to minutes (float64). +// On error it returns 0. +func durationMinutes(v any) float64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Minutes() +} + +// durationHours converts a duration to hours (float64). +// On error it returns 0. +func durationHours(v any) float64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Hours() +} + +// durationDays converts a duration to days (float64). (Not in Go's stdlib; handy in templates.) +// On error it returns 0. +func durationDays(v any) float64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Hours() / 24.0 +} + +// durationWeeks converts a duration to weeks (float64). (Not in Go's stdlib; handy in templates.) +// On error it returns 0. +func durationWeeks(v any) float64 { + d, err := asDuration(v) + if err != nil { + return 0 + } + return d.Hours() / 24.0 / 7.0 +} + +// durationRoundTo rounds v to the nearest multiple of m. +// Returns a time.Duration. +// +// v and m accept the same forms as asDuration (e.g. "2h13m", "30s"). +// On error, it returns time.Duration(0). If m is invalid, it returns v. +func durationRoundTo(v any, m any) time.Duration { + d, err := asDuration(v) + if err != nil { + return 0 + } + mul, err := asDuration(m) + if err != nil { + return d + } + return d.Round(mul) +} + +// durationTruncateTo truncates v toward zero to a multiple of m. +// Returns a time.Duration. +// +// On error, it returns time.Duration(0). If m is invalid, it returns v. +func durationTruncateTo(v any, m any) time.Duration { + d, err := asDuration(v) + if err != nil { + return 0 + } + mul, err := asDuration(m) + if err != nil { + return d + } + return d.Truncate(mul) +} diff --git a/pkg/engine/funcs_test.go b/pkg/engine/funcs_test.go index be9d0153f..cf6a8d5c9 100644 --- a/pkg/engine/funcs_test.go +++ b/pkg/engine/funcs_test.go @@ -17,11 +17,14 @@ limitations under the License. package engine import ( + "math" "strings" "testing" "text/template" + "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFuncs(t *testing.T) { @@ -151,6 +154,17 @@ keyInElement1 = "valueInElement1"`, }, { tpl: `{{ mustToJson . }}`, vars: loopMap, + }, { + tpl: `{{ mustToDuration 30 }}`, + expect: `30s`, + vars: nil, + }, { + tpl: `{{ mustToDuration "1m30s" }}`, + expect: `1m30s`, + vars: nil, + }, { + tpl: `{{ mustToDuration "foo" }}`, + vars: nil, }, { tpl: `{{ toYaml . }}`, expect: "", // should return empty string and swallow error @@ -181,6 +195,239 @@ keyInElement1 = "valueInElement1"`, } } +func TestDurationHelpers(t *testing.T) { + tests := []struct { + name string + tpl string + vars any + expect string + }{{ + name: "durationSeconds parses duration string", + tpl: `{{ durationSeconds "1m30s" }}`, + expect: `90`, + }, { + name: "durationSeconds parses numeric string as seconds", + tpl: `{{ durationSeconds "2.5" }}`, + expect: `2.5`, + }, { + name: "durationSeconds trims whitespace around numeric string", + tpl: `{{ durationSeconds " 2.5 " }}`, + expect: `2.5`, + }, { + name: "durationSeconds int treated as seconds", + tpl: `{{ durationSeconds 2 }}`, + expect: `2`, + }, { + name: "durationSeconds float treated as seconds", + tpl: `{{ durationSeconds 2.5 }}`, + expect: `2.5`, + }, { + name: "durationSeconds uint treated as seconds", + tpl: `{{ durationSeconds . }}`, + vars: uint(2), + expect: `2`, + }, { + name: "durationSeconds time.Duration passthrough", + tpl: `{{ durationSeconds . }}`, + vars: 1500 * time.Millisecond, + expect: `1.5`, + }, { + name: "invalid duration string returns 0", + tpl: `{{ durationSeconds "nope" }}`, + expect: `0`, + }, { + name: "empty duration string returns 0", + tpl: `{{ durationSeconds "" }}`, + expect: `0`, + }, { + name: "whitespace-only duration string returns 0", + tpl: `{{ durationSeconds " " }}`, + expect: `0`, + }, { + name: "nil returns 0", + tpl: `{{ durationSeconds . }}`, + vars: nil, + expect: `0`, + }, { + name: "durationSeconds uint overflow returns 0", + tpl: `{{ durationSeconds . }}`, + vars: uint64(math.MaxInt64) + 1, + expect: `0`, + }, { + name: "durationSeconds int overflow returns 0", + tpl: `{{ durationSeconds . }}`, + vars: maxDurationSeconds + 1, + expect: `0`, + }, { + name: "durationSeconds int underflow returns 0", + tpl: `{{ durationSeconds . }}`, + vars: minDurationSeconds - 1, + expect: `0`, + }, { + name: "durationSeconds float overflow returns 0", + tpl: `{{ durationSeconds . }}`, + vars: maxDurationSecondsFloat + 0.5, + expect: `0`, + }, { + name: "durationSeconds float underflow returns 0", + tpl: `{{ durationSeconds . }}`, + vars: minDurationSecondsFloat - 0.5, + expect: `0`, + }, { + name: "durationSeconds NaN returns 0", + tpl: `{{ durationSeconds . }}`, + vars: math.NaN(), + expect: `0`, + }, { + name: "durationSeconds Inf returns 0", + tpl: `{{ durationSeconds . }}`, + vars: math.Inf(1), + expect: `0`, + }, { + name: "durationMilliseconds int seconds", + tpl: `{{ durationMilliseconds 2 }}`, + expect: `2000`, + }, { + name: "durationMilliseconds float seconds", + tpl: `{{ durationMilliseconds 1.5 }}`, + expect: `1500`, + }, { + name: "durationMicroseconds int seconds", + tpl: `{{ durationMicroseconds 2 }}`, + expect: `2000000`, + }, { + name: "durationNanoseconds int seconds", + tpl: `{{ durationNanoseconds 2 }}`, + expect: `2000000000`, + }, { + name: "durationMinutes parses duration string", + tpl: `{{ durationMinutes "90s" }}`, + expect: `1.5`, + }, { + name: "durationHours parses duration string", + tpl: `{{ durationHours "90m" }}`, + expect: `1.5`, + }, { + name: "durationDays parses duration string", + tpl: `{{ durationDays "36h" }}`, + expect: `1.5`, + }, { + name: "durationDays numeric seconds", + tpl: `{{ durationDays 86400 }}`, + expect: `1`, + }, { + name: "durationWeeks parses duration string", + tpl: `{{ durationWeeks "168h" }}`, + expect: `1`, + }, { + name: "durationWeeks parses fractional weeks", + tpl: `{{ durationWeeks "252h" }}`, + expect: `1.5`, + }, { + name: "durationRoundTo numeric seconds", + tpl: `{{ durationRoundTo 93 60 }}`, // 93s rounded to 60s = 120s + expect: `2m0s`, + }, { + name: "durationTruncateTo numeric seconds", + tpl: `{{ durationTruncateTo 93 60 }}`, // 93s truncated to 60s = 60s + expect: `1m0s`, + }, { + name: "durationRoundTo accepts duration-string multiplier", + tpl: `{{ durationRoundTo "93s" "1m" }}`, + expect: `2m0s`, + }, { + name: "durationTruncateTo accepts duration-string multiplier", + tpl: `{{ durationTruncateTo "93s" "1m" }}`, + expect: `1m0s`, + }, { + name: "durationRoundTo invalid m returns v unchanged", + tpl: `{{ durationRoundTo "93s" "nope" }}`, + expect: `1m33s`, + }, { + name: "durationTruncateTo invalid m returns v unchanged", + tpl: `{{ durationTruncateTo "93s" "nope" }}`, + expect: `1m33s`, + }, { + name: "durationRoundTo zero m returns v unchanged", + tpl: `{{ durationRoundTo "93s" 0 }}`, + expect: `1m33s`, + }, { + name: "durationTruncateTo negative m returns v unchanged", + tpl: `{{ durationTruncateTo "93s" -1 }}`, + expect: `1m33s`, + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var b strings.Builder + err := template.Must(template.New("test").Funcs(funcMap()).Parse(tt.tpl)).Execute(&b, tt.vars) + require.NoError(t, err, tt.tpl) + assert.Equal(t, tt.expect, b.String(), tt.tpl) + }) + } + + mustErrTests := []struct { + name string + tpl string + vars any + }{{ + name: "mustToDuration invalid string", + tpl: `{{ mustToDuration "nope" }}`, + }, { + name: "mustToDuration empty string", + tpl: `{{ mustToDuration "" }}`, + }, { + name: "mustToDuration whitespace string", + tpl: `{{ mustToDuration " " }}`, + }, { + name: "mustToDuration unsupported type", + tpl: `{{ mustToDuration . }}`, + vars: []int{1, 2, 3}, + }, { + name: "mustToDuration uint overflow", + tpl: `{{ mustToDuration . }}`, + vars: uint64(math.MaxInt64) + 1, + }, { + name: "mustToDuration int overflow", + tpl: `{{ mustToDuration . }}`, + vars: maxDurationSeconds + 1, + }, { + name: "mustToDuration int underflow", + tpl: `{{ mustToDuration . }}`, + vars: minDurationSeconds - 1, + }, { + name: "mustToDuration float overflow", + tpl: `{{ mustToDuration . }}`, + vars: maxDurationSecondsFloat + 0.5, + }, { + name: "mustToDuration float underflow", + tpl: `{{ mustToDuration . }}`, + vars: minDurationSecondsFloat - 0.5, + }, { + name: "mustToDuration NaN", + tpl: `{{ mustToDuration . }}`, + vars: math.NaN(), + }, { + name: "mustToDuration Inf", + tpl: `{{ mustToDuration . }}`, + vars: math.Inf(-1), + }, + } + + for _, tt := range mustErrTests { + t.Run(tt.name, func(t *testing.T) { + var b strings.Builder + tmpl := template.Must( + template.New("test"). + Funcs(funcMap()). + Parse(tt.tpl), + ) + err := tmpl.Execute(&b, tt.vars) + require.Error(t, err, tt.tpl) + }) + } +} + // This test to check a function provided by sprig is due to a change in a // dependency of sprig. mergo in v0.3.9 changed the way it merges and only does // public fields (i.e. those starting with a capital letter). This test, from From 4e24ee41a436889a2542a008eaa0ecab8332a1eb Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Sun, 26 Apr 2026 09:16:27 -0600 Subject: [PATCH 03/30] fix(kube): prevent spurious early exit in WaitForDelete during informer sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During informer initialization there is a brief window where watched resources appear as Unknown before their real statuses are delivered. The statusObserver skips Unknown resources when waiting for deletion (they may have been deleted before the watch started), but if *all* resources are in that transient Unknown state the skipped-resource list is empty. AggregateStatus on an empty slice returns the desired status, causing cancel() to be called immediately — before any real status event has arrived. Guard against this by tracking the count of Unknown-skipped resources. When every resource was Unknown-skipped and none have a definitive status yet, defer the early-cancel decision until at least one resource reports a real status. This preserves the correct behaviour for resources that were genuinely deleted before the watch started (they eventually receive a NotFound or stay Unknown, and the aggregate succeeds), while fixing the race for resources that are transiently Unknown at startup. Also tighten the ctx.Err() check in waitForDelete: only append a deadline error when there are resource-specific errors to accompany it. A timeout while all resources are Unknown or NotFound is not itself an error — the resources are in an acceptable state for a delete wait. Fixes: TestStatusWaitForDelete/error_when_not_all_objects_are_deleted Signed-off-by: Terry Howe --- pkg/kube/statuswait.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/kube/statuswait.go b/pkg/kube/statuswait.go index 59c1218ff..a93d28fc1 100644 --- a/pkg/kube/statuswait.go +++ b/pkg/kube/statuswait.go @@ -160,7 +160,10 @@ func (w *statusWaiter) waitForDelete(ctx context.Context, resourceList ResourceL errs = append(errs, fmt.Errorf("resource %s/%s/%s still exists. status: %s, message: %s", rs.Identifier.GroupKind.Kind, rs.Identifier.Namespace, rs.Identifier.Name, rs.Status, rs.Message)) } - if err := ctx.Err(); err != nil { + // Only include a deadline error when there are also resource-specific errors. + // If all resources are Unknown or NotFound (e.g. deleted before the watch started), + // a timeout is not itself an error for WaitForDelete. + if err := ctx.Err(); err != nil && len(errs) > 0 { errs = append(errs, err) } if len(errs) > 0 { @@ -234,6 +237,7 @@ func statusObserver(cancel context.CancelFunc, desired status.Status, logger *sl return func(statusCollector *collector.ResourceStatusCollector, _ event.Event) { var rss []*event.ResourceStatus var nonDesiredResources []*event.ResourceStatus + var unknownSkipped int for _, rs := range statusCollector.ResourceStatuses { if rs == nil { continue @@ -241,6 +245,7 @@ func statusObserver(cancel context.CancelFunc, desired status.Status, logger *sl // If a resource is already deleted before waiting has started, it will show as unknown. // This check ensures we don't wait forever for a resource that is already deleted. if rs.Status == status.UnknownStatus && desired == status.NotFoundStatus { + unknownSkipped++ continue } // Failed is a terminal state. This check ensures we don't wait forever for a resource @@ -254,6 +259,14 @@ func statusObserver(cancel context.CancelFunc, desired status.Status, logger *sl } } + // During informer initialization there is a brief window where existing resources + // appear as Unknown before their real status is delivered. If every resource was + // skipped as Unknown, we cannot yet distinguish "all deleted" from "not yet synced", + // so hold off on the early-cancel to avoid a spurious success or premature exit. + if unknownSkipped > 0 && len(rss) == 0 { + return + } + if aggregator.AggregateStatus(rss, desired) == desired { logger.Debug("all resources achieved desired status", "desiredStatus", desired, "resourceCount", len(rss)) cancel() From 5e09ee78ee5861b857a3526a2fd1ddf2f73950e2 Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Sun, 26 Apr 2026 09:49:20 -0600 Subject: [PATCH 04/30] fix(kube): always propagate context.Canceled in WaitForDelete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous change suppressed ctx.Err() whenever there were no resource-specific errors, which incorrectly swallowed context.Canceled and other non-deadline errors signalling an external interruption. Refine the condition: only suppress context.DeadlineExceeded when there are no resource-specific errors (resources are Unknown/NotFound, meaning the delete wait succeeded or resources were already gone). Any other context error — including context.Canceled — is always propagated. Signed-off-by: Terry Howe --- pkg/kube/statuswait.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pkg/kube/statuswait.go b/pkg/kube/statuswait.go index a93d28fc1..10327358e 100644 --- a/pkg/kube/statuswait.go +++ b/pkg/kube/statuswait.go @@ -160,11 +160,16 @@ func (w *statusWaiter) waitForDelete(ctx context.Context, resourceList ResourceL errs = append(errs, fmt.Errorf("resource %s/%s/%s still exists. status: %s, message: %s", rs.Identifier.GroupKind.Kind, rs.Identifier.Namespace, rs.Identifier.Name, rs.Status, rs.Message)) } - // Only include a deadline error when there are also resource-specific errors. - // If all resources are Unknown or NotFound (e.g. deleted before the watch started), - // a timeout is not itself an error for WaitForDelete. - if err := ctx.Err(); err != nil && len(errs) > 0 { - errs = append(errs, err) + if err := ctx.Err(); err != nil { + // context.Canceled and other non-deadline errors always propagate: they signal an + // external interruption regardless of resource state. + // context.DeadlineExceeded is only added when there are resource-specific errors; + // if all resources are Unknown or NotFound the timeout is not itself a failure for + // a delete wait (e.g. resources deleted before the watch started stay Unknown in + // the fake client but are effectively gone). + if !errors.Is(err, context.DeadlineExceeded) || len(errs) > 0 { + errs = append(errs, err) + } } if len(errs) > 0 { return errors.Join(errs...) From f8ba28bb17f9254bc2c1b6409b24c16a59934a9c Mon Sep 17 00:00:00 2001 From: Matthieu MOREL Date: Mon, 27 Apr 2026 19:48:55 +0200 Subject: [PATCH 05/30] testifylint: enable error-is-as and error-nil rules Signed-off-by: Matthieu MOREL --- .golangci.yml | 2 - internal/chart/v3/chart_test.go | 2 +- internal/plugin/runtime_extismv1_test.go | 2 +- pkg/action/install_test.go | 8 +-- pkg/action/registry_login_test.go | 10 ++-- pkg/action/upgrade_test.go | 2 +- pkg/chart/v2/chart_test.go | 2 +- pkg/cmd/helpers_test.go | 4 +- pkg/engine/engine_test.go | 5 +- pkg/registry/client_http_test.go | 11 ++-- pkg/registry/client_insecure_tls_test.go | 8 +-- pkg/registry/client_tls_test.go | 16 +++--- pkg/registry/registry_test.go | 72 ++++++++++++------------ pkg/repo/v1/repotest/tlsconfig.go | 3 +- 14 files changed, 72 insertions(+), 75 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1ed3353b4..853324c6e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -101,8 +101,6 @@ linters: - empty - encoded-compare - equal-values - - error-is-as - - error-nil - expected-actual - float-compare - go-require diff --git a/internal/chart/v3/chart_test.go b/internal/chart/v3/chart_test.go index 5f6ca548d..f89030095 100644 --- a/internal/chart/v3/chart_test.go +++ b/internal/chart/v3/chart_test.go @@ -104,7 +104,7 @@ func TestMetadata(t *testing.T) { is.Equal("foo.yaml", chrt.Name()) is.Equal("1.0.0", chrt.AppVersion()) - is.Equal(nil, chrt.Validate()) + is.NoError(chrt.Validate()) } func TestIsRoot(t *testing.T) { diff --git a/internal/plugin/runtime_extismv1_test.go b/internal/plugin/runtime_extismv1_test.go index 8d9c55195..bcd791905 100644 --- a/internal/plugin/runtime_extismv1_test.go +++ b/internal/plugin/runtime_extismv1_test.go @@ -79,7 +79,7 @@ func TestRuntimeExtismV1InvokePlugin(t *testing.T) { Name: "Phippy", }, }) - require.Nil(t, err) + require.NoError(t, err) msg := output.Message.(schema.OutputMessageTestV1) assert.Equal(t, "Hello, Phippy! (6)", msg.Greeting) diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go index 05ca9a75e..38d692a0b 100644 --- a/pkg/action/install_test.go +++ b/pkg/action/install_test.go @@ -867,7 +867,7 @@ func TestInstallReleaseOutputDir(t *testing.T) { test.AssertGoldenFile(t, filepath.Join(dir, "hello/templates/rbac"), "rbac.txt") _, err = os.Stat(filepath.Join(dir, "hello/templates/empty")) - is.True(errors.Is(err, fs.ErrNotExist)) + is.ErrorIs(err, fs.ErrNotExist) } func TestInstallOutputDirWithReleaseName(t *testing.T) { @@ -903,7 +903,7 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) { test.AssertGoldenFile(t, filepath.Join(newDir, "hello/templates/rbac"), "rbac.txt") _, err = os.Stat(filepath.Join(newDir, "hello/templates/empty")) - is.True(errors.Is(err, fs.ErrNotExist)) + is.ErrorIs(err, fs.ErrNotExist) } func TestNameAndChart(t *testing.T) { @@ -1168,7 +1168,7 @@ func TestInstallCRDs_AlreadyExist(t *testing.T) { mockChart := buildChart(withFile(mockFile)) crdsToInstall := mockChart.CRDObjects() - assert.Nil(t, instAction.installCRDs(crdsToInstall)) + assert.NoError(t, instAction.installCRDs(crdsToInstall)) } func TestInstallCRDs_KubeClient_BuildError(t *testing.T) { @@ -1227,7 +1227,7 @@ func TestCheckDependencies(t *testing.T) { dependency := chart.Dependency{Name: "hello"} mockChart := buildChart(withDependency()) - assert.Nil(t, CheckDependencies(mockChart, []ci.Dependency{&dependency})) + assert.NoError(t, CheckDependencies(mockChart, []ci.Dependency{&dependency})) } func TestCheckDependencies_MissingDependency(t *testing.T) { diff --git a/pkg/action/registry_login_test.go b/pkg/action/registry_login_test.go index 590673b3a..474118c9f 100644 --- a/pkg/action/registry_login_test.go +++ b/pkg/action/registry_login_test.go @@ -37,7 +37,7 @@ func TestWithCertFile(t *testing.T) { certFile := "testdata/cert.pem" opt := WithCertFile(certFile) - assert.Nil(t, opt(client)) + assert.NoError(t, opt(client)) assert.Equal(t, certFile, client.certFile) } @@ -47,7 +47,7 @@ func TestWithInsecure(t *testing.T) { opt := WithInsecure(true) - assert.Nil(t, opt(client)) + assert.NoError(t, opt(client)) assert.True(t, client.insecure) } @@ -58,7 +58,7 @@ func TestWithKeyFile(t *testing.T) { keyFile := "testdata/key.pem" opt := WithKeyFile(keyFile) - assert.Nil(t, opt(client)) + assert.NoError(t, opt(client)) assert.Equal(t, keyFile, client.keyFile) } @@ -69,7 +69,7 @@ func TestWithCAFile(t *testing.T) { caFile := "testdata/ca.pem" opt := WithCAFile(caFile) - assert.Nil(t, opt(client)) + assert.NoError(t, opt(client)) assert.Equal(t, caFile, client.caFile) } @@ -79,6 +79,6 @@ func TestWithPlainHTTPLogin(t *testing.T) { opt := WithPlainHTTPLogin(true) - assert.Nil(t, opt(client)) + assert.NoError(t, opt(client)) assert.True(t, client.plainHTTP) } diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go index 393692976..4e48b28a6 100644 --- a/pkg/action/upgrade_test.go +++ b/pkg/action/upgrade_test.go @@ -716,7 +716,7 @@ func TestGetUpgradeServerSideValue(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { serverSideApply, err := getUpgradeServerSideValue(tt.actionServerSideOption, tt.releaseApplyMethod) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, tt.expectedServerSideApply, serverSideApply) }) } diff --git a/pkg/chart/v2/chart_test.go b/pkg/chart/v2/chart_test.go index d44e7251b..52e9c6b43 100644 --- a/pkg/chart/v2/chart_test.go +++ b/pkg/chart/v2/chart_test.go @@ -104,7 +104,7 @@ func TestMetadata(t *testing.T) { is.Equal("foo.yaml", chrt.Name()) is.Equal("1.0.0", chrt.AppVersion()) - is.Equal(nil, chrt.Validate()) + is.NoError(chrt.Validate()) } func TestIsRoot(t *testing.T) { diff --git a/pkg/cmd/helpers_test.go b/pkg/cmd/helpers_test.go index 08065499e..9b4483793 100644 --- a/pkg/cmd/helpers_test.go +++ b/pkg/cmd/helpers_test.go @@ -290,14 +290,14 @@ func TestCmdGetDryRunFlagStrategy(t *testing.T) { if tc.ExpectedError { assert.Error(t, err) } else { - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, tc.ExpectedStrategy, dryRunStrategy) } if tc.ExpectedLog != nil { logResult := map[string]string{} err = json.Unmarshal(logBuf.Bytes(), &logResult) - require.Nil(t, err) + require.NoError(t, err) assert.Equal(t, tc.ExpectedLog.Level, logResult["level"]) assert.Equal(t, tc.ExpectedLog.Msg, logResult["msg"]) diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 869b5d202..f618dbb44 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -27,6 +27,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -1357,7 +1358,7 @@ NestedHelperFunctions/charts/common/templates/_helpers_2.tpl:1:49 } _, err := Render(c, vals) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, expectedErrorMessage, err.Error()) } @@ -1391,7 +1392,7 @@ template: no template "nested_helper.name" associated with template "gotpl"` } _, err := Render(c, vals) - assert.NotNil(t, err) + require.Error(t, err) assert.Equal(t, expectedErrorMessage, err.Error()) } diff --git a/pkg/registry/client_http_test.go b/pkg/registry/client_http_test.go index 1c6751559..3eb74c541 100644 --- a/pkg/registry/client_http_test.go +++ b/pkg/registry/client_http_test.go @@ -17,7 +17,6 @@ limitations under the License. package registry import ( - "errors" "os" "testing" @@ -43,12 +42,12 @@ func (suite *HTTPRegistryClientTestSuite) Test_0_Login() { err := suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), LoginOptPlainText(true)) - suite.NotNil(err, "error logging into registry with bad credentials") + suite.Require().Error(err, "error logging into registry with bad credentials") err = suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), LoginOptPlainText(true)) - suite.Nil(err, "no error logging into registry with good credentials") + suite.Require().NoError(err, "no error logging into registry with good credentials") } func (suite *HTTPRegistryClientTestSuite) Test_1_Push() { @@ -68,15 +67,15 @@ func (suite *HTTPRegistryClientTestSuite) Test_4_ManInTheMiddle() { // returns content that does not match the expected digest _, err := suite.RegistryClient.Pull(ref) - suite.NotNil(err) - suite.True(errors.Is(err, content.ErrMismatchedDigest)) + suite.Require().Error(err) + suite.ErrorIs(err, content.ErrMismatchedDigest) } func (suite *HTTPRegistryClientTestSuite) Test_5_ImageIndex() { ref := suite.FakeRegistryHost + "/testrepo/image-index:0.1.0" _, err := suite.RegistryClient.Pull(ref) - suite.Nil(err) + suite.Require().NoError(err) } func TestHTTPRegistryClientTestSuite(t *testing.T) { diff --git a/pkg/registry/client_insecure_tls_test.go b/pkg/registry/client_insecure_tls_test.go index 2774f5e6f..8c4e928e4 100644 --- a/pkg/registry/client_insecure_tls_test.go +++ b/pkg/registry/client_insecure_tls_test.go @@ -41,12 +41,12 @@ func (suite *InsecureTLSRegistryClientTestSuite) Test_0_Login() { err := suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), LoginOptInsecure(true)) - suite.NotNil(err, "error logging into registry with bad credentials") + suite.Require().Error(err, "error logging into registry with bad credentials") err = suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), LoginOptInsecure(true)) - suite.Nil(err, "no error logging into registry with good credentials") + suite.Require().NoError(err, "no error logging into registry with good credentials") } func (suite *InsecureTLSRegistryClientTestSuite) Test_1_Push() { @@ -65,11 +65,11 @@ func (suite *InsecureTLSRegistryClientTestSuite) Test_4_Logout() { err := suite.RegistryClient.Logout("this-host-aint-real:5000") if err != nil { // credential backend for mac generates an error - suite.NotNil(err, "failed to delete the credential for this-host-aint-real:5000") + suite.Require().Error(err, "failed to delete the credential for this-host-aint-real:5000") } err = suite.RegistryClient.Logout(suite.DockerRegistryHost) - suite.Nil(err, "no error logging out of registry") + suite.Require().NoError(err, "no error logging out of registry") } func TestInsecureTLSRegistryClientTestSuite(t *testing.T) { diff --git a/pkg/registry/client_tls_test.go b/pkg/registry/client_tls_test.go index ddeeb3b66..2bea0377f 100644 --- a/pkg/registry/client_tls_test.go +++ b/pkg/registry/client_tls_test.go @@ -43,26 +43,26 @@ func (suite *TLSRegistryClientTestSuite) Test_0_Login() { err := suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)) - suite.NotNil(err, "error logging into registry with bad credentials") + suite.Require().Error(err, "error logging into registry with bad credentials") err = suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), LoginOptTLSClientConfig(tlsCert, tlsKey, tlsCA)) - suite.Nil(err, "no error logging into registry with good credentials") + suite.Require().NoError(err, "no error logging into registry with good credentials") } func (suite *TLSRegistryClientTestSuite) Test_1_Login() { err := suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth("badverybad", "ohsobad"), LoginOptTLSClientConfigFromConfig(&tls.Config{})) - suite.NotNil(err, "error logging into registry with bad credentials") + suite.Require().Error(err, "error logging into registry with bad credentials") // Create a *tls.Config from tlsCert, tlsKey, and tlsCA. cert, err := tls.LoadX509KeyPair(tlsCert, tlsKey) - suite.Nil(err, "error loading x509 key pair") + suite.Require().NoError(err, "error loading x509 key pair") rootCAs := x509.NewCertPool() caCert, err := os.ReadFile(tlsCA) - suite.Nil(err, "error reading CA certificate") + suite.Require().NoError(err, "error reading CA certificate") rootCAs.AppendCertsFromPEM(caCert) conf := &tls.Config{ Certificates: []tls.Certificate{cert}, @@ -72,7 +72,7 @@ func (suite *TLSRegistryClientTestSuite) Test_1_Login() { err = suite.RegistryClient.Login(suite.DockerRegistryHost, LoginOptBasicAuth(testUsername, testPassword), LoginOptTLSClientConfigFromConfig(conf)) - suite.Nil(err, "no error logging into registry with good credentials") + suite.Require().NoError(err, "no error logging into registry with good credentials") } func (suite *TLSRegistryClientTestSuite) Test_1_Push() { @@ -91,11 +91,11 @@ func (suite *TLSRegistryClientTestSuite) Test_4_Logout() { err := suite.RegistryClient.Logout("this-host-aint-real:5000") if err != nil { // credential backend for mac generates an error - suite.NotNil(err, "failed to delete the credential for this-host-aint-real:5000") + suite.Require().Error(err, "failed to delete the credential for this-host-aint-real:5000") } err = suite.RegistryClient.Logout(suite.DockerRegistryHost) - suite.Nil(err, "no error logging out of registry") + suite.Require().NoError(err, "no error logging out of registry") } func TestTLSRegistryClientTestSuite(t *testing.T) { diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index b0c08fa3c..9b9f51ca0 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -107,26 +107,26 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool) { TLSClientConfig: tlsConf, }, } - suite.Nil(err, "no error loading tls config") + suite.Require().NoError(err, "no error loading tls config") opts = append(opts, ClientOptHTTPClient(httpClient)) } else { opts = append(opts, ClientOptPlainHTTP()) } suite.RegistryClient, err = NewClient(opts...) - suite.Nil(err, "no error creating registry client") + suite.Require().NoError(err, "no error creating registry client") // create htpasswd file (w BCrypt, which is required) pwBytes, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost) - suite.Nil(err, "no error generating bcrypt password for test htpasswd file") + suite.Require().NoError(err, "no error generating bcrypt password for test htpasswd file") htpasswdPath := filepath.Join(suite.WorkspaceDir, testHtpasswdFileBasename) err = os.WriteFile(htpasswdPath, fmt.Appendf(nil, "%s:%s\n", testUsername, string(pwBytes)), 0644) - suite.Nil(err, "no error creating test htpasswd file") + suite.Require().NoError(err, "no error creating test htpasswd file") // Registry config config := &configuration.Configuration{} ln, err := net.Listen("tcp", "127.0.0.1:0") - suite.Nil(err, "no error finding free port for test registry") + suite.Require().NoError(err, "no error finding free port for test registry") defer func() { _ = ln.Close() }() // Change the registry host to another host which is not localhost. @@ -159,7 +159,7 @@ func setup(suite *TestRegistry, tlsEnabled, insecure bool) { } } suite.dockerRegistry, err = registry.NewRegistry(context.Background(), config) - suite.Nil(err, "no error creating test registry") + suite.Require().NoError(err, "no error creating test registry") suite.FakeRegistryHost = initFakeRegistryTestServer() suite.CompromisedRegistryHost = initCompromisedRegistryTestServer() @@ -386,61 +386,61 @@ func testPush(suite *TestRegistry) { // Bad bytes ref := suite.DockerRegistryHost + "/testrepo/testchart:1.2.3" _, err := suite.RegistryClient.Push([]byte("hello"), ref, PushOptCreationTime(testingChartCreationTime)) - suite.NotNil(err, "error pushing non-chart bytes") + suite.Require().Error(err, "error pushing non-chart bytes") // Load a test chart chartData, err := os.ReadFile("../repo/v1/repotest/testdata/examplechart-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err := extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") // non-strict ref (chart name) ref = fmt.Sprintf("%s/testrepo/boop:%s", suite.DockerRegistryHost, meta.Version) _, err = suite.RegistryClient.Push(chartData, ref, PushOptCreationTime(testingChartCreationTime)) - suite.NotNil(err, "error pushing non-strict ref (bad basename)") + suite.Require().Error(err, "error pushing non-strict ref (bad basename)") // non-strict ref (chart name), with strict mode disabled _, err = suite.RegistryClient.Push(chartData, ref, PushOptStrictMode(false), PushOptCreationTime(testingChartCreationTime)) - suite.Nil(err, "no error pushing non-strict ref (bad basename), with strict mode disabled") + suite.Require().NoError(err, "no error pushing non-strict ref (bad basename), with strict mode disabled") // non-strict ref (chart version) ref = fmt.Sprintf("%s/testrepo/%s:latest", suite.DockerRegistryHost, meta.Name) _, err = suite.RegistryClient.Push(chartData, ref, PushOptCreationTime(testingChartCreationTime)) - suite.NotNil(err, "error pushing non-strict ref (bad tag)") + suite.Require().Error(err, "error pushing non-strict ref (bad tag)") // non-strict ref (chart version), with strict mode disabled _, err = suite.RegistryClient.Push(chartData, ref, PushOptStrictMode(false), PushOptCreationTime(testingChartCreationTime)) - suite.Nil(err, "no error pushing non-strict ref (bad tag), with strict mode disabled") + suite.Require().NoError(err, "no error pushing non-strict ref (bad tag), with strict mode disabled") // basic push, good ref chartData, err = os.ReadFile("../downloader/testdata/local-subchart-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err = extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") ref = fmt.Sprintf("%s/testrepo/%s:%s", suite.DockerRegistryHost, meta.Name, meta.Version) _, err = suite.RegistryClient.Push(chartData, ref, PushOptCreationTime(testingChartCreationTime)) - suite.Nil(err, "no error pushing good ref") + suite.Require().NoError(err, "no error pushing good ref") _, err = suite.RegistryClient.Pull(ref) - suite.Nil(err, "no error pulling a simple chart") + suite.Require().NoError(err, "no error pulling a simple chart") // Load another test chart chartData, err = os.ReadFile("../downloader/testdata/signtest-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err = extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") // Load prov file provData, err := os.ReadFile("../downloader/testdata/signtest-0.1.0.tgz.prov") - suite.Nil(err, "no error loading test prov") + suite.Require().NoError(err, "no error loading test prov") // push with prov ref = fmt.Sprintf("%s/testrepo/%s:%s", suite.DockerRegistryHost, meta.Name, meta.Version) result, err := suite.RegistryClient.Push(chartData, ref, PushOptProvData(provData), PushOptCreationTime(testingChartCreationTime)) - suite.Nil(err, "no error pushing good ref with prov") + suite.Require().NoError(err, "no error pushing good ref with prov") _, err = suite.RegistryClient.Pull(ref, PullOptWithProv(true)) - suite.Nil(err, "no error pulling a simple chart") + suite.Require().NoError(err, "no error pulling a simple chart") // Validate the output // Note: these digests/sizes etc may change if the test chart/prov files are modified, @@ -470,50 +470,50 @@ func testPull(suite *TestRegistry) { // bad/missing ref ref := suite.DockerRegistryHost + "/testrepo/no-existy:1.2.3" _, err := suite.RegistryClient.Pull(ref) - suite.NotNil(err, "error on bad/missing ref") + suite.Require().Error(err, "error on bad/missing ref") // Load test chart (to build ref pushed in previous test) chartData, err := os.ReadFile("../downloader/testdata/local-subchart-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err := extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") ref = fmt.Sprintf("%s/testrepo/%s:%s", suite.DockerRegistryHost, meta.Name, meta.Version) // Simple pull, chart only _, err = suite.RegistryClient.Pull(ref) - suite.Nil(err, "no error pulling a simple chart") + suite.Require().NoError(err, "no error pulling a simple chart") // Simple pull with prov (no prov uploaded) _, err = suite.RegistryClient.Pull(ref, PullOptWithProv(true)) - suite.NotNil(err, "error pulling a chart with prov when no prov exists") + suite.Require().Error(err, "error pulling a chart with prov when no prov exists") // Simple pull with prov, ignoring missing prov _, err = suite.RegistryClient.Pull(ref, PullOptWithProv(true), PullOptIgnoreMissingProv(true)) - suite.Nil(err, + suite.Require().NoError(err, "no error pulling a chart with prov when no prov exists, ignoring missing") // Load test chart (to build ref pushed in previous test) chartData, err = os.ReadFile("../downloader/testdata/signtest-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err = extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") ref = fmt.Sprintf("%s/testrepo/%s:%s", suite.DockerRegistryHost, meta.Name, meta.Version) // Load prov file provData, err := os.ReadFile("../downloader/testdata/signtest-0.1.0.tgz.prov") - suite.Nil(err, "no error loading test prov") + suite.Require().NoError(err, "no error loading test prov") // no chart and no prov causes error _, err = suite.RegistryClient.Pull(ref, PullOptWithChart(false), PullOptWithProv(false)) - suite.NotNil(err, "error on both no chart and no prov") + suite.Require().Error(err, "error on both no chart and no prov") // full pull with chart and prov result, err := suite.RegistryClient.Pull(ref, PullOptWithProv(true)) - suite.Require().Nil(err, "no error pulling a chart with prov") + suite.Require().NoError(err, "no error pulling a chart with prov") // Validate the output // Note: these digests/sizes etc may change if the test chart/prov files are modified, @@ -548,13 +548,13 @@ func testPull(suite *TestRegistry) { func testTags(suite *TestRegistry) { // Load test chart (to build ref pushed in previous test) chartData, err := os.ReadFile("../downloader/testdata/local-subchart-0.1.0.tgz") - suite.Nil(err, "no error loading test chart") + suite.Require().NoError(err, "no error loading test chart") meta, err := extractChartMeta(chartData) - suite.Nil(err, "no error extracting chart meta") + suite.Require().NoError(err, "no error extracting chart meta") ref := fmt.Sprintf("%s/testrepo/%s", suite.DockerRegistryHost, meta.Name) // Query for tags and validate length tags, err := suite.RegistryClient.Tags(ref) - suite.Nil(err, "no error retrieving tags") + suite.Require().NoError(err, "no error retrieving tags") suite.Equal(1, len(tags)) } diff --git a/pkg/repo/v1/repotest/tlsconfig.go b/pkg/repo/v1/repotest/tlsconfig.go index 3ea7338ff..d579f8054 100644 --- a/pkg/repo/v1/repotest/tlsconfig.go +++ b/pkg/repo/v1/repotest/tlsconfig.go @@ -35,8 +35,7 @@ func MakeTestTLSConfig(t *testing.T, path string) *tls.Config { tlsutil.WithCertKeyPairFiles(pub, priv), tlsutil.WithCAFile(ca), ) - //require.Nil(t, err, err.Error()) - require.Nil(t, err) + require.NoError(t, err) tlsConf.ServerName = "helm.sh" From 73f71bceae2674d41fb2f082ee4fa5a842b613cc Mon Sep 17 00:00:00 2001 From: Ogulcan Aydogan Date: Thu, 30 Apr 2026 14:35:16 +0100 Subject: [PATCH 06/30] fix(registry): remove pre-Go-1.20 transport cloner fallback Helm now requires Go 1.26 (#32078); the cloner[T] type-assertion fallback in transport.go was a defensive shim for Go versions before http.Transport.Clone() existed. The fallback path is unreachable on supported Go versions. Refs: #31386 Signed-off-by: Ogulcan Aydogan --- pkg/registry/transport.go | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/pkg/registry/transport.go b/pkg/registry/transport.go index f039a8159..e4177efb3 100644 --- a/pkg/registry/transport.go +++ b/pkg/registry/transport.go @@ -52,22 +52,10 @@ type LoggingTransport struct { // NewTransport creates and returns a new instance of LoggingTransport func NewTransport(debug bool) *retry.Transport { - type cloner[T any] interface { - Clone() T - } - - // try to copy (clone) the http.DefaultTransport so any mutations we - // perform on it (e.g. TLS config) are not reflected globally - // follow https://github.com/golang/go/issues/39299 for a more elegant - // solution in the future + // clone http.DefaultTransport so mutations (e.g. TLS config) are not + // reflected globally transport := http.DefaultTransport - if t, ok := transport.(cloner[*http.Transport]); ok { - transport = t.Clone() - } else if t, ok := transport.(cloner[http.RoundTripper]); ok { - // this branch will not be used with go 1.20, it was added - // optimistically to try to clone if the http.DefaultTransport - // implementation changes, still the Clone method in that case - // might not return http.RoundTripper... + if t, ok := transport.(*http.Transport); ok { transport = t.Clone() } if debug { From 854f7f6b7217dcfe135df9e4652517d3ec9c3913 Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Mon, 4 May 2026 13:57:52 -0700 Subject: [PATCH 07/30] fix: fetch logs from all containers in test pods When a test pod contains multiple containers (e.g. Istio/Consul/Vault sidecars), 'helm test --logs' failed with 'a container name must be specified'. This happened because GetPodLogs called the Kubernetes log API without specifying a container name. The fix fetches the pod spec first, then iterates over all containers (init containers + regular containers) and requests logs for each one explicitly. Errors from individual containers are collected and returned together via errors.Join rather than aborting on the first failure. Also fixes a typo: hooksByWight -> hooksByWeight. Closes #6902 Signed-off-by: Sebastien Tardif --- pkg/action/release_testing.go | 53 +++++++++++---- pkg/action/release_testing_test.go | 103 ++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 15 deletions(-) diff --git a/pkg/action/release_testing.go b/pkg/action/release_testing.go index 043a41236..9de4e58f2 100644 --- a/pkg/action/release_testing.go +++ b/pkg/action/release_testing.go @@ -18,6 +18,7 @@ package action import ( "context" + "errors" "fmt" "io" "slices" @@ -25,6 +26,8 @@ import ( "time" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" chartutil "helm.sh/helm/v4/pkg/chart/v2/util" "helm.sh/helm/v4/pkg/kube" @@ -124,9 +127,9 @@ func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error { return fmt.Errorf("unable to get kubernetes client to fetch pod logs: %w", err) } - hooksByWight := append([]*release.Hook{}, rel.Hooks...) - sort.Stable(hookByWeight(hooksByWight)) - for _, h := range hooksByWight { + hooksByWeight := append([]*release.Hook{}, rel.Hooks...) + sort.Stable(hookByWeight(hooksByWeight)) + for _, h := range hooksByWeight { for _, e := range h.Events { if e == release.HookTest { if slices.Contains(r.Filters[ExcludeNameFilter], h.Name) { @@ -135,20 +138,42 @@ func (r *ReleaseTesting) GetPodLogs(out io.Writer, rel *release.Release) error { if len(r.Filters[IncludeNameFilter]) > 0 && !slices.Contains(r.Filters[IncludeNameFilter], h.Name) { continue } - req := client.CoreV1().Pods(r.Namespace).GetLogs(h.Name, &v1.PodLogOptions{}) - logReader, err := req.Stream(context.Background()) - if err != nil { - return fmt.Errorf("unable to get pod logs for %s: %w", h.Name, err) - } - - fmt.Fprintf(out, "POD LOGS: %s\n", h.Name) - _, err = io.Copy(out, logReader) - fmt.Fprintln(out) - if err != nil { - return fmt.Errorf("unable to write pod logs for %s: %w", h.Name, err) + if err := r.getContainerLogs(out, client, h.Name); err != nil { + return err } } } } return nil } + +// getContainerLogs fetches logs from all containers (init and regular) in the +// named pod and writes them to out. It continues on per-container errors and +// returns all of them joined at the end. +func (r *ReleaseTesting) getContainerLogs(out io.Writer, client kubernetes.Interface, podName string) error { + pod, err := client.CoreV1().Pods(r.Namespace).Get(context.Background(), podName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("unable to get pod %s: %w", podName, err) + } + + allContainers := append(pod.Spec.InitContainers, pod.Spec.Containers...) + + var errs []error + for _, c := range allContainers { + opts := &v1.PodLogOptions{Container: c.Name} + req := client.CoreV1().Pods(r.Namespace).GetLogs(podName, opts) + logReader, err := req.Stream(context.Background()) + if err != nil { + errs = append(errs, fmt.Errorf("unable to get logs for pod %s, container %s: %w", podName, c.Name, err)) + continue + } + + fmt.Fprintf(out, "POD LOGS: %s (%s)\n", podName, c.Name) + _, err = io.Copy(out, logReader) + fmt.Fprintln(out) + if err != nil { + errs = append(errs, fmt.Errorf("unable to write logs for pod %s, container %s: %w", podName, c.Name, err)) + } + } + return errors.Join(errs...) +} diff --git a/pkg/action/release_testing_test.go b/pkg/action/release_testing_test.go index ab35e104a..ea647af80 100644 --- a/pkg/action/release_testing_test.go +++ b/pkg/action/release_testing_test.go @@ -22,10 +22,14 @@ import ( "errors" "io" "os" + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + fakeclientset "k8s.io/client-go/kubernetes/fake" "helm.sh/helm/v4/pkg/cli" "helm.sh/helm/v4/pkg/kube" @@ -89,7 +93,7 @@ func TestReleaseTestingGetPodLogs_PodRetrievalError(t *testing.T) { }, } - require.ErrorContains(t, client.GetPodLogs(&bytes.Buffer{}, &release.Release{Hooks: hooks}), "unable to get pod logs") + require.ErrorContains(t, client.GetPodLogs(&bytes.Buffer{}, &release.Release{Hooks: hooks}), "unable to get pod") } func TestReleaseTesting_WaitOptionsPassedDownstream(t *testing.T) { @@ -117,3 +121,100 @@ func TestReleaseTesting_WaitOptionsPassedDownstream(t *testing.T) { // Verify that WaitOptions were passed to GetWaiter is.NotEmpty(failer.RecordedWaitOptions, "WaitOptions should be passed to GetWaiter") } + +func TestGetContainerLogs_MultipleContainers(t *testing.T) { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + {Name: "main"}, + {Name: "sidecar"}, + }, + }, + } + + client := fakeclientset.NewClientset(pod) + rt := &ReleaseTesting{Namespace: "default"} + + var buf bytes.Buffer + err := rt.getContainerLogs(&buf, client, "test-pod") + // The fake client doesn't serve real log streams, so we expect + // per-container errors rather than success, but critically it should + // NOT fail with "a container name must be specified". + if err != nil { + assert.NotContains(t, err.Error(), "a container name must be specified") + assert.Contains(t, err.Error(), "container main") + assert.Contains(t, err.Error(), "container sidecar") + } +} + +func TestGetContainerLogs_WithInitContainers(t *testing.T) { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + }, + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ + {Name: "init-setup"}, + }, + Containers: []v1.Container{ + {Name: "main"}, + }, + }, + } + + client := fakeclientset.NewClientset(pod) + rt := &ReleaseTesting{Namespace: "default"} + + var buf bytes.Buffer + err := rt.getContainerLogs(&buf, client, "test-pod") + if err != nil { + // Both init and regular containers should be attempted + assert.Contains(t, err.Error(), "container init-setup") + assert.Contains(t, err.Error(), "container main") + } +} + +func TestGetContainerLogs_PodNotFound(t *testing.T) { + client := fakeclientset.NewClientset() + rt := &ReleaseTesting{Namespace: "default"} + + var buf bytes.Buffer + err := rt.getContainerLogs(&buf, client, "nonexistent-pod") + require.Error(t, err) + assert.Contains(t, err.Error(), "unable to get pod nonexistent-pod") +} + +func TestGetPodLogs_MultiContainerOutput(t *testing.T) { + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "multi-test", + Namespace: "default", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + {Name: "container-a"}, + {Name: "container-b"}, + }, + }, + } + + client := fakeclientset.NewClientset(pod) + rt := &ReleaseTesting{ + Namespace: "default", + Filters: map[string][]string{}, + } + + // Call getContainerLogs directly to test output formatting + var buf bytes.Buffer + _ = rt.getContainerLogs(&buf, client, "multi-test") + output := buf.String() + // Even if logs fail, check that header formatting uses container names + if len(output) > 0 { + assert.True(t, strings.Contains(output, "(container-a)") || strings.Contains(output, "(container-b)")) + } +} From 922558fc1a3b3f2c2b7e8ad0f32bd5bcd46ca70e Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Mon, 4 May 2026 14:04:25 -0700 Subject: [PATCH 08/30] fix: address review feedback - Close log stream after reading (prevents connection/fd leak) - Strengthen tests to assert on output headers rather than error paths - Remove unused import Signed-off-by: Sebastien Tardif --- pkg/action/release_testing.go | 1 + pkg/action/release_testing_test.go | 40 +++++++++++------------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/pkg/action/release_testing.go b/pkg/action/release_testing.go index 9de4e58f2..8cb6ce664 100644 --- a/pkg/action/release_testing.go +++ b/pkg/action/release_testing.go @@ -170,6 +170,7 @@ func (r *ReleaseTesting) getContainerLogs(out io.Writer, client kubernetes.Inter fmt.Fprintf(out, "POD LOGS: %s (%s)\n", podName, c.Name) _, err = io.Copy(out, logReader) + logReader.Close() fmt.Fprintln(out) if err != nil { errs = append(errs, fmt.Errorf("unable to write logs for pod %s, container %s: %w", podName, c.Name, err)) diff --git a/pkg/action/release_testing_test.go b/pkg/action/release_testing_test.go index ea647af80..dcc708548 100644 --- a/pkg/action/release_testing_test.go +++ b/pkg/action/release_testing_test.go @@ -22,7 +22,6 @@ import ( "errors" "io" "os" - "strings" "testing" "github.com/stretchr/testify/assert" @@ -141,14 +140,10 @@ func TestGetContainerLogs_MultipleContainers(t *testing.T) { var buf bytes.Buffer err := rt.getContainerLogs(&buf, client, "test-pod") - // The fake client doesn't serve real log streams, so we expect - // per-container errors rather than success, but critically it should - // NOT fail with "a container name must be specified". - if err != nil { - assert.NotContains(t, err.Error(), "a container name must be specified") - assert.Contains(t, err.Error(), "container main") - assert.Contains(t, err.Error(), "container sidecar") - } + require.NoError(t, err) + output := buf.String() + assert.Contains(t, output, "POD LOGS: test-pod (main)") + assert.Contains(t, output, "POD LOGS: test-pod (sidecar)") } func TestGetContainerLogs_WithInitContainers(t *testing.T) { @@ -172,11 +167,11 @@ func TestGetContainerLogs_WithInitContainers(t *testing.T) { var buf bytes.Buffer err := rt.getContainerLogs(&buf, client, "test-pod") - if err != nil { - // Both init and regular containers should be attempted - assert.Contains(t, err.Error(), "container init-setup") - assert.Contains(t, err.Error(), "container main") - } + require.NoError(t, err) + output := buf.String() + // Init containers should appear before regular containers + assert.Contains(t, output, "POD LOGS: test-pod (init-setup)") + assert.Contains(t, output, "POD LOGS: test-pod (main)") } func TestGetContainerLogs_PodNotFound(t *testing.T) { @@ -189,7 +184,7 @@ func TestGetContainerLogs_PodNotFound(t *testing.T) { assert.Contains(t, err.Error(), "unable to get pod nonexistent-pod") } -func TestGetPodLogs_MultiContainerOutput(t *testing.T) { +func TestGetContainerLogs_OutputHeaderFormat(t *testing.T) { pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "multi-test", @@ -204,17 +199,12 @@ func TestGetPodLogs_MultiContainerOutput(t *testing.T) { } client := fakeclientset.NewClientset(pod) - rt := &ReleaseTesting{ - Namespace: "default", - Filters: map[string][]string{}, - } + rt := &ReleaseTesting{Namespace: "default"} - // Call getContainerLogs directly to test output formatting var buf bytes.Buffer - _ = rt.getContainerLogs(&buf, client, "multi-test") + err := rt.getContainerLogs(&buf, client, "multi-test") + require.NoError(t, err) output := buf.String() - // Even if logs fail, check that header formatting uses container names - if len(output) > 0 { - assert.True(t, strings.Contains(output, "(container-a)") || strings.Contains(output, "(container-b)")) - } + assert.Contains(t, output, "POD LOGS: multi-test (container-a)") + assert.Contains(t, output, "POD LOGS: multi-test (container-b)") } From 19b3656306829cae166f484feb4a1319f47844c0 Mon Sep 17 00:00:00 2001 From: George Jenkins Date: Wed, 6 May 2026 10:35:57 -0700 Subject: [PATCH 09/30] Bump to version v4.2 (#32102) Signed-off-by: George Jenkins --- internal/version/version.go | 2 +- pkg/chart/common/capabilities_test.go | 4 ++-- pkg/cmd/testdata/output/version-short.txt | 2 +- pkg/cmd/testdata/output/version-template.txt | 2 +- pkg/cmd/testdata/output/version.txt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/version/version.go b/internal/version/version.go index 3daf80893..007f79f16 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -34,7 +34,7 @@ var ( // // Increment major number for new feature additions and behavioral changes. // Increment minor number for bug fixes and performance enhancements. - version = "v4.1" + version = "v4.2" // metadata is extra build time data metadata = "" diff --git a/pkg/chart/common/capabilities_test.go b/pkg/chart/common/capabilities_test.go index c9f026cbb..c8d47581c 100644 --- a/pkg/chart/common/capabilities_test.go +++ b/pkg/chart/common/capabilities_test.go @@ -60,8 +60,8 @@ func TestDefaultCapabilities(t *testing.T) { } hv := caps.HelmVersion - if hv.Version != "v4.1" { - t.Errorf("Expected default HelmVersion to be v4.1, got %q", hv.Version) + if hv.Version != "v4.2" { + t.Errorf("Expected default HelmVersion to be v4.2, got %q", hv.Version) } } diff --git a/pkg/cmd/testdata/output/version-short.txt b/pkg/cmd/testdata/output/version-short.txt index 8cf4318fb..2fa2c5705 100644 --- a/pkg/cmd/testdata/output/version-short.txt +++ b/pkg/cmd/testdata/output/version-short.txt @@ -1 +1 @@ -v4.1 +v4.2 diff --git a/pkg/cmd/testdata/output/version-template.txt b/pkg/cmd/testdata/output/version-template.txt index 8fd8b4962..8f2491e54 100644 --- a/pkg/cmd/testdata/output/version-template.txt +++ b/pkg/cmd/testdata/output/version-template.txt @@ -1 +1 @@ -Version: v4.1 \ No newline at end of file +Version: v4.2 \ No newline at end of file diff --git a/pkg/cmd/testdata/output/version.txt b/pkg/cmd/testdata/output/version.txt index 1f4cf4d4a..331c6d5e9 100644 --- a/pkg/cmd/testdata/output/version.txt +++ b/pkg/cmd/testdata/output/version.txt @@ -1 +1 @@ -version.BuildInfo{Version:"v4.1", GitCommit:"", GitTreeState:"", GoVersion:"", KubeClientVersion:"v1.20"} +version.BuildInfo{Version:"v4.2", GitCommit:"", GitTreeState:"", GoVersion:"", KubeClientVersion:"v1.20"} From d9b2716be5fbb3309c3176b0c887d91ffb16c048 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 21:33:30 +0000 Subject: [PATCH 10/30] chore(deps): bump github/codeql-action from 4.35.3 to 4.35.4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e46ed2cbd01164d986452f91f178727624ae40d7...68bde559dea0fdcac2102bfdf6230c5f70eb485e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6714fc8de..256d26cc3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # pinv4.35.3 + uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e46ed2cbd01164d986452f91f178727624ae40d7 # pinv4.35.3 + uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # pinv4.35.3 + uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 5d78ddd61..16a9a8c13 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: results.sarif From 2cc69251d81ad94e9e0edbea6c31dedf4e2c25d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 21:34:37 +0000 Subject: [PATCH 11/30] chore(deps): bump golang.org/x/crypto from 0.50.0 to 0.51.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.50.0 to 0.51.0. - [Commits](https://github.com/golang/crypto/compare/v0.50.0...v0.51.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.51.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 40c02c7e1..4fd2ecde8 100644 --- a/go.mod +++ b/go.mod @@ -35,9 +35,9 @@ require ( github.com/stretchr/testify v1.11.1 github.com/tetratelabs/wazero v1.11.0 go.yaml.in/yaml/v3 v3.0.4 - golang.org/x/crypto v0.50.0 - golang.org/x/term v0.42.0 - golang.org/x/text v0.36.0 + golang.org/x/crypto v0.51.0 + golang.org/x/term v0.43.0 + golang.org/x/text v0.37.0 gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.36.0 k8s.io/apiextensions-apiserver v0.36.0 @@ -157,13 +157,13 @@ require ( go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect + golang.org/x/sys v0.44.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.43.0 // indirect + golang.org/x/tools v0.44.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect google.golang.org/grpc v1.80.0 // indirect diff --git a/go.sum b/go.sum index f1a2ca9f8..50373d1f4 100644 --- a/go.sum +++ b/go.sum @@ -382,14 +382,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -400,8 +400,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -430,8 +430,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -439,8 +439,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -448,8 +448,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -458,8 +458,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= From 6620fec5d19f6c86425501ee64f8cb8a8fb3fa3e Mon Sep 17 00:00:00 2001 From: Sumit Solanki Date: Sat, 9 May 2026 12:17:40 +0530 Subject: [PATCH 12/30] fix(downloader): order DiskCache.Get checks for overlayfs empty dirs Signed-off-by: Sumit Solanki --- pkg/downloader/cache.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/downloader/cache.go b/pkg/downloader/cache.go index 1e23fbfcd..c628ba95d 100644 --- a/pkg/downloader/cache.go +++ b/pkg/downloader/cache.go @@ -59,15 +59,17 @@ func (c *DiskCache) Get(key [sha256.Size]byte, cacheType string) (string, error) if err != nil { return "", err } - // Empty files treated as not exist because there is no content. - if fi.Size() == 0 { - return p, os.ErrNotExist - } // directories should never happen unless something outside helm is operating // on this content. if fi.IsDir() { return p, errors.New("is a directory") } + // Empty files treated as not exist because there is no content. + // IsDir must be checked first: some filesystems (e.g. overlay) report + // directory size as 0. + if fi.Size() == 0 { + return p, os.ErrNotExist + } return p, nil } From 53d5f13f46f7dd555be8bd90616abdc77d470000 Mon Sep 17 00:00:00 2001 From: Sumit Solanki Date: Sat, 9 May 2026 12:28:41 +0530 Subject: [PATCH 13/30] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Sumit Solanki --- pkg/downloader/cache.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/downloader/cache.go b/pkg/downloader/cache.go index c628ba95d..92d477e49 100644 --- a/pkg/downloader/cache.go +++ b/pkg/downloader/cache.go @@ -64,8 +64,8 @@ func (c *DiskCache) Get(key [sha256.Size]byte, cacheType string) (string, error) if fi.IsDir() { return p, errors.New("is a directory") } - // Empty files treated as not exist because there is no content. - // IsDir must be checked first: some filesystems (e.g. overlay) report + // Empty files are treated as non-existent because there is no content. + // IsDir must be checked first: some filesystems (e.g. overlayfs) report // directory size as 0. if fi.Size() == 0 { return p, os.ErrNotExist From 432fc8a21724cc75e0cd8ec8fd754d2bde42c15f Mon Sep 17 00:00:00 2001 From: box4wangjing Date: Tue, 12 May 2026 01:22:24 +0800 Subject: [PATCH 14/30] refactor: use slices.Backward to simplify the code Signed-off-by: box4wangjing --- internal/chart/v3/util/dependencies.go | 5 +++-- pkg/action/hooks.go | 4 ++-- pkg/chart/v2/util/dependencies.go | 5 +++-- pkg/cmd/history.go | 5 +++-- pkg/repo/v1/index.go | 17 +++++++++-------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/internal/chart/v3/util/dependencies.go b/internal/chart/v3/util/dependencies.go index 9c4d8e80f..b31f7eb96 100644 --- a/internal/chart/v3/util/dependencies.go +++ b/internal/chart/v3/util/dependencies.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "log/slog" + "slices" "strings" chart "helm.sh/helm/v4/internal/chart/v3" @@ -242,8 +243,8 @@ func set(path []string, data map[string]any) map[string]any { return nil } cur := data - for i := len(path) - 1; i >= 0; i-- { - cur = map[string]any{path[i]: cur} + for _, v := range slices.Backward(path) { + cur = map[string]any{v: cur} } return cur } diff --git a/pkg/action/hooks.go b/pkg/action/hooks.go index a4a8da7a6..e7be37bd8 100644 --- a/pkg/action/hooks.go +++ b/pkg/action/hooks.go @@ -150,8 +150,8 @@ func (cfg *Configuration) execHookWithDelayedShutdown(rl *release.Release, hook return func() error { // If all hooks are successful, check the annotation of each hook to determine whether the hook should be deleted // or output should be logged under succeeded condition. If so, then clear the corresponding resource object in each hook - for i := len(executingHooks) - 1; i >= 0; i-- { - h := executingHooks[i] + for _, v := range slices.Backward(executingHooks) { + h := v if err := cfg.outputLogsByPolicy(h, rl.Namespace, release.HookOutputOnSucceeded); err != nil { // We log here as we still want to attempt hook resource deletion even if output logging fails. log.Printf("error outputting logs for hook failure: %v", err) diff --git a/pkg/chart/v2/util/dependencies.go b/pkg/chart/v2/util/dependencies.go index abd673f9d..f28a4f4b1 100644 --- a/pkg/chart/v2/util/dependencies.go +++ b/pkg/chart/v2/util/dependencies.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "log/slog" + "slices" "strings" "helm.sh/helm/v4/internal/copystructure" @@ -242,8 +243,8 @@ func set(path []string, data map[string]any) map[string]any { return nil } cur := data - for i := len(path) - 1; i >= 0; i-- { - cur = map[string]any{path[i]: cur} + for _, v := range slices.Backward(path) { + cur = map[string]any{v: cur} } return cur } diff --git a/pkg/cmd/history.go b/pkg/cmd/history.go index 3349b7bc1..7c0f3ecde 100644 --- a/pkg/cmd/history.go +++ b/pkg/cmd/history.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "io" + "slices" "strconv" "time" @@ -207,8 +208,8 @@ func getHistory(client *action.History, name string) (releaseHistory, error) { } func getReleaseHistory(rls []*release.Release) (history releaseHistory) { - for i := len(rls) - 1; i >= 0; i-- { - r := rls[i] + for _, v := range slices.Backward(rls) { + r := v c := formatChartName(r.Chart) s := r.Info.Status.String() v := r.Version diff --git a/pkg/repo/v1/index.go b/pkg/repo/v1/index.go index 3dbdf7dfc..825dc2753 100644 --- a/pkg/repo/v1/index.go +++ b/pkg/repo/v1/index.go @@ -25,6 +25,7 @@ import ( "os" "path" "path/filepath" + "slices" "sort" "strings" "time" @@ -356,21 +357,21 @@ func loadIndex(data []byte, source string) (*IndexFile, error) { } for name, cvs := range i.Entries { - for idx := len(cvs) - 1; idx >= 0; idx-- { - if cvs[idx] == nil { + for idx, v := range slices.Backward(cvs) { + if v == nil { slog.Warn(fmt.Sprintf("skipping loading invalid entry for chart %q from %s: empty entry", name, source)) cvs = append(cvs[:idx], cvs[idx+1:]...) continue } // When metadata section missing, initialize with no data - if cvs[idx].Metadata == nil { - cvs[idx].Metadata = &chart.Metadata{} + if v.Metadata == nil { + v.Metadata = &chart.Metadata{} } - if cvs[idx].APIVersion == "" { - cvs[idx].APIVersion = chart.APIVersionV1 + if v.APIVersion == "" { + v.APIVersion = chart.APIVersionV1 } - if err := cvs[idx].Validate(); ignoreSkippableChartValidationError(err) != nil { - slog.Warn(fmt.Sprintf("skipping loading invalid entry for chart %q %q from %s: %s", name, cvs[idx].Version, source, err)) + if err := v.Validate(); ignoreSkippableChartValidationError(err) != nil { + slog.Warn(fmt.Sprintf("skipping loading invalid entry for chart %q %q from %s: %s", name, v.Version, source, err)) cvs = append(cvs[:idx], cvs[idx+1:]...) } } From 2032ec5cbaf168de0fadc59959319e4b580ff72e Mon Sep 17 00:00:00 2001 From: Kai Tanaka <275430420+quyentonndbs@users.noreply.github.com> Date: Tue, 12 May 2026 14:12:03 +0000 Subject: [PATCH 15/30] docs: fix 'than'->'that' typo in deprecatedAPIError godoc Signed-off-by: Kai Tanaka <275430420+quyentonndbs@users.noreply.github.com> --- internal/chart/v3/lint/rules/deprecations.go | 2 +- pkg/chart/v2/lint/rules/deprecations.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/chart/v3/lint/rules/deprecations.go b/internal/chart/v3/lint/rules/deprecations.go index a607a5fb4..9c73268af 100644 --- a/internal/chart/v3/lint/rules/deprecations.go +++ b/internal/chart/v3/lint/rules/deprecations.go @@ -28,7 +28,7 @@ import ( kscheme "k8s.io/client-go/kubernetes/scheme" ) -// deprecatedAPIError indicates than an API is deprecated in Kubernetes +// deprecatedAPIError indicates that an API is deprecated in Kubernetes type deprecatedAPIError struct { Deprecated string Message string diff --git a/pkg/chart/v2/lint/rules/deprecations.go b/pkg/chart/v2/lint/rules/deprecations.go index 7d5245869..76626659b 100644 --- a/pkg/chart/v2/lint/rules/deprecations.go +++ b/pkg/chart/v2/lint/rules/deprecations.go @@ -28,7 +28,7 @@ import ( kscheme "k8s.io/client-go/kubernetes/scheme" ) -// deprecatedAPIError indicates than an API is deprecated in Kubernetes +// deprecatedAPIError indicates that an API is deprecated in Kubernetes type deprecatedAPIError struct { Deprecated string Message string From ea2343ebeaf7b4b6b115fd1c7b34a159d6a573ff Mon Sep 17 00:00:00 2001 From: Sebastien Tardif Date: Fri, 15 May 2026 07:16:39 -0700 Subject: [PATCH 16/30] fix(repo): use structured slog args in index.go slog.Error on line 157 passes printf-style positional args (%q, %s) instead of key-value pairs. The slog API treats these as unkeyed attributes, producing garbled log output. Two nearby slog.Warn calls wrap fmt.Sprintf unnecessarily. Convert all three calls to use proper structured key-value arguments. Signed-off-by: Sebastien Tardif Assisted-by: Grok/grok-4 --- pkg/repo/v1/index.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/repo/v1/index.go b/pkg/repo/v1/index.go index 825dc2753..ba747d702 100644 --- a/pkg/repo/v1/index.go +++ b/pkg/repo/v1/index.go @@ -154,7 +154,7 @@ func (i IndexFile) MustAdd(md *chart.Metadata, filename, baseURL, digest string) // Deprecated: Use index.MustAdd instead. func (i IndexFile) Add(md *chart.Metadata, filename, baseURL, digest string) { if err := i.MustAdd(md, filename, baseURL, digest); err != nil { - slog.Error("skipping loading invalid entry for chart %q %q from %s: %s", md.Name, md.Version, filename, err) + slog.Error("skipping loading invalid entry for chart", "name", md.Name, "version", md.Version, "file", filename, "error", err) } } @@ -359,7 +359,7 @@ func loadIndex(data []byte, source string) (*IndexFile, error) { for name, cvs := range i.Entries { for idx, v := range slices.Backward(cvs) { if v == nil { - slog.Warn(fmt.Sprintf("skipping loading invalid entry for chart %q from %s: empty entry", name, source)) + slog.Warn("skipping loading invalid entry for chart: empty entry", "name", name, "source", source) cvs = append(cvs[:idx], cvs[idx+1:]...) continue } @@ -371,7 +371,7 @@ func loadIndex(data []byte, source string) (*IndexFile, error) { v.APIVersion = chart.APIVersionV1 } if err := v.Validate(); ignoreSkippableChartValidationError(err) != nil { - slog.Warn(fmt.Sprintf("skipping loading invalid entry for chart %q %q from %s: %s", name, v.Version, source, err)) + slog.Warn("skipping loading invalid entry for chart", "name", name, "version", v.Version, "source", source, "error", err) cvs = append(cvs[:idx], cvs[idx+1:]...) } } From f772ffedc6154f82bc0ac680f9ffa46054112ac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 21:33:32 +0000 Subject: [PATCH 17/30] chore(deps): bump github/codeql-action from 4.35.4 to 4.35.5 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...9e0d7b8d25671d64c341c19c0152d693099fb5ba) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 256d26cc3..2af5c67cc 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 + uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 + uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # pinv4.35.4 + uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 16a9a8c13..77f220426 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: sarif_file: results.sarif From b5a9299eecefe45da13a01188cabac6af4c336d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 21:34:27 +0000 Subject: [PATCH 18/30] chore(deps): bump github.com/fluxcd/cli-utils from 1.2.0 to 1.2.1 Bumps [github.com/fluxcd/cli-utils](https://github.com/fluxcd/cli-utils) from 1.2.0 to 1.2.1. - [Release notes](https://github.com/fluxcd/cli-utils/releases) - [Commits](https://github.com/fluxcd/cli-utils/compare/v1.2.0...v1.2.1) --- updated-dependencies: - dependency-name: github.com/fluxcd/cli-utils dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 4fd2ecde8..0ae34e4f6 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/evanphx/json-patch/v5 v5.9.11 github.com/extism/go-sdk v1.7.1 github.com/fatih/color v1.19.0 - github.com/fluxcd/cli-utils v1.2.0 + github.com/fluxcd/cli-utils v1.2.1 github.com/foxcpp/go-mockdns v1.2.0 github.com/gobwas/glob v0.2.3 github.com/gofrs/flock v0.13.0 @@ -48,7 +48,7 @@ require ( k8s.io/klog/v2 v2.140.0 k8s.io/kubectl v0.36.0 oras.land/oras-go/v2 v2.6.0 - sigs.k8s.io/controller-runtime v0.24.0 + sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/kustomize/kyaml v0.21.1 sigs.k8s.io/yaml v1.6.0 ) diff --git a/go.sum b/go.sum index 50373d1f4..dc6c788e1 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/cli-utils v1.2.0 h1:1o07pXTMxJ/XJ1GpAbLtjdXwfCUMq4Ku1OcnvJHLohI= -github.com/fluxcd/cli-utils v1.2.0/go.mod h1:d5HdTDdR5sCbsIbgtOQ7x7srKYwYeZORU6CD2yn4j/M= +github.com/fluxcd/cli-utils v1.2.1 h1:ug9CicKW7H9QXnvNDapTSKuryZvWcu4Nw7pRvQa6jDY= +github.com/fluxcd/cli-utils v1.2.1/go.mod h1:cky6M6eHvTQkoPtsuFYLIgAMYdpTCSLoor4IA6vueSw= github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0= github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -509,8 +509,8 @@ k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0x k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= -sigs.k8s.io/controller-runtime v0.24.0 h1:Ck6N2LdS8Lovy1o25BB4r1xjvLEKUl1s2o9kU+KWDE4= -sigs.k8s.io/controller-runtime v0.24.0/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs= From 378ceacd9ce239e5b3de1e7ce7c55cf18e16f69b Mon Sep 17 00:00:00 2001 From: Matheus Pimenta Date: Sat, 16 May 2026 15:28:16 +0100 Subject: [PATCH 19/30] fix(upstream): upgrade to cli-utils 1.2.1, controller-runtime 0.24.1 and k8s 1.36.1 Signed-off-by: Matheus Pimenta --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 4fd2ecde8..8220a5f1c 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/evanphx/json-patch/v5 v5.9.11 github.com/extism/go-sdk v1.7.1 github.com/fatih/color v1.19.0 - github.com/fluxcd/cli-utils v1.2.0 + github.com/fluxcd/cli-utils v1.2.1 github.com/foxcpp/go-mockdns v1.2.0 github.com/gobwas/glob v0.2.3 github.com/gofrs/flock v0.13.0 @@ -39,16 +39,16 @@ require ( golang.org/x/term v0.43.0 golang.org/x/text v0.37.0 gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.36.0 - k8s.io/apiextensions-apiserver v0.36.0 - k8s.io/apimachinery v0.36.0 - k8s.io/apiserver v0.36.0 - k8s.io/cli-runtime v0.36.0 - k8s.io/client-go v0.36.0 + k8s.io/api v0.36.1 + k8s.io/apiextensions-apiserver v0.36.1 + k8s.io/apimachinery v0.36.1 + k8s.io/apiserver v0.36.1 + k8s.io/cli-runtime v0.36.1 + k8s.io/client-go v0.36.1 k8s.io/klog/v2 v2.140.0 - k8s.io/kubectl v0.36.0 + k8s.io/kubectl v0.36.1 oras.land/oras-go/v2 v2.6.0 - sigs.k8s.io/controller-runtime v0.24.0 + sigs.k8s.io/controller-runtime v0.24.1 sigs.k8s.io/kustomize/kyaml v0.21.1 sigs.k8s.io/yaml v1.6.0 ) @@ -171,7 +171,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/component-base v0.36.0 // indirect + k8s.io/component-base v0.36.1 // indirect k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect diff --git a/go.sum b/go.sum index 50373d1f4..544e4205e 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/cli-utils v1.2.0 h1:1o07pXTMxJ/XJ1GpAbLtjdXwfCUMq4Ku1OcnvJHLohI= -github.com/fluxcd/cli-utils v1.2.0/go.mod h1:d5HdTDdR5sCbsIbgtOQ7x7srKYwYeZORU6CD2yn4j/M= +github.com/fluxcd/cli-utils v1.2.1 h1:ug9CicKW7H9QXnvNDapTSKuryZvWcu4Nw7pRvQa6jDY= +github.com/fluxcd/cli-utils v1.2.1/go.mod h1:cky6M6eHvTQkoPtsuFYLIgAMYdpTCSLoor4IA6vueSw= github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0= github.com/foxcpp/go-mockdns v1.2.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -485,32 +485,32 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.36.0 h1:SgqDhZzHdOtMk40xVSvCXkP9ME0H05hPM3p9AB1kL80= -k8s.io/api v0.36.0/go.mod h1:m1LVrGPNYax5NBHdO+QuAedXyuzTt4RryI/qnmNvs34= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= -k8s.io/apimachinery v0.36.0 h1:jZyPzhd5Z+3h9vJLt0z9XdzW9VzNzWAUw+P1xZ9PXtQ= -k8s.io/apimachinery v0.36.0/go.mod h1:FklypaRJt6n5wUIwWXIP6GJlIpUizTgfo1T/As+Tyxc= -k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE= -k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho= -k8s.io/cli-runtime v0.36.0 h1:HNxciQpQMMOKS0/GiUXcKDyA6J2FDILJj9NmP2BZrTg= -k8s.io/cli-runtime v0.36.0/go.mod h1:KObkknK9Ro5LYX+1RdiKc7C8CvGg4aX+V/Zv+E8WPHA= -k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c= -k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y= -k8s.io/component-base v0.36.0 h1:hFjEktssxiJhrK1zfybkH4kJOi8iZuF+mIDCqS5+jRo= -k8s.io/component-base v0.36.0/go.mod h1:JZvIfcNHk+uck+8LhJzhSBtydWXaZNQwX2OdL+Mnwsk= +k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= +k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= +k8s.io/apiextensions-apiserver v0.36.1 h1:6JfYmPUsuUIHuN+3QxutXYWj492RqF5fBSx67GYK5Ks= +k8s.io/apiextensions-apiserver v0.36.1/go.mod h1:pLzZin90riwisdzKwv/GoTwENooytoIx5zWJb4Hkby8= +k8s.io/apimachinery v0.36.1 h1:G63Gjx2W+q0YD+72Vo8oY0nDnePVwnuzTmmy5ENrVSA= +k8s.io/apimachinery v0.36.1/go.mod h1:ibYOR00vW/I1kzvi5SF0dRuJ52BvKtfvRdOn35GPQ+8= +k8s.io/apiserver v0.36.1 h1:iMS5V+rPUertv5P9RaqJgmHHTuh4quWpoxchvMUY+JY= +k8s.io/apiserver v0.36.1/go.mod h1:Cby1PbLWztu0GDOxoO6iFOyyqIsziHNEW+w9zVQ22Kw= +k8s.io/cli-runtime v0.36.1 h1:yuC/BGnnj1YYPh6D1P+pZnzinCs6DvMq86yAeNqoqzM= +k8s.io/cli-runtime v0.36.1/go.mod h1:ZQWHGt8xAF7KnviB79vX0lYNyUUqKIpU+LQg7exuFAw= +k8s.io/client-go v0.36.1 h1:FN/K8QIT2CEDt+2WB2HnWrUANZ50AP5GII43/SP2JR0= +k8s.io/client-go v0.36.1/go.mod h1:s6rAnCtTGYDQnpNjEhSaISV+2O8jwruZ6m3QOYBFbtU= +k8s.io/component-base v0.36.1 h1:iG6GsELftXqTNG9HG6kiVjatSgAw1sf5pJ6R5a6N0kA= +k8s.io/component-base v0.36.1/go.mod h1:nf9XPlntRdqO6WMeEWAA5F93Y4ICZQdeT9GeqLDB3JI= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/kubectl v0.36.0 h1:hEGr8NvIm2Wjqs2Xy48Uzmvo6lpHdGKlLyMvau2gTms= -k8s.io/kubectl v0.36.0/go.mod h1:iDe8aV5BEi45W8k+5n71I2pJ/nwE0PHDu+/2cejzYoo= +k8s.io/kubectl v0.36.1 h1:96HqS9twIdHM0MlJLTwbo14b9kUKPkOzZ4tlRDLv4qI= +k8s.io/kubectl v0.36.1/go.mod h1:/DGPAIewKsFWF9VFgGvkPhao2Ev4SNuE3BioZo8yPbk= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc= oras.land/oras-go/v2 v2.6.0/go.mod h1:magiQDfG6H1O9APp+rOsvCPcW1GD2MM7vgnKY0Y+u1o= -sigs.k8s.io/controller-runtime v0.24.0 h1:Ck6N2LdS8Lovy1o25BB4r1xjvLEKUl1s2o9kU+KWDE4= -sigs.k8s.io/controller-runtime v0.24.0/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs= From 979e68fbbd5a932c67b756884880d7641f268632 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Wed, 20 May 2026 13:24:39 +0300 Subject: [PATCH 20/30] internal/plugin: remove zero-width spaces from plugin name comment The comment describing allowed plugin name characters contained three U+200B (zero-width space) characters around the '_' and '-' literals. The rendered comment is identical without them; the ZWSP were likely copy-pasted from a rich-text source. Downstream impact: every project that vendors helm.sh/helm/v4 and runs Renovate gets a repo-wide warning on its Dependency Dashboard about hidden Unicode characters. Renovate scans the whole tree (including vendor/) for ZWSP/bidi-override codepoints and cannot be told to skip a path for this specific check. Removing the characters here clears the warning everywhere downstream. Signed-off-by: Aleksei Sviridkin --- internal/plugin/plugin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/plugin/plugin.go b/internal/plugin/plugin.go index 132b1739e..789e583ae 100644 --- a/internal/plugin/plugin.go +++ b/internal/plugin/plugin.go @@ -77,5 +77,5 @@ type Output struct { // validPluginName is a regular expression that validates plugin names. // -// Plugin names can only contain the ASCII characters a-z, A-Z, 0-9, ​_​ and ​-. +// Plugin names can only contain the ASCII characters a-z, A-Z, 0-9, _ and -. var validPluginName = regexp.MustCompile("^[A-Za-z0-9_-]+$") From ace245b8273e23c9f12993befa535a19ab1bc172 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 21:33:33 +0000 Subject: [PATCH 21/30] chore(deps): bump actions/stale from 10.2.0 to 10.3.0 Bumps [actions/stale](https://github.com/actions/stale) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/b5d41d4e1d5dceea10e7104786b73624c18a190f...eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 9b0c29952..bbe339e79 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -12,7 +12,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 + - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue has been marked as stale because it has been open for 90 days with no activity. This thread will be automatically closed in 30 days if no further activity occurs.' From 442e1460b9ec4450a7c12d6b6a59848e7b16d9d1 Mon Sep 17 00:00:00 2001 From: Benoit Tigeot Date: Fri, 22 May 2026 09:47:08 +0200 Subject: [PATCH 22/30] docs: update version status for v4 stable release Helm v4 shipped on 2025-11-17. Mark it as the current stable release and v3 as support-mode with its end-of-support dates. Signed-off-by: Benoit Tigeot --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 37bc8abaa..d581ceac3 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Think of it like apt/yum/homebrew for Kubernetes. ## Helm Development and Stable Versions -Helm v4 is currently under development on the `main` branch. This is unstable and the APIs within the Go SDK and at the command line are changing. -Helm v3 (current stable) is maintained on the `dev-v3` branch. APIs there follow semantic versioning. +Helm v4 is the current stable release, developed on the `main` branch. +Helm v3 is in support mode on the `dev-v3` branch: bug fixes until July 8th 2026, security fixes until November 11th 2026. ## Install @@ -64,7 +64,7 @@ Get started with the [Quick Start guide](https://helm.sh/docs/intro/quickstart/) The [Helm roadmap uses GitHub milestones](https://github.com/helm/helm/milestones) to track the progress of the project. -The development of Helm v4 is currently happening on the `main` branch while the development of Helm v3, the stable branch, is happening on the `dev-v3` branch. Changes should be made to the `main` branch prior to being added to the `dev-v3` branch so that all changes are carried along to Helm v4. +Helm v4 development happens on the `main` branch. Helm v3 is in support mode on the `dev-v3` branch and receives only bug and security fixes. ## Community, discussion, contribution, and support From 60665e9035ccab375780ef77934bde2ffa674448 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 21:33:30 +0000 Subject: [PATCH 23/30] chore(deps): bump github/codeql-action from 4.35.5 to 4.36.0 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/9e0d7b8d25671d64c341c19c0152d693099fb5ba...7211b7c8077ea37d8641b6271f6a365a22a5fbfa) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2af5c67cc..1c3ea0bf4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 + uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # pinv4.35.5 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 77f220426..c4a0cb196 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: sarif_file: results.sarif From dbb3e353372f6e4abca9155c44d8b9a5f1e97626 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 21:33:35 +0000 Subject: [PATCH 24/30] chore(deps): bump golangci/golangci-lint-action from 9.2.0 to 9.2.1 Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 9.2.0 to 9.2.1. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/1e7e51e771db61008b38414a730f564565cf7c20...82606bf257cbaff209d206a39f5134f0cfbfd2ee) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-version: 9.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 8b64a3be2..734bc682a 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -22,6 +22,6 @@ jobs: go-version: '${{ env.GOLANG_VERSION }}' check-latest: true - name: golangci-lint - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 #pin@9.2.0 + uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee #pin@9.2.1 with: version: ${{ env.GOLANGCI_LINT_VERSION }} From 54ae27fd841f33fd979476b1c378fe58fe7ff52f Mon Sep 17 00:00:00 2001 From: Terry Howe Date: Fri, 22 May 2026 16:09:20 -0600 Subject: [PATCH 25/30] fix(deps): bump golang.org/x/net to v0.55.0 to address GO-2026-5026 Upgrades golang.org/x/net from v0.53.0 to v0.55.0 to fix CVE-2026-39821 (GO-2026-5026), where idna.ToASCII/ToUnicode incorrectly accept Punycode- encoded labels that decode to ASCII-only labels, enabling privilege escalation via hostname check bypass. Coordinated x/ upgrade pulled in by the module graph: - golang.org/x/sys v0.44.0 => v0.45.0 Signed-off-by: Terry Howe --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 8220a5f1c..14662ddb4 100644 --- a/go.mod +++ b/go.mod @@ -158,10 +158,10 @@ require ( go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.53.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.44.0 // indirect + golang.org/x/sys v0.45.0 // indirect golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.44.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect diff --git a/go.sum b/go.sum index 544e4205e..422a39eb9 100644 --- a/go.sum +++ b/go.sum @@ -400,8 +400,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -430,8 +430,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= From e679ec9f041f9fa484f8539efd4b5e665526b883 Mon Sep 17 00:00:00 2001 From: Arnav Nagzirkar Date: Mon, 25 May 2026 22:27:12 -0700 Subject: [PATCH 26/30] ci: enable bidichk linter to prevent invisible Unicode characters Adds the bidichk linter to .golangci.yml to detect dangerous invisible Unicode characters (ZWSP, bidi controls) in source files during CI. Fixes #32137 Signed-off-by: Arnav Nagzirkar --- .golangci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.golangci.yml b/.golangci.yml index 1ed3353b4..ca3566f15 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,6 +19,7 @@ linters: # Keep sorted alphabetically enable: + - bidichk - depguard - dupl - exhaustive From 7510b832149ee739b3ace110f8238e1ffd922cca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 02:05:35 +0000 Subject: [PATCH 27/30] chore(deps): bump golang.org/x/crypto from 0.51.0 to 0.52.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.51.0 to 0.52.0. - [Commits](https://github.com/golang/crypto/compare/v0.51.0...v0.52.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.52.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 14662ddb4..2cd535e49 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/tetratelabs/wazero v1.11.0 go.yaml.in/yaml/v3 v3.0.4 - golang.org/x/crypto v0.51.0 + golang.org/x/crypto v0.52.0 golang.org/x/term v0.43.0 golang.org/x/text v0.37.0 gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 422a39eb9..30244c99c 100644 --- a/go.sum +++ b/go.sum @@ -382,8 +382,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= From 6dc1c1ccf8066b06f5e30c5bf1d2cdd2924c8c43 Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 27 May 2026 14:59:21 -0400 Subject: [PATCH 28/30] lower resync period Signed-off-by: Austin Abro --- pkg/kube/statuswait.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pkg/kube/statuswait.go b/pkg/kube/statuswait.go index 59c1218ff..29de0af2b 100644 --- a/pkg/kube/statuswait.go +++ b/pkg/kube/statuswait.go @@ -68,6 +68,12 @@ func alwaysReady(_ *unstructured.Unstructured) (*status.Result, error) { }, nil } +func getStatusWatcher(dynamicClient dynamic.Interface, mapper meta.RESTMapper) *watcher.DefaultStatusWatcher { + sw := watcher.NewDefaultStatusWatcher(dynamicClient, mapper) + sw.ResyncPeriod = 3 * time.Minute + return sw +} + func (w *statusWaiter) WatchUntilReady(resourceList ResourceList, timeout time.Duration) error { if timeout == 0 { timeout = DefaultStatusWatcherTimeout @@ -75,7 +81,7 @@ func (w *statusWaiter) WatchUntilReady(resourceList ResourceList, timeout time.D ctx, cancel := w.contextWithTimeout(w.watchUntilReadyCtx, timeout) defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) - sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) + sw := getStatusWatcher(w.client, w.restMapper) jobSR := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) podSR := helmStatusReaders.NewCustomPodStatusReader(w.restMapper) // We don't want to wait on any other resources as watchUntilReady is only for Helm hooks. @@ -97,7 +103,7 @@ func (w *statusWaiter) Wait(resourceList ResourceList, timeout time.Duration) er ctx, cancel := w.contextWithTimeout(w.waitCtx, timeout) defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) - sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) + sw := getStatusWatcher(w.client, w.restMapper) sw.StatusReader = statusreaders.NewStatusReader(w.restMapper, w.readers...) return w.wait(ctx, resourceList, sw) } @@ -109,7 +115,7 @@ func (w *statusWaiter) WaitWithJobs(resourceList ResourceList, timeout time.Dura ctx, cancel := w.contextWithTimeout(w.waitWithJobsCtx, timeout) defer cancel() w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) - sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) + sw := getStatusWatcher(w.client, w.restMapper) newCustomJobStatusReader := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) readers := append([]engine.StatusReader(nil), w.readers...) readers = append(readers, newCustomJobStatusReader) @@ -125,7 +131,7 @@ func (w *statusWaiter) WaitForDelete(resourceList ResourceList, timeout time.Dur ctx, cancel := w.contextWithTimeout(w.waitForDeleteCtx, timeout) defer cancel() w.Logger().Debug("waiting for resources to be deleted", "count", len(resourceList), "timeout", timeout) - sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) + sw := getStatusWatcher(w.client, w.restMapper) return w.waitForDelete(ctx, resourceList, sw) } From 3aa1b742b9228219378ce3d1b978d8d9e30547cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 23:30:01 +0000 Subject: [PATCH 29/30] chore(deps): bump github.com/tetratelabs/wazero from 1.11.0 to 1.12.0 Bumps [github.com/tetratelabs/wazero](https://github.com/tetratelabs/wazero) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/tetratelabs/wazero/releases) - [Commits](https://github.com/tetratelabs/wazero/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: github.com/tetratelabs/wazero dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2cd535e49..77d0e92fc 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 - github.com/tetratelabs/wazero v1.11.0 + github.com/tetratelabs/wazero v1.12.0 go.yaml.in/yaml/v3 v3.0.4 golang.org/x/crypto v0.52.0 golang.org/x/term v0.43.0 diff --git a/go.sum b/go.sum index 30244c99c..a48486be0 100644 --- a/go.sum +++ b/go.sum @@ -309,8 +309,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 h1:ZF+QBjOI+tILZjBaFj3HgFonKXUcwgJ4djLb6i42S3Q= github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834/go.mod h1:m9ymHTgNSEjuxvw8E7WWe4Pl4hZQHXONY8wE6dMLaRk= -github.com/tetratelabs/wazero v1.11.0 h1:+gKemEuKCTevU4d7ZTzlsvgd1uaToIDtlQlmNbwqYhA= -github.com/tetratelabs/wazero v1.11.0/go.mod h1:eV28rsN8Q+xwjogd7f4/Pp4xFxO7uOGbLcD/LzB1wiU= +github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU= +github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= From f8abbfd7d4ab7d9cd883fab5d24c8175eaec56b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:57:37 +0000 Subject: [PATCH 30/30] chore(deps): bump github/codeql-action from 4.36.0 to 4.36.1 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...87557b9c84dde89fdd9b10e88954ac2f4248e463) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1c3ea0bf4..351acf713 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -48,7 +48,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 + uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # pinv4.36.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -59,7 +59,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 + uses: github/codeql-action/autobuild@87557b9c84dde89fdd9b10e88954ac2f4248e463 # pinv4.36.1 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -73,4 +73,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # pinv4.36.0 + uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # pinv4.36.1 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index c4a0cb196..0fe504b87 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -64,6 +64,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: sarif_file: results.sarif