Repository: helm/helm
Pull request #13483 (2024-11-25 17:17:23)

fix(helm): pass down username/password CLI parameters to OCI registry clients (v3 backport)
**What this PR does / why we need it**:

Backport https://github.com/helm/helm/pull/12769 to v3 branch

**Special notes for your reviewer**:

**If applicable**:
- [ ] this PR contains user facing changes (the `docs needed` label should be applied if so)
- [ ] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility



Patch:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 9a6aeb582..a5dbdac4d 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -13,14 +13,10 @@ name: "CodeQL"
 
 on:
   push:
-    branches:
-      - main
-      - dev-v3
+    branches: [ main ]
   pull_request:
     # The branches below must be a subset of the branches above
-    branches:
-      - main
-      - dev-v3
+    branches: [ main ]
   schedule:
     - cron: '29 6 * * 6'
 
@@ -43,7 +39,7 @@ jobs:
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
+      uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # pin@v4.2.1
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index 746f7c306..2b61232aa 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -13,10 +13,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
+        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # pin@v4.2.1
 
       - name: Setup Go
-        uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # pin@5.1.0
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
         with:
           go-version: '1.22'
           check-latest: true
diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml
index ea9d09526..e8e33a0e8 100644
--- a/.github/workflows/govulncheck.yml
+++ b/.github/workflows/govulncheck.yml
@@ -14,7 +14,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Setup Go
-        uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # pin@5.1.0
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
         with:
           go-version: '1.22'
           check-latest: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9d51acef7..31cd39308 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -17,15 +17,15 @@ permissions: read-all
 jobs:
   release:
     if: startsWith(github.ref, 'refs/tags/v')
-    runs-on: ubuntu-latest-16-cores
+    runs-on: ubuntu-latest
     steps:
       - name: Checkout source code
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
+        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # pin@v4.2.1
         with:
           fetch-depth: 0
 
       - name: Setup Go
-        uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # pin@5.1.0
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
         with:
           go-version: '1.22.7'
 
@@ -74,14 +74,14 @@ jobs:
           connection_string: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
 
   canary-release:
-    runs-on: ubuntu-latest-16-cores
+    runs-on: ubuntu-latest
     if: github.ref == 'refs/heads/main'
     steps:
       - name: Checkout source code
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
+        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # pin@v4.2.1
 
       - name: Setup Go
-        uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # pin@5.1.0
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
         with:
           go-version: '1.22'
           check-latest: true
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index a4edf1a1e..881a5f1b8 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -28,7 +28,7 @@ jobs:
 
     steps:
       - name: "Checkout code"
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
         with:
           persist-credentials: false
 
diff --git a/.github/workflows/stale-issue-bot.yaml b/.github/workflows/stale-issue-bot.yaml
index b31e08b6e..8ec5b7f5a 100644
--- a/.github/workflows/stale-issue-bot.yaml
+++ b/.github/workflows/stale-issue-bot.yaml
@@ -9,7 +9,7 @@ jobs:
   stale:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0
+    - uses: actions/stale@87c2b794b9b47a9bec68ae03c01aeb572ffebdb1 # v3.0.14
       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.'
diff --git a/Makefile b/Makefile
index 2a264916a..b4bdf34a4 100644
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ all: build
 build: $(BINDIR)/$(BINNAME)
 
 $(BINDIR)/$(BINNAME): $(SRC)
-	CGO_ENABLED=$(CGO_ENABLED) go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME) ./cmd/helm
+	GO111MODULE=on CGO_ENABLED=$(CGO_ENABLED) go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME) ./cmd/helm
 
 # ------------------------------------------------------------------------------
 #  install
@@ -104,15 +104,15 @@ test: test-unit
 test-unit:
 	@echo
 	@echo "==> Running unit tests <=="
-	go test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
+	GO111MODULE=on go test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
 	@echo
 	@echo "==> Running unit test(s) with ldflags <=="
 # Test to check the deprecation warnings on Kubernetes templates created by `helm create` against the current Kubernetes
 # version. Note: The version details are set in var LDFLAGS. To avoid the ldflags impact on other unit tests that are
 # based on older versions, this is run separately. When run without the ldflags in the unit test (above) or coverage
 # test, it still passes with a false-positive result as the resources shouldn’t be deprecated in the older Kubernetes
-# version if it only starts failing with the latest.
-	go test $(GOFLAGS) -run ^TestHelmCreateChart_CheckDeprecatedWarnings$$ ./pkg/lint/ $(TESTFLAGS) -ldflags '$(LDFLAGS)'
+# version if it only starts failing with the latest. 
+	GO111MODULE=on go test $(GOFLAGS) -run ^TestHelmCreateChart_CheckDeprecatedWarnings$$ ./pkg/lint/ $(TESTFLAGS) -ldflags '$(LDFLAGS)'
 
 
 .PHONY: test-coverage
@@ -151,7 +151,7 @@ coverage:
 
 .PHONY: format
 format: $(GOIMPORTS)
-	go list -f '{{.Dir}}' ./... | xargs $(GOIMPORTS) -w -local helm.sh/helm
+	GO111MODULE=on go list -f '{{.Dir}}' ./... | xargs $(GOIMPORTS) -w -local helm.sh/helm
 
 # Generate golden files used in unit tests
 .PHONY: gen-test-golden
@@ -168,10 +168,10 @@ gen-test-golden: test-unit
 # without a go.mod file when downloading the following dependencies
 
 $(GOX):
-	(cd /; go install github.com/mitchellh/gox@v1.0.2-0.20220701044238-9f712387e2d2)
+	(cd /; GO111MODULE=on go install github.com/mitchellh/gox@v1.0.2-0.20220701044238-9f712387e2d2)
 
 $(GOIMPORTS):
-	(cd /; go install golang.org/x/tools/cmd/goimports@latest)
+	(cd /; GO111MODULE=on go install golang.org/x/tools/cmd/goimports@latest)
 
 # ------------------------------------------------------------------------------
 #  release
@@ -179,7 +179,7 @@ $(GOIMPORTS):
 .PHONY: build-cross
 build-cross: LDFLAGS += -extldflags "-static"
 build-cross: $(GOX)
-	GOFLAGS="-trimpath" CGO_ENABLED=0 $(GOX) -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/$(BINNAME)" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/helm
+	GOFLAGS="-trimpath" GO111MODULE=on CGO_ENABLED=0 $(GOX) -parallel=3 -output="_dist/{{.OS}}-{{.Arch}}/$(BINNAME)" -osarch='$(TARGETS)' $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/helm
 
 .PHONY: dist
 dist:
diff --git a/cmd/helm/dependency.go b/cmd/helm/dependency.go
index 228c73c80..19b648604 100644
--- a/cmd/helm/dependency.go
+++ b/cmd/helm/dependency.go
@@ -20,6 +20,7 @@ import (
 	"path/filepath"
 
 	"github.com/spf13/cobra"
+	"github.com/spf13/pflag"
 
 	"helm.sh/helm/v3/cmd/helm/require"
 	"helm.sh/helm/v3/pkg/action"
@@ -93,7 +94,7 @@ func newDependencyCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 
 	cmd.AddCommand(newDependencyListCmd(out))
 	cmd.AddCommand(newDependencyUpdateCmd(cfg, out))
-	cmd.AddCommand(newDependencyBuildCmd(cfg, out))
+	cmd.AddCommand(newDependencyBuildCmd(out))
 
 	return cmd
 }
@@ -120,3 +121,16 @@ func newDependencyListCmd(out io.Writer) *cobra.Command {
 	f.UintVar(&client.ColumnWidth, "max-col-width", 80, "maximum column width for output table")
 	return cmd
 }
+
+func addDependencySubcommandFlags(f *pflag.FlagSet, client *action.Dependency) {
+	f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
+	f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
+	f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
+	f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
+	f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
+	f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
+	f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
+	f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
+	f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
+	f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
+}
diff --git a/cmd/helm/dependency_build.go b/cmd/helm/dependency_build.go
index 2cf0c6c81..5b5598498 100644
--- a/cmd/helm/dependency_build.go
+++ b/cmd/helm/dependency_build.go
@@ -41,7 +41,7 @@ If no lock file is found, 'helm dependency build' will mirror the behavior
 of 'helm dependency update'.
 `
 
-func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
+func newDependencyBuildCmd(out io.Writer) *cobra.Command {
 	client := action.NewDependency()
 
 	cmd := &cobra.Command{
@@ -54,13 +54,19 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
 			if len(args) > 0 {
 				chartpath = filepath.Clean(args[0])
 			}
+			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
+			if err != nil {
+				return fmt.Errorf("missing registry client: %w", err)
+			}
+
 			man := &downloader.Manager{
 				Out:              out,
 				ChartPath:        chartpath,
 				Keyring:          client.Keyring,
 				SkipUpdate:       client.SkipRefresh,
 				Getters:          getter.All(settings),
-				RegistryClient:   cfg.RegistryClient,
+				RegistryClient:   registryClient,
 				RepositoryConfig: settings.RepositoryConfig,
 				RepositoryCache:  settings.RepositoryCache,
 				Debug:            settings.Debug,
@@ -68,7 +74,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
 			if client.Verify {
 				man.Verify = downloader.VerifyIfPossible
 			}
-			err := man.Build()
+			err = man.Build()
 			if e, ok := err.(downloader.ErrRepoNotFound); ok {
 				return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
 			}
@@ -77,9 +83,7 @@ func newDependencyBuildCmd(cfg *action.Configuration, out io.Writer) *cobra.Comm
 	}
 
 	f := cmd.Flags()
-	f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
-	f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
-	f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
+	addDependencySubcommandFlags(f, client)
 
 	return cmd
 }
diff --git a/cmd/helm/dependency_update.go b/cmd/helm/dependency_update.go
index cb6e9c0cc..3ac39adff 100644
--- a/cmd/helm/dependency_update.go
+++ b/cmd/helm/dependency_update.go
@@ -16,6 +16,7 @@ limitations under the License.
 package main
 
 import (
+	"fmt"
 	"io"
 	"path/filepath"
 
@@ -43,7 +44,7 @@ in the Chart.yaml file, but (b) at the wrong version.
 `
 
 // newDependencyUpdateCmd creates a new dependency update command.
-func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
+func newDependencyUpdateCmd(_ *action.Configuration, out io.Writer) *cobra.Command {
 	client := action.NewDependency()
 
 	cmd := &cobra.Command{
@@ -57,13 +58,19 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
 			if len(args) > 0 {
 				chartpath = filepath.Clean(args[0])
 			}
+			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
+			if err != nil {
+				return fmt.Errorf("missing registry client: %w", err)
+			}
+
 			man := &downloader.Manager{
 				Out:              out,
 				ChartPath:        chartpath,
 				Keyring:          client.Keyring,
 				SkipUpdate:       client.SkipRefresh,
 				Getters:          getter.All(settings),
-				RegistryClient:   cfg.RegistryClient,
+				RegistryClient:   registryClient,
 				RepositoryConfig: settings.RepositoryConfig,
 				RepositoryCache:  settings.RepositoryCache,
 				Debug:            settings.Debug,
@@ -76,9 +83,7 @@ func newDependencyUpdateCmd(cfg *action.Configuration, out io.Writer) *cobra.Com
 	}
 
 	f := cmd.Flags()
-	f.BoolVar(&client.Verify, "verify", false, "verify the packages against signatures")
-	f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "keyring containing public keys")
-	f.BoolVar(&client.SkipRefresh, "skip-refresh", false, "do not refresh the local repository cache")
+	addDependencySubcommandFlags(f, client)
 
 	return cmd
 }
diff --git a/cmd/helm/install.go b/cmd/helm/install.go
index 23ff29d95..15ae6952f 100644
--- a/cmd/helm/install.go
+++ b/cmd/helm/install.go
@@ -141,7 +141,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 		},
 		RunE: func(_ *cobra.Command, args []string) error {
 			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
-				client.InsecureSkipTLSverify, client.PlainHTTP)
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
 			if err != nil {
 				return fmt.Errorf("missing registry client: %w", err)
 			}
diff --git a/cmd/helm/package.go b/cmd/helm/package.go
index b96110ee8..19ab3dc7f 100644
--- a/cmd/helm/package.go
+++ b/cmd/helm/package.go
@@ -47,7 +47,7 @@ If '--keyring' is not specified, Helm usually defaults to the public keyring
 unless your environment is otherwise configured.
 `
 
-func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
+func newPackageCmd(out io.Writer) *cobra.Command {
 	client := action.NewPackage()
 	valueOpts := &values.Options{}
 
@@ -75,6 +75,12 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 				return err
 			}
 
+			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
+			if err != nil {
+				return fmt.Errorf("missing registry client: %w", err)
+			}
+
 			for i := 0; i < len(args); i++ {
 				path, err := filepath.Abs(args[i])
 				if err != nil {
@@ -91,7 +97,7 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 						Keyring:          client.Keyring,
 						Getters:          p,
 						Debug:            settings.Debug,
-						RegistryClient:   cfg.RegistryClient,
+						RegistryClient:   registryClient,
 						RepositoryConfig: settings.RepositoryConfig,
 						RepositoryCache:  settings.RepositoryCache,
 					}
@@ -119,6 +125,13 @@ func newPackageCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 	f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version")
 	f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.")
 	f.BoolVarP(&client.DependencyUpdate, "dependency-update", "u", false, `update dependencies from "Chart.yaml" to dir "charts/" before packaging`)
+	f.StringVar(&client.Username, "username", "", "chart repository username where to locate the requested chart")
+	f.StringVar(&client.Password, "password", "", "chart repository password where to locate the requested chart")
+	f.StringVar(&client.CertFile, "cert-file", "", "identify HTTPS client using this SSL certificate file")
+	f.StringVar(&client.KeyFile, "key-file", "", "identify HTTPS client using this SSL key file")
+	f.BoolVar(&client.InsecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart download")
+	f.BoolVar(&client.PlainHTTP, "plain-http", false, "use insecure HTTP connections for the chart download")
+	f.StringVar(&client.CaFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
 
 	return cmd
 }
diff --git a/cmd/helm/pull.go b/cmd/helm/pull.go
index e0dd1effe..de4918d72 100644
--- a/cmd/helm/pull.go
+++ b/cmd/helm/pull.go
@@ -65,7 +65,7 @@ func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 			}
 
 			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
-				client.InsecureSkipTLSverify, client.PlainHTTP)
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
 			if err != nil {
 				return fmt.Errorf("missing registry client: %w", err)
 			}
diff --git a/cmd/helm/push.go b/cmd/helm/push.go
index 6ec26441d..9a67fa086 100644
--- a/cmd/helm/push.go
+++ b/cmd/helm/push.go
@@ -40,6 +40,8 @@ type registryPushOptions struct {
 	caFile                string
 	insecureSkipTLSverify bool
 	plainHTTP             bool
+	password              string
+	username              string
 }
 
 func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
@@ -68,7 +70,10 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 			return noMoreArgsComp()
 		},
 		RunE: func(_ *cobra.Command, args []string) error {
-			registryClient, err := newRegistryClient(o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP)
+			registryClient, err := newRegistryClient(
+				o.certFile, o.keyFile, o.caFile, o.insecureSkipTLSverify, o.plainHTTP, o.username, o.password,
+			)
+
 			if err != nil {
 				return fmt.Errorf("missing registry client: %w", err)
 			}
@@ -96,6 +101,8 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 	f.StringVar(&o.caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle")
 	f.BoolVar(&o.insecureSkipTLSverify, "insecure-skip-tls-verify", false, "skip tls certificate checks for the chart upload")
 	f.BoolVar(&o.plainHTTP, "plain-http", false, "use insecure HTTP connections for the chart upload")
+	f.StringVar(&o.username, "username", "", "chart repository username where to locate the requested chart")
+	f.StringVar(&o.password, "password", "", "chart repository password where to locate the requested chart")
 
 	return cmd
 }
diff --git a/cmd/helm/root.go b/cmd/helm/root.go
index 57738b111..2ba8a882e 100644
--- a/cmd/helm/root.go
+++ b/cmd/helm/root.go
@@ -21,6 +21,7 @@ import (
 	"fmt"
 	"io"
 	"log"
+	"net/http"
 	"os"
 	"strings"
 
@@ -29,6 +30,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/tools/clientcmd"
 
+	"helm.sh/helm/v3/internal/tlsutil"
 	"helm.sh/helm/v3/pkg/action"
 	"helm.sh/helm/v3/pkg/registry"
 	"helm.sh/helm/v3/pkg/repo"
@@ -153,7 +155,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
 	flags.ParseErrorsWhitelist.UnknownFlags = true
 	flags.Parse(args)
 
-	registryClient, err := newDefaultRegistryClient(false)
+	registryClient, err := newDefaultRegistryClient(false, "", "")
 	if err != nil {
 		return nil, err
 	}
@@ -167,7 +169,7 @@ func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string
 		newPullCmd(actionConfig, out),
 		newShowCmd(actionConfig, out),
 		newLintCmd(out),
-		newPackageCmd(actionConfig, out),
+		newPackageCmd(out),
 		newRepoCmd(out),
 		newSearchCmd(out),
 		newVerifyCmd(out),
@@ -255,27 +257,30 @@ func checkForExpiredRepos(repofile string) {
 
 }
 
-func newRegistryClient(certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool) (*registry.Client, error) {
+func newRegistryClient(
+	certFile, keyFile, caFile string, insecureSkipTLSverify, plainHTTP bool, username, password string,
+) (*registry.Client, error) {
 	if certFile != "" && keyFile != "" || caFile != "" || insecureSkipTLSverify {
-		registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify)
+		registryClient, err := newRegistryClientWithTLS(certFile, keyFile, caFile, insecureSkipTLSverify, username, password)
 		if err != nil {
 			return nil, err
 		}
 		return registryClient, nil
 	}
-	registryClient, err := newDefaultRegistryClient(plainHTTP)
+	registryClient, err := newDefaultRegistryClient(plainHTTP, username, password)
 	if err != nil {
 		return nil, err
 	}
 	return registryClient, nil
 }
 
-func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) {
+func newDefaultRegistryClient(plainHTTP bool, username, password string) (*registry.Client, error) {
 	opts := []registry.ClientOption{
 		registry.ClientOptDebug(settings.Debug),
 		registry.ClientOptEnableCache(true),
 		registry.ClientOptWriter(os.Stderr),
 		registry.ClientOptCredentialsFile(settings.RegistryConfig),
+		registry.ClientOptBasicAuth(username, password),
 	}
 	if plainHTTP {
 		opts = append(opts, registry.ClientOptPlainHTTP())
@@ -289,10 +294,26 @@ func newDefaultRegistryClient(plainHTTP bool) (*registry.Client, error) {
 	return registryClient, nil
 }
 
-func newRegistryClientWithTLS(certFile, keyFile, caFile string, insecureSkipTLSverify bool) (*registry.Client, error) {
+func newRegistryClientWithTLS(
+	certFile, keyFile, caFile string, insecureSkipTLSverify bool, username, password string,
+) (*registry.Client, error) {
+	tlsConf, err := tlsutil.NewClientTLS(certFile, keyFile, caFile, insecureSkipTLSverify)
+	if err != nil {
+		return nil, fmt.Errorf("can't create TLS config for client: %w", err)
+	}
+
 	// Create a new registry client
-	registryClient, err := registry.NewRegistryClientWithTLS(os.Stderr, certFile, keyFile, caFile, insecureSkipTLSverify,
-		settings.RegistryConfig, settings.Debug,
+	registryClient, err := registry.NewClient(
+		registry.ClientOptDebug(settings.Debug),
+		registry.ClientOptEnableCache(true),
+		registry.ClientOptWriter(os.Stderr),
+		registry.ClientOptCredentialsFile(settings.RegistryConfig),
+		registry.ClientOptHTTPClient(&http.Client{
+			Transport: &http.Transport{
+				TLSClientConfig: tlsConf,
+			},
+		}),
+		registry.ClientOptBasicAuth(username, password),
 	)
 	if err != nil {
 		return nil, err
diff --git a/cmd/helm/show.go b/cmd/helm/show.go
index 7c06a2297..b850af099 100644
--- a/cmd/helm/show.go
+++ b/cmd/helm/show.go
@@ -226,7 +226,7 @@ func runShow(args []string, client *action.Show) (string, error) {
 
 func addRegistryClient(client *action.Show) error {
 	registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
-		client.InsecureSkipTLSverify, client.PlainHTTP)
+		client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
 	if err != nil {
 		return fmt.Errorf("missing registry client: %w", err)
 	}
diff --git a/cmd/helm/template.go b/cmd/helm/template.go
index b53ed6b1c..ff6621a49 100644
--- a/cmd/helm/template.go
+++ b/cmd/helm/template.go
@@ -74,7 +74,7 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 			}
 
 			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
-				client.InsecureSkipTLSverify, client.PlainHTTP)
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
 			if err != nil {
 				return fmt.Errorf("missing registry client: %w", err)
 			}
diff --git a/cmd/helm/upgrade.go b/cmd/helm/upgrade.go
index 108550cbf..1585a78da 100644
--- a/cmd/helm/upgrade.go
+++ b/cmd/helm/upgrade.go
@@ -103,7 +103,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 			client.Namespace = settings.Namespace()
 
 			registryClient, err := newRegistryClient(client.CertFile, client.KeyFile, client.CaFile,
-				client.InsecureSkipTLSverify, client.PlainHTTP)
+				client.InsecureSkipTLSverify, client.PlainHTTP, client.Username, client.Password)
 			if err != nil {
 				return fmt.Errorf("missing registry client: %w", err)
 			}
diff --git a/go.mod b/go.mod
index 9dc909796..f9ae67011 100644
--- a/go.mod
+++ b/go.mod
@@ -34,17 +34,17 @@ require (
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.9.0
 	github.com/xeipuuv/gojsonschema v1.2.0
-	golang.org/x/crypto v0.29.0
-	golang.org/x/term v0.26.0
-	golang.org/x/text v0.20.0
-	k8s.io/api v0.31.2
-	k8s.io/apiextensions-apiserver v0.31.2
-	k8s.io/apimachinery v0.31.2
-	k8s.io/apiserver v0.31.2
-	k8s.io/cli-runtime v0.31.2
-	k8s.io/client-go v0.31.2
+	golang.org/x/crypto v0.28.0
+	golang.org/x/term v0.25.0
+	golang.org/x/text v0.19.0
+	k8s.io/api v0.31.1
+	k8s.io/apiextensions-apiserver v0.31.1
+	k8s.io/apimachinery v0.31.1
+	k8s.io/apiserver v0.31.1
+	k8s.io/cli-runtime v0.31.1
+	k8s.io/client-go v0.31.1
 	k8s.io/klog/v2 v2.130.1
-	k8s.io/kubectl v0.31.2
+	k8s.io/kubectl v0.31.1
 	oras.land/oras-go v1.2.5
 	sigs.k8s.io/yaml v1.4.0
 )
@@ -152,8 +152,8 @@ require (
 	golang.org/x/mod v0.17.0 // indirect
 	golang.org/x/net v0.26.0 // indirect
 	golang.org/x/oauth2 v0.21.0 // indirect
-	golang.org/x/sync v0.9.0 // indirect
-	golang.org/x/sys v0.27.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
+	golang.org/x/sys v0.26.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
@@ -163,7 +163,7 @@ require (
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/component-base v0.31.2 // indirect
+	k8s.io/component-base v0.31.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
 	k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
diff --git a/go.sum b/go.sum
index c42a2a931..4cb60f8d2 100644
--- a/go.sum
+++ b/go.sum
@@ -413,8 +413,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.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
-golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -460,8 +460,8 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
-golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -484,8 +484,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.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
-golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -494,8 +494,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.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
-golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
+golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
+golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
 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=
@@ -503,8 +503,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.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
-golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
 golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -567,26 +567,26 @@ gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
 gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0=
-k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk=
-k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0=
-k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM=
-k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
-k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
-k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4=
-k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE=
-k8s.io/cli-runtime v0.31.2 h1:7FQt4C4Xnqx8V1GJqymInK0FFsoC+fAZtbLqgXYVOLQ=
-k8s.io/cli-runtime v0.31.2/go.mod h1:XROyicf+G7rQ6FQJMbeDV9jqxzkWXTYD6Uxd15noe0Q=
-k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc=
-k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs=
-k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA=
-k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ=
+k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
+k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
+k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40=
+k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ=
+k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
+k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
+k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c=
+k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM=
+k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk=
+k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U=
+k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
+k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
+k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
+k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
-k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M=
-k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM=
+k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24=
+k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM=
 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
 k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
diff --git a/pkg/action/dependency.go b/pkg/action/dependency.go
index 3265f1f17..19305fee8 100644
--- a/pkg/action/dependency.go
+++ b/pkg/action/dependency.go
@@ -34,10 +34,17 @@ import (
 //
 // It provides the implementation of 'helm dependency' and its respective subcommands.
 type Dependency struct {
-	Verify      bool
-	Keyring     string
-	SkipRefresh bool
-	ColumnWidth uint
+	Verify                bool
+	Keyring               string
+	SkipRefresh           bool
+	ColumnWidth           uint
+	Username              string
+	Password              string
+	CertFile              string
+	KeyFile               string
+	CaFile                string
+	InsecureSkipTLSverify bool
+	PlainHTTP             bool
 }
 
 // NewDependency creates a new Dependency object with the given configuration.
diff --git a/pkg/action/hooks.go b/pkg/action/hooks.go
index 4bffb6ae0..0af625dff 100644
--- a/pkg/action/hooks.go
+++ b/pkg/action/hooks.go
@@ -99,8 +99,7 @@ func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
 
 	// If all hooks are successful, check the annotation of each hook to determine whether the hook should be deleted
 	// 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 _, h := range executingHooks {
 		if err := cfg.deleteHookByPolicy(h, release.HookSucceeded, timeout); err != nil {
 			return err
 		}
diff --git a/pkg/action/install.go b/pkg/action/install.go
index 7ca40c88a..ae732f4fd 100644
--- a/pkg/action/install.go
+++ b/pkg/action/install.go
@@ -770,6 +770,7 @@ func (c *ChartPathOptions) LocateChart(name string, settings *cli.EnvSettings) (
 			getter.WithTLSClientConfig(c.CertFile, c.KeyFile, c.CaFile),
 			getter.WithInsecureSkipVerifyTLS(c.InsecureSkipTLSverify),
 			getter.WithPlainHTTP(c.PlainHTTP),
+			getter.WithBasicAuth(c.Username, c.Password),
 		},
 		RepositoryConfig: settings.RepositoryConfig,
 		RepositoryCache:  settings.RepositoryCache,
diff --git a/pkg/action/package.go b/pkg/action/package.go
index 013b32f55..2357e3882 100644
--- a/pkg/action/package.go
+++ b/pkg/action/package.go
@@ -44,8 +44,15 @@ type Package struct {
 	Destination      string
 	DependencyUpdate bool
 
-	RepositoryConfig string
-	RepositoryCache  string
+	RepositoryConfig      string
+	RepositoryCache       string
+	PlainHTTP             bool
+	Username              string
+	Password              string
+	CertFile              string
+	KeyFile               string
+	CaFile                string
+	InsecureSkipTLSverify bool
 }
 
 // NewPackage creates a new Package object with the given configuration.
diff --git a/pkg/action/push.go b/pkg/action/push.go
index 70e5c1582..68d2ba42d 100644
--- a/pkg/action/push.go
+++ b/pkg/action/push.go
@@ -73,7 +73,7 @@ func WithPlainHTTP(plainHTTP bool) PushOpt {
 	}
 }
 
-// WithPushOptWriter sets the registryOut field on the push configuration object.
+// WithOptWriter sets the registryOut field on the push configuration object.
 func WithPushOptWriter(out io.Writer) PushOpt {
 	return func(p *Push) {
 		p.out = out
diff --git a/pkg/chart/loader/load.go b/pkg/chart/loader/load.go
index a68a05aa9..f59c35a5e 100644
--- a/pkg/chart/loader/load.go
+++ b/pkg/chart/loader/load.go
@@ -174,7 +174,7 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) {
 		case filepath.Ext(n) == ".tgz":
 			file := files[0]
 			if file.Name != n {
-				return c, errors.Errorf("error unpacking subchart tar in %s: expected %s, got %s", c.Name(), n, file.Name)
+				return c, errors.Errorf("error unpacking tar in %s: expected %s, got %s", c.Name(), n, file.Name)
 			}
 			// Untar the chart and add to c.Dependencies
 			sc, err = LoadArchive(bytes.NewBuffer(file.Data))
@@ -194,7 +194,7 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) {
 		}
 
 		if err != nil {
-			return c, errors.Wrapf(err, "error unpacking subchart %s in %s", n, c.Name())
+			return c, errors.Wrapf(err, "error unpacking %s in %s", n, c.Name())
 		}
 		c.AddDependency(sc)
 	}
diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go
index dde6a1057..a95894e00 100644
--- a/pkg/downloader/chart_downloader.go
+++ b/pkg/downloader/chart_downloader.go
@@ -97,8 +97,6 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
 		return "", nil, err
 	}
 
-	c.Options = append(c.Options, getter.WithAcceptHeader("application/gzip,application/octet-stream"))
-
 	data, err := g.Get(u.String(), c.Options...)
 	if err != nil {
 		return "", nil, err
diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go
index 1acb2093d..45ab4da7e 100644
--- a/pkg/getter/getter.go
+++ b/pkg/getter/getter.go
@@ -38,7 +38,6 @@ type options struct {
 	unTar                 bool
 	insecureSkipVerifyTLS bool
 	plainHTTP             bool
-	acceptHeader          string
 	username              string
 	password              string
 	passCredentialsAll    bool
@@ -61,13 +60,6 @@ func WithURL(url string) Option {
 	}
 }
 
-// WithAcceptHeader sets the request's Accept header as some REST APIs serve multiple content types
-func WithAcceptHeader(header string) Option {
-	return func(opts *options) {
-		opts.acceptHeader = header
-	}
-}
-
 // WithBasicAuth sets the request's Authorization header to use the provided credentials
 func WithBasicAuth(username, password string) Option {
 	return func(opts *options) {
diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go
index df3dcd910..b53e558e3 100644
--- a/pkg/getter/httpgetter.go
+++ b/pkg/getter/httpgetter.go
@@ -53,10 +53,6 @@ func (g *HTTPGetter) get(href string) (*bytes.Buffer, error) {
 		return nil, err
 	}
 
-	if g.opts.acceptHeader != "" {
-		req.Header.Set("Accept", g.opts.acceptHeader)
-	}
-
 	req.Header.Set("User-Agent", version.GetUserAgent())
 	if g.opts.userAgent != "" {
 		req.Header.Set("User-Agent", g.opts.userAgent)
diff --git a/pkg/pusher/ocipusher.go b/pkg/pusher/ocipusher.go
index 33296aadd..b37a0c605 100644
--- a/pkg/pusher/ocipusher.go
+++ b/pkg/pusher/ocipusher.go
@@ -90,9 +90,8 @@ func (pusher *OCIPusher) push(chartRef, href string) error {
 		path.Join(strings.TrimPrefix(href, fmt.Sprintf("%s://", registry.OCIScheme)), meta.Metadata.Name),
 		meta.Metadata.Version)
 
-	// The time the chart was "created" is semantically the time the chart archive file was last written(modified)
-	chartArchiveFileCreatedTime := ctime.Modified(stat)
-	pushOpts = append(pushOpts, registry.PushOptCreationTime(chartArchiveFileCreatedTime.Format(time.RFC3339)))
+	chartCreationTime := ctime.Created(stat)
+	pushOpts = append(pushOpts, registry.PushOptCreationTime(chartCreationTime.Format(time.RFC3339)))
 
 	_, err = client.Push(chartBytes, ref, pushOpts...)
 	return err
diff --git a/pkg/registry/client.go b/pkg/registry/client.go
index 42f736816..9e58e1c16 100644
--- a/pkg/registry/client.go
+++ b/pkg/registry/client.go
@@ -18,6 +18,7 @@ package registry // import "helm.sh/helm/v3/pkg/registry"
 
 import (
 	"context"
+	"encoding/base64"
 	"encoding/json"
 	"fmt"
 	"io"
@@ -56,6 +57,8 @@ type (
 		enableCache bool
 		// path to repository config file e.g. ~/.docker/config.json
 		credentialsFile    string
+		username           string
+		password           string
 		out                io.Writer
 		authorizer         auth.Client
 		registryAuthorizer *registryauth.Client
@@ -105,6 +108,19 @@ func NewClient(options ...ClientOption) (*Client, error) {
 		if client.plainHTTP {
 			opts = append(opts, auth.WithResolverPlainHTTP())
 		}
+
+		// if username and password are set, use them for authentication
+		// by adding the basic auth Authorization header to the resolver
+		if client.username != "" && client.password != "" {
+			concat := client.username + ":" + client.password
+			encodedAuth := base64.StdEncoding.EncodeToString([]byte(concat))
+			opts = append(opts, auth.WithResolverHeaders(
+				http.Header{
+					"Authorization": []string{"Basic " + encodedAuth},
+				},
+			))
+		}
+
 		resolver, err := client.authorizer.ResolverWithOpts(opts...)
 		if err != nil {
 			return nil, err
@@ -125,6 +141,13 @@ func NewClient(options ...ClientOption) (*Client, error) {
 			},
 			Cache: cache,
 			Credential: func(_ context.Context, reg string) (registryauth.Credential, error) {
+				if client.username != "" && client.password != "" {
+					return registryauth.Credential{
+						Username: client.username,
+						Password: client.password,
+					}, nil
+				}
+
 				dockerClient, ok := client.authorizer.(*dockerauth.Client)
 				if !ok {
 					return registryauth.EmptyCredential, errors.New("unable to obtain docker client")
@@ -168,6 +191,14 @@ func ClientOptEnableCache(enableCache bool) ClientOption {
 	}
 }
 
+// ClientOptBasicAuth returns a function that sets the username and password setting on client options set
+func ClientOptBasicAuth(username, password string) ClientOption {
+	return func(client *Client) {
+		client.username = username
+		client.password = password
+	}
+}
+
 // ClientOptWriter returns a function that sets the writer setting on client options set
 func ClientOptWriter(out io.Writer) ClientOption {
 	return func(client *Client) {
diff --git a/pkg/time/ctime/ctime.go b/pkg/time/ctime/ctime.go
index 63a41c0bf..f2998d76d 100644
--- a/pkg/time/ctime/ctime.go
+++ b/pkg/time/ctime/ctime.go
@@ -21,9 +21,5 @@ import (
 )
 
 func Created(fi os.FileInfo) time.Time {
-	return modified(fi)
-}
-
-func Modified(fi os.FileInfo) time.Time {
-	return modified(fi)
+	return created(fi)
 }
diff --git a/pkg/time/ctime/ctime_linux.go b/pkg/time/ctime/ctime_linux.go
index d8a6ea1a1..c3cea1d78 100644
--- a/pkg/time/ctime/ctime_linux.go
+++ b/pkg/time/ctime/ctime_linux.go
@@ -23,8 +23,8 @@ import (
 	"time"
 )
 
-func modified(fi os.FileInfo) time.Time {
+func created(fi os.FileInfo) time.Time {
 	st := fi.Sys().(*syscall.Stat_t)
 	//nolint
-	return time.Unix(int64(st.Mtim.Sec), int64(st.Mtim.Nsec))
+	return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
 }
diff --git a/pkg/time/ctime/ctime_other.go b/pkg/time/ctime/ctime_other.go
index 12afc6df2..f21ed7347 100644
--- a/pkg/time/ctime/ctime_other.go
+++ b/pkg/time/ctime/ctime_other.go
@@ -22,6 +22,6 @@ import (
 	"time"
 )
 
-func modified(fi os.FileInfo) time.Time {
+func created(fi os.FileInfo) time.Time {
 	return fi.ModTime()
 }
diff --git a/scripts/get-helm-3 b/scripts/get-helm-3
index 5f19bd3fa..2292b70ee 100755
--- a/scripts/get-helm-3
+++ b/scripts/get-helm-3
@@ -30,7 +30,6 @@ HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)"
 HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)"
 HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)"
 HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)"
-HAS_TAR="$(type "tar" &> /dev/null && echo true || echo false)"
 
 # initArch discovers the architecture for this system.
 initArch() {
@@ -103,11 +102,6 @@ verifySupported() {
   if [ "${HAS_GIT}" != "true" ]; then
     echo "[WARNING] Could not find git. It is required for plugin installation."
   fi
-
-  if [ "${HAS_TAR}" != "true" ]; then
-    echo "[ERROR] Could not find tar. It is required to extract the helm binary archive."
-    exit 1
-  fi
 }
 
 # checkDesiredVersion checks if the desired version is available.


Test patch:
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index 19ada6df6..28338dd68 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -3,7 +3,6 @@ on:
   push:
     branches:
       - "main"
-      - "dev-v3"
       - "release-**"
   pull_request:
     branches:
@@ -17,9 +16,9 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout source code
-        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4.2.2
+        uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # pin@v4.2.1
       - name: Setup Go
-        uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # pin@5.1.0
+        uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # pin@5.0.2
         with:
           go-version: '1.22'
           check-latest: true
diff --git a/cmd/helm/testdata/output/lint-chart-with-bad-subcharts-with-subcharts.txt b/cmd/helm/testdata/output/lint-chart-with-bad-subcharts-with-subcharts.txt
index 6e2efcecd..d43c7c361 100644
--- a/cmd/helm/testdata/output/lint-chart-with-bad-subcharts-with-subcharts.txt
+++ b/cmd/helm/testdata/output/lint-chart-with-bad-subcharts-with-subcharts.txt
@@ -1,8 +1,8 @@
 ==> Linting testdata/testcharts/chart-with-bad-subcharts
 [INFO] Chart.yaml: icon is recommended
-[ERROR] templates/: error unpacking subchart bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
+[ERROR] templates/: error unpacking bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
 [ERROR] : unable to load chart
-	error unpacking subchart bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
+	error unpacking bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
 
 ==> Linting testdata/testcharts/chart-with-bad-subcharts/charts/bad-subchart
 [ERROR] Chart.yaml: name is required
diff --git a/cmd/helm/testdata/output/lint-chart-with-bad-subcharts.txt b/cmd/helm/testdata/output/lint-chart-with-bad-subcharts.txt
index af533797b..7c898b89f 100644
--- a/cmd/helm/testdata/output/lint-chart-with-bad-subcharts.txt
+++ b/cmd/helm/testdata/output/lint-chart-with-bad-subcharts.txt
@@ -1,7 +1,7 @@
 ==> Linting testdata/testcharts/chart-with-bad-subcharts
 [INFO] Chart.yaml: icon is recommended
-[ERROR] templates/: error unpacking subchart bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
+[ERROR] templates/: error unpacking bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
 [ERROR] : unable to load chart
-	error unpacking subchart bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
+	error unpacking bad-subchart in chart-with-bad-subcharts: validation: chart.metadata.name is required
 
 Error: 1 chart(s) linted, 1 chart(s) failed
diff --git a/pkg/chartutil/testdata/subpop/charts/subchart2/charts/subchartB/templates/service.yaml b/pkg/chartutil/testdata/subpop/charts/subchart2/charts/subchartB/templates/service.yaml
index fb3dfc445..3f168bdbf 100644
--- a/pkg/chartutil/testdata/subpop/charts/subchart2/charts/subchartB/templates/service.yaml
+++ b/pkg/chartutil/testdata/subpop/charts/subchart2/charts/subchartB/templates/service.yaml
@@ -3,7 +3,7 @@ kind: Service
 metadata:
   name: subchart2-{{ .Chart.Name }}
   labels:
-    helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
+    helm.sh/hart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
 spec:
   type: {{ .Values.service.type }}
   ports:
diff --git a/pkg/chartutil/validate_name_test.go b/pkg/chartutil/validate_name_test.go
index 09dec9fbb..5f0792f94 100644
--- a/pkg/chartutil/validate_name_test.go
+++ b/pkg/chartutil/validate_name_test.go
@@ -18,7 +18,7 @@ package chartutil
 
 import "testing"
 
-// TestValidateReleaseName is a regression test for ValidateName
+// TestValidateName is a regression test for ValidateName
 //
 // Kubernetes has strict naming conventions for resource names. This test represents
 // those conventions.
diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go
index 2c38c6154..0ba7e03e8 100644
--- a/pkg/getter/httpgetter_test.go
+++ b/pkg/getter/httpgetter_test.go
@@ -280,29 +280,6 @@ func TestDownload(t *testing.T) {
 	if got.String() != expect {
 		t.Errorf("Expected %q, got %q", expect, got.String())
 	}
-
-	// test server with varied Accept Header
-	const expectedAcceptHeader = "application/gzip,application/octet-stream"
-	acceptHeaderSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if r.Header.Get("Accept") != expectedAcceptHeader {
-			t.Errorf("Expected '%s', got '%s'", expectedAcceptHeader, r.Header.Get("Accept"))
-		}
-		fmt.Fprint(w, expect)
-	}))
-
-	defer acceptHeaderSrv.Close()
-
-	u, _ = url.ParseRequestURI(acceptHeaderSrv.URL)
-	httpgetter, err = NewHTTPGetter(
-		WithAcceptHeader(expectedAcceptHeader),
-	)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = httpgetter.Get(u.String())
-	if err != nil {
-		t.Fatal(err)
-	}
 }
 
 func TestDownloadTLS(t *testing.T) {
diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go
index f2d6bcb59..4ceb5f4b3 100644
--- a/pkg/kube/client_test.go
+++ b/pkg/kube/client_test.go
@@ -22,7 +22,6 @@ import (
 	"net/http"
 	"strings"
 	"testing"
-	"time"
 
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -453,195 +452,6 @@ func TestPerform(t *testing.T) {
 	}
 }
 
-func TestWait(t *testing.T) {
-	podList := newPodList("starfish", "otter", "squid")
-
-	var created *time.Time
-
-	c := newTestClient(t)
-	c.Factory.(*cmdtesting.TestFactory).Client = &fake.RESTClient{
-		NegotiatedSerializer: unstructuredSerializer,
-		Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
-			p, m := req.URL.Path, req.Method
-			t.Logf("got request %s %s", p, m)
-			switch {
-			case p == "/api/v1/namespaces/default/pods/starfish" && m == "GET":
-				pod := &podList.Items[0]
-				if created != nil && time.Since(*created) >= time.Second*5 {
-					pod.Status.Conditions = []v1.PodCondition{
-						{
-							Type:   v1.PodReady,
-							Status: v1.ConditionTrue,
-						},
-					}
-				}
-				return newResponse(200, pod)
-			case p == "/api/v1/namespaces/default/pods/otter" && m == "GET":
-				pod := &podList.Items[1]
-				if created != nil && time.Since(*created) >= time.Second*5 {
-					pod.Status.Conditions = []v1.PodCondition{
-						{
-							Type:   v1.PodReady,
-							Status: v1.ConditionTrue,
-						},
-					}
-				}
-				return newResponse(200, pod)
-			case p == "/api/v1/namespaces/default/pods/squid" && m == "GET":
-				pod := &podList.Items[2]
-				if created != nil && time.Since(*created) >= time.Second*5 {
-					pod.Status.Conditions = []v1.PodCondition{
-						{
-							Type:   v1.PodReady,
-							Status: v1.ConditionTrue,
-						},
-					}
-				}
-				return newResponse(200, pod)
-			case p == "/namespaces/default/pods" && m == "POST":
-				resources, err := c.Build(req.Body, false)
-				if err != nil {
-					t.Fatal(err)
-				}
-				now := time.Now()
-				created = &now
-				return newResponse(200, resources[0].Object)
-			default:
-				t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path)
-				return nil, nil
-			}
-		}),
-	}
-	resources, err := c.Build(objBody(&podList), false)
-	if err != nil {
-		t.Fatal(err)
-	}
-	result, err := c.Create(resources)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(result.Created) != 3 {
-		t.Errorf("expected 3 resource created, got %d", len(result.Created))
-	}
-
-	if err := c.Wait(resources, time.Second*30); err != nil {
-		t.Errorf("expected wait without error, got %s", err)
-	}
-
-	if time.Since(*created) < time.Second*5 {
-		t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created))
-	}
-}
-
-func TestWaitJob(t *testing.T) {
-	job := newJob("starfish", 0, intToInt32(1), 0, 0)
-
-	var created *time.Time
-
-	c := newTestClient(t)
-	c.Factory.(*cmdtesting.TestFactory).Client = &fake.RESTClient{
-		NegotiatedSerializer: unstructuredSerializer,
-		Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
-			p, m := req.URL.Path, req.Method
-			t.Logf("got request %s %s", p, m)
-			switch {
-			case p == "/apis/batch/v1/namespaces/default/jobs/starfish" && m == "GET":
-				if created != nil && time.Since(*created) >= time.Second*5 {
-					job.Status.Succeeded = 1
-				}
-				return newResponse(200, job)
-			case p == "/namespaces/default/jobs" && m == "POST":
-				resources, err := c.Build(req.Body, false)
-				if err != nil {
-					t.Fatal(err)
-				}
-				now := time.Now()
-				created = &now
-				return newResponse(200, resources[0].Object)
-			default:
-				t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path)
-				return nil, nil
-			}
-		}),
-	}
-	resources, err := c.Build(objBody(job), false)
-	if err != nil {
-		t.Fatal(err)
-	}
-	result, err := c.Create(resources)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(result.Created) != 1 {
-		t.Errorf("expected 1 resource created, got %d", len(result.Created))
-	}
-
-	if err := c.WaitWithJobs(resources, time.Second*30); err != nil {
-		t.Errorf("expected wait without error, got %s", err)
-	}
-
-	if time.Since(*created) < time.Second*5 {
-		t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*created))
-	}
-}
-
-func TestWaitDelete(t *testing.T) {
-	pod := newPod("starfish")
-
-	var deleted *time.Time
-
-	c := newTestClient(t)
-	c.Factory.(*cmdtesting.TestFactory).Client = &fake.RESTClient{
-		NegotiatedSerializer: unstructuredSerializer,
-		Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
-			p, m := req.URL.Path, req.Method
-			t.Logf("got request %s %s", p, m)
-			switch {
-			case p == "/namespaces/default/pods/starfish" && m == "GET":
-				if deleted != nil && time.Since(*deleted) >= time.Second*5 {
-					return newResponse(404, notFoundBody())
-				}
-				return newResponse(200, &pod)
-			case p == "/namespaces/default/pods/starfish" && m == "DELETE":
-				now := time.Now()
-				deleted = &now
-				return newResponse(200, &pod)
-			case p == "/namespaces/default/pods" && m == "POST":
-				resources, err := c.Build(req.Body, false)
-				if err != nil {
-					t.Fatal(err)
-				}
-				return newResponse(200, resources[0].Object)
-			default:
-				t.Fatalf("unexpected request: %s %s", req.Method, req.URL.Path)
-				return nil, nil
-			}
-		}),
-	}
-	resources, err := c.Build(objBody(&pod), false)
-	if err != nil {
-		t.Fatal(err)
-	}
-	result, err := c.Create(resources)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(result.Created) != 1 {
-		t.Errorf("expected 1 resource created, got %d", len(result.Created))
-	}
-	if _, err := c.Delete(resources); err != nil {
-		t.Fatal(err)
-	}
-
-	if err := c.WaitForDelete(resources, time.Second*30); err != nil {
-		t.Errorf("expected wait without error, got %s", err)
-	}
-
-	if time.Since(*deleted) < time.Second*5 {
-		t.Errorf("expected to wait at least 5 seconds before ready status was detected, but got %s", time.Since(*deleted))
-	}
-}
-
 func TestReal(t *testing.T) {
 	t.Skip("This is a live test, comment this line to run")
 	c := New(nil)
diff --git a/pkg/kube/ready_test.go b/pkg/kube/ready_test.go
index 14bf8588b..d4983ba75 100644
--- a/pkg/kube/ready_test.go
+++ b/pkg/kube/ready_test.go
@@ -20,718 +20,16 @@ import (
 	"testing"
 
 	appsv1 "k8s.io/api/apps/v1"
-	appsv1beta1 "k8s.io/api/apps/v1beta1"
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
-	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
-	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-	apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/intstr"
-	"k8s.io/cli-runtime/pkg/resource"
-	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/fake"
 )
 
 const defaultNamespace = metav1.NamespaceDefault
 
-func Test_ReadyChecker_IsReady_Pod(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		pod     *corev1.Pod
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady Pod",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.Pod{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			pod:     newPodWithCondition("foo", corev1.ConditionTrue),
-			want:    true,
-			wantErr: false,
-		},
-		{
-			name: "IsReady Pod returns error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.Pod{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			pod:     newPodWithCondition("bar", corev1.ConditionTrue),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.CoreV1().Pods(defaultNamespace).Create(context.TODO(), tt.pod, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create Pod error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_Job(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		job     *batchv1.Job
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady Job error while getting job",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &batchv1.Job{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			job:     newJob("bar", 1, intToInt32(1), 1, 0),
-			want:    false,
-			wantErr: true,
-		},
-		{
-			name: "IsReady Job",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &batchv1.Job{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			job:     newJob("foo", 1, intToInt32(1), 1, 0),
-			want:    true,
-			wantErr: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.BatchV1().Jobs(defaultNamespace).Create(context.TODO(), tt.job, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create Job error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_Deployment(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name       string
-		fields     fields
-		args       args
-		replicaSet *appsv1.ReplicaSet
-		deployment *appsv1.Deployment
-		want       bool
-		wantErr    bool
-	}{
-		{
-			name: "IsReady Deployments error while getting current Deployment",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1.Deployment{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			replicaSet: newReplicaSet("foo", 0, 0, true),
-			deployment: newDeployment("bar", 1, 1, 0, true),
-			want:       false,
-			wantErr:    true,
-		},
-		{
-			name: "IsReady Deployments", //TODO fix this one
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1.Deployment{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			replicaSet: newReplicaSet("foo", 0, 0, true),
-			deployment: newDeployment("foo", 1, 1, 0, true),
-			want:       false,
-			wantErr:    false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.AppsV1().Deployments(defaultNamespace).Create(context.TODO(), tt.deployment, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create Deployment error: %v", err)
-				return
-			}
-			if _, err := c.client.AppsV1().ReplicaSets(defaultNamespace).Create(context.TODO(), tt.replicaSet, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create ReplicaSet error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_PersistentVolumeClaim(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		pvc     *corev1.PersistentVolumeClaim
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady PersistentVolumeClaim",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.PersistentVolumeClaim{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			pvc:     newPersistentVolumeClaim("foo", corev1.ClaimPending),
-			want:    false,
-			wantErr: false,
-		},
-		{
-			name: "IsReady PersistentVolumeClaim with error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.PersistentVolumeClaim{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			pvc:     newPersistentVolumeClaim("bar", corev1.ClaimPending),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.CoreV1().PersistentVolumeClaims(defaultNamespace).Create(context.TODO(), tt.pvc, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create PersistentVolumeClaim error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_Service(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		svc     *corev1.Service
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady Service",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.Service{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			svc:     newService("foo", corev1.ServiceSpec{Type: corev1.ServiceTypeLoadBalancer, ClusterIP: ""}),
-			want:    false,
-			wantErr: false,
-		},
-		{
-			name: "IsReady Service with error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.Service{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			svc:     newService("bar", corev1.ServiceSpec{Type: corev1.ServiceTypeExternalName, ClusterIP: ""}),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.CoreV1().Services(defaultNamespace).Create(context.TODO(), tt.svc, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create Service error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_DaemonSet(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		ds      *appsv1.DaemonSet
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady DaemonSet",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1.DaemonSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			ds:      newDaemonSet("foo", 0, 0, 1, 0, true),
-			want:    false,
-			wantErr: false,
-		},
-		{
-			name: "IsReady DaemonSet with error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1.DaemonSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			ds:      newDaemonSet("bar", 0, 1, 1, 1, true),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.AppsV1().DaemonSets(defaultNamespace).Create(context.TODO(), tt.ds, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create DaemonSet error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_StatefulSet(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		ss      *appsv1.StatefulSet
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady StatefulSet",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1beta1.StatefulSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			ss:      newStatefulSet("foo", 1, 0, 0, 1, true),
-			want:    false,
-			wantErr: false,
-		},
-		{
-			name: "IsReady StatefulSet with error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &appsv1beta1.StatefulSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			ss:      newStatefulSet("bar", 1, 0, 1, 1, true),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.AppsV1().StatefulSets(defaultNamespace).Create(context.TODO(), tt.ss, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create StatefulSet error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_ReplicationController(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		rc      *corev1.ReplicationController
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady ReplicationController",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.ReplicationController{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			rc:      newReplicationController("foo", false),
-			want:    false,
-			wantErr: false,
-		},
-		{
-			name: "IsReady ReplicationController with error",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.ReplicationController{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			rc:      newReplicationController("bar", false),
-			want:    false,
-			wantErr: true,
-		},
-		{
-			name: "IsReady ReplicationController and pods not ready for object",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &corev1.ReplicationController{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			rc:      newReplicationController("foo", true),
-			want:    true,
-			wantErr: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			if _, err := c.client.CoreV1().ReplicationControllers(defaultNamespace).Create(context.TODO(), tt.rc, metav1.CreateOptions{}); err != nil {
-				t.Errorf("Failed to create ReplicationController error: %v", err)
-				return
-			}
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_IsReady_ReplicaSet(t *testing.T) {
-	type fields struct {
-		client        kubernetes.Interface
-		log           func(string, ...interface{})
-		checkJobs     bool
-		pausedAsReady bool
-	}
-	type args struct {
-		ctx      context.Context
-		resource *resource.Info
-	}
-	tests := []struct {
-		name    string
-		fields  fields
-		args    args
-		rs      *appsv1.ReplicaSet
-		want    bool
-		wantErr bool
-	}{
-		{
-			name: "IsReady ReplicaSet",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &extensionsv1beta1.ReplicaSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			rs:      newReplicaSet("foo", 1, 1, true),
-			want:    false,
-			wantErr: true,
-		},
-		{
-			name: "IsReady ReplicaSet not ready",
-			fields: fields{
-				client:        fake.NewSimpleClientset(),
-				log:           func(string, ...interface{}) {},
-				checkJobs:     true,
-				pausedAsReady: false,
-			},
-			args: args{
-				ctx:      context.TODO(),
-				resource: &resource.Info{Object: &extensionsv1beta1.ReplicaSet{}, Name: "foo", Namespace: defaultNamespace},
-			},
-			rs:      newReplicaSet("bar", 1, 1, false),
-			want:    false,
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := &ReadyChecker{
-				client:        tt.fields.client,
-				log:           tt.fields.log,
-				checkJobs:     tt.fields.checkJobs,
-				pausedAsReady: tt.fields.pausedAsReady,
-			}
-			//
-			got, err := c.IsReady(tt.args.ctx, tt.args.resource)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("IsReady() error = %v, wantErr %v", err, tt.wantErr)
-			}
-			if got != tt.want {
-				t.Errorf("IsReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
 func Test_ReadyChecker_deploymentReady(t *testing.T) {
 	type args struct {
 		rs  *appsv1.ReplicaSet
@@ -1223,144 +521,6 @@ func Test_ReadyChecker_serviceReady(t *testing.T) {
 	}
 }
 
-func Test_ReadyChecker_crdBetaReady(t *testing.T) {
-	type args struct {
-		crdBeta apiextv1beta1.CustomResourceDefinition
-	}
-	tests := []struct {
-		name string
-		args args
-		want bool
-	}{
-		{
-			name: "crdBeta type is Establish and Conditional is true",
-			args: args{crdBeta: newcrdBetaReady("foo", apiextv1beta1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1beta1.Established,
-						Status: apiextv1beta1.ConditionTrue,
-					},
-				},
-			})},
-			want: true,
-		},
-		{
-			name: "crdBeta type is Establish and Conditional is false",
-			args: args{crdBeta: newcrdBetaReady("foo", apiextv1beta1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1beta1.Established,
-						Status: apiextv1beta1.ConditionFalse,
-					},
-				},
-			})},
-			want: false,
-		},
-		{
-			name: "crdBeta type is NamesAccepted and Conditional is true",
-			args: args{crdBeta: newcrdBetaReady("foo", apiextv1beta1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1beta1.NamesAccepted,
-						Status: apiextv1beta1.ConditionTrue,
-					},
-				},
-			})},
-			want: false,
-		},
-		{
-			name: "crdBeta type is NamesAccepted and Conditional is false",
-			args: args{crdBeta: newcrdBetaReady("foo", apiextv1beta1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1beta1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1beta1.NamesAccepted,
-						Status: apiextv1beta1.ConditionFalse,
-					},
-				},
-			})},
-			want: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := NewReadyChecker(fake.NewSimpleClientset(), nil)
-			got := c.crdBetaReady(tt.args.crdBeta)
-			if got != tt.want {
-				t.Errorf("crdBetaReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_ReadyChecker_crdReady(t *testing.T) {
-	type args struct {
-		crdBeta apiextv1.CustomResourceDefinition
-	}
-	tests := []struct {
-		name string
-		args args
-		want bool
-	}{
-		{
-			name: "crdBeta type is Establish and Conditional is true",
-			args: args{crdBeta: newcrdReady("foo", apiextv1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1.Established,
-						Status: apiextv1.ConditionTrue,
-					},
-				},
-			})},
-			want: true,
-		},
-		{
-			name: "crdBeta type is Establish and Conditional is false",
-			args: args{crdBeta: newcrdReady("foo", apiextv1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1.Established,
-						Status: apiextv1.ConditionFalse,
-					},
-				},
-			})},
-			want: false,
-		},
-		{
-			name: "crdBeta type is NamesAccepted and Conditional is true",
-			args: args{crdBeta: newcrdReady("foo", apiextv1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1.NamesAccepted,
-						Status: apiextv1.ConditionTrue,
-					},
-				},
-			})},
-			want: false,
-		},
-		{
-			name: "crdBeta type is NamesAccepted and Conditional is false",
-			args: args{crdBeta: newcrdReady("foo", apiextv1.CustomResourceDefinitionStatus{
-				Conditions: []apiextv1.CustomResourceDefinitionCondition{
-					{
-						Type:   apiextv1.NamesAccepted,
-						Status: apiextv1.ConditionFalse,
-					},
-				},
-			})},
-			want: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			c := NewReadyChecker(fake.NewSimpleClientset(), nil)
-			got := c.crdReady(tt.args.crdBeta)
-			if got != tt.want {
-				t.Errorf("crdBetaReady() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
 func newStatefulSetWithUpdateRevision(name string, replicas, partition, readyReplicas, updatedReplicas int, updateRevision string, generationInSync bool) *appsv1.StatefulSet {
 	ss := newStatefulSet(name, replicas, partition, readyReplicas, updatedReplicas, generationInSync)
 	ss.Status.UpdateRevision = updateRevision
@@ -1612,28 +772,6 @@ func newService(name string, serviceSpec corev1.ServiceSpec) *corev1.Service {
 	}
 }
 
-func newcrdBetaReady(name string, crdBetaStatus apiextv1beta1.CustomResourceDefinitionStatus) apiextv1beta1.CustomResourceDefinition {
-	return apiextv1beta1.CustomResourceDefinition{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: defaultNamespace,
-		},
-		Spec:   apiextv1beta1.CustomResourceDefinitionSpec{},
-		Status: crdBetaStatus,
-	}
-}
-
-func newcrdReady(name string, crdBetaStatus apiextv1.CustomResourceDefinitionStatus) apiextv1.CustomResourceDefinition {
-	return apiextv1.CustomResourceDefinition{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      name,
-			Namespace: defaultNamespace,
-		},
-		Spec:   apiextv1.CustomResourceDefinitionSpec{},
-		Status: crdBetaStatus,
-	}
-}
-
 func intToInt32(i int) *int32 {
 	i32 := int32(i)
 	return &i32
diff --git a/pkg/lint/rules/chartfile_test.go b/pkg/lint/rules/chartfile_test.go
index f4c836cf7..a06d7dc31 100644
--- a/pkg/lint/rules/chartfile_test.go
+++ b/pkg/lint/rules/chartfile_test.go
@@ -30,13 +30,13 @@ import (
 )
 
 const (
-	badChartNameDir    = "testdata/badchartname"
+	badCharNametDir    = "testdata/badchartname"
 	badChartDir        = "testdata/badchartfile"
 	anotherBadChartDir = "testdata/anotherbadchartfile"
 )
 
 var (
-	badChartNamePath         = filepath.Join(badChartNameDir, "Chart.yaml")
+	badChartNamePath         = filepath.Join(badCharNametDir, "Chart.yaml")
 	badChartFilePath         = filepath.Join(badChartDir, "Chart.yaml")
 	nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
 )
diff --git a/pkg/plugin/plugin_test.go b/pkg/plugin/plugin_test.go
index b81797390..725052346 100644
--- a/pkg/plugin/plugin_test.go
+++ b/pkg/plugin/plugin_test.go
@@ -92,7 +92,6 @@ func TestPlatformPrepareCommand(t *testing.T) {
 				{OperatingSystem: "linux", Architecture: "ppc64le", Command: "echo -n linux-ppc64le"},
 				{OperatingSystem: "linux", Architecture: "s390x", Command: "echo -n linux-s390x"},
 				{OperatingSystem: "linux", Architecture: "riscv64", Command: "echo -n linux-riscv64"},
-				{OperatingSystem: "linux", Architecture: "loong64", Command: "echo -n linux-loong64"},
 				{OperatingSystem: "windows", Architecture: "amd64", Command: "echo -n win-64"},
 			},
 		},
@@ -112,8 +111,6 @@ func TestPlatformPrepareCommand(t *testing.T) {
 		osStrCmp = "linux-s390x"
 	} else if os == "linux" && arch == "riscv64" {
 		osStrCmp = "linux-riscv64"
-	} else if os == "linux" && arch == "loong64" {
-		osStrCmp = "linux-loong64"
 	} else if os == "windows" && arch == "amd64" {
 		osStrCmp = "win-64"
 	} else {
diff --git a/pkg/registry/utils_test.go b/pkg/registry/utils_test.go
index d7aba2bb7..ee78ea76f 100644
--- a/pkg/registry/utils_test.go
+++ b/pkg/registry/utils_test.go
@@ -89,6 +89,7 @@ func setup(suite *TestSuite, tlsEnabled, insecure bool) *registry.Registry {
 		ClientOptWriter(suite.Out),
 		ClientOptCredentialsFile(credentialsFile),
 		ClientOptResolver(nil),
+		ClientOptBasicAuth(testUsername, testPassword),
 	}
 
 	if tlsEnabled {
@@ -128,11 +129,12 @@ func setup(suite *TestSuite, tlsEnabled, insecure bool) *registry.Registry {
 	// This is required because Docker enforces HTTP if the registry
 	// host is localhost/127.0.0.1.
 	suite.DockerRegistryHost = fmt.Sprintf("helm-test-registry:%d", port)
-	suite.srv, _ = mockdns.NewServer(map[string]mockdns.Zone{
+	suite.srv, err = mockdns.NewServer(map[string]mockdns.Zone{
 		"helm-test-registry.": {
 			A: []string{"127.0.0.1"},
 		},
 	}, false)
+	suite.Nil(err, "no error creating mock DNS server")
 	suite.srv.PatchNet(net.DefaultResolver)
 
 	config.HTTP.Addr = fmt.Sprintf(":%d", port)
@@ -349,7 +351,7 @@ func testPull(suite *TestSuite) {
 
 	// full pull with chart and prov
 	result, err := suite.RegistryClient.Pull(ref, PullOptWithProv(true))
-	suite.Nil(err, "no error pulling a chart with prov")
+	suite.Require().Nil(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,