Merge branch 'helm:main' into feature/rollback-description-flag

pull/31580/head
MrJack 1 day ago committed by GitHub
commit 2b239b84e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -12,7 +12,7 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0
- uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.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.'

@ -1,6 +1,7 @@
formatters:
enable:
- gofmt
- gofumpt
- goimports
exclusions:
@ -10,6 +11,10 @@ formatters:
gofmt:
simplify: true
gofumpt:
module-path: helm.sh/helm/v4
extra-rules: false
goimports:
local-prefixes:
- helm.sh/helm/v4

@ -34,7 +34,7 @@ require (
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
github.com/tetratelabs/wazero v1.12.0
go.yaml.in/yaml/v3 v3.0.4
go.yaml.in/yaml/v3 v3.0.5
golang.org/x/crypto v0.54.0
golang.org/x/term v0.45.0
golang.org/x/text v0.40.0

@ -376,8 +376,9 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=

@ -30,14 +30,16 @@ import (
const namespace = "testNamespace"
const badChartDir = "rules/testdata/badchartfile"
const badValuesFileDir = "rules/testdata/badvaluesfile"
const badYamlFileDir = "rules/testdata/albatross"
const badCrdFileDir = "rules/testdata/badcrdfile"
const goodChartDir = "rules/testdata/goodone"
const subChartValuesDir = "rules/testdata/withsubchart"
const malformedTemplate = "rules/testdata/malformed-template"
const invalidChartFileDir = "rules/testdata/invalidchartfile"
const (
badChartDir = "rules/testdata/badchartfile"
badValuesFileDir = "rules/testdata/badvaluesfile"
badYamlFileDir = "rules/testdata/albatross"
badCrdFileDir = "rules/testdata/badcrdfile"
goodChartDir = "rules/testdata/goodone"
subChartValuesDir = "rules/testdata/withsubchart"
malformedTemplate = "rules/testdata/malformed-template"
invalidChartFileDir = "rules/testdata/invalidchartfile"
)
func TestBadChartV3(t *testing.T) {
var values map[string]any

@ -44,8 +44,10 @@ var (
nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
)
var badChart, _ = chartutil.LoadChartfile(badChartFilePath)
var badChartName, _ = chartutil.LoadChartfile(badChartNamePath)
var (
badChart, _ = chartutil.LoadChartfile(badChartFilePath)
badChartName, _ = chartutil.LoadChartfile(badChartNamePath)
)
// Validation functions Test
func TestValidateChartYamlNotDirectory(t *testing.T) {
@ -68,7 +70,7 @@ func TestValidateChartName(t *testing.T) {
}
func TestValidateChartVersion(t *testing.T) {
var failTest = []struct {
failTest := []struct {
Version string
ErrorMsg string
}{
@ -80,7 +82,7 @@ func TestValidateChartVersion(t *testing.T) {
{"1", "'1' is not a valid SemVerV2"},
}
var successTest = []string{"0.0.1", "0.0.1+build", "0.0.1-beta"}
successTest := []string{"0.0.1", "0.0.1+build", "0.0.1-beta"}
for i, test := range failTest {
t.Run(strconv.Itoa(i), func(t *testing.T) {
@ -96,7 +98,7 @@ func TestValidateChartVersion(t *testing.T) {
}
func TestValidateChartMaintainer(t *testing.T) {
var failTest = []struct {
failTest := []struct {
Name string
Email string
ErrorMsg string
@ -106,7 +108,7 @@ func TestValidateChartMaintainer(t *testing.T) {
{"John Snow", "wrongFormatEmail.com", "invalid email"},
}
var successTest = []struct {
successTest := []struct {
Name string
Email string
}{
@ -134,8 +136,8 @@ func TestValidateChartMaintainer(t *testing.T) {
}
func TestValidateChartSources(t *testing.T) {
var failTest = []string{"", "RiverRun", "john@winterfell", "riverrun.io"}
var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"}
failTest := []string{"", "RiverRun", "john@winterfell", "riverrun.io"}
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"}
for _, test := range failTest {
t.Run(test, func(t *testing.T) {
badChart.Sources = []string{test}
@ -166,8 +168,8 @@ func TestValidateChartIconPresence(t *testing.T) {
}
func TestValidateChartIconURL(t *testing.T) {
var failTest = []string{"RiverRun", "john@winterfell", "riverrun.io"}
var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"}
failTest := []string{"RiverRun", "john@winterfell", "riverrun.io"}
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"}
for _, test := range failTest {
t.Run(test, func(t *testing.T) {
badChart.Icon = test

@ -35,11 +35,11 @@ import (
const templateTestBasedir = "./testdata/albatross"
func TestValidateAllowedExtension(t *testing.T) {
var failTest = []string{"/foo", "/test.toml"}
failTest := []string{"/foo", "/test.toml"}
for _, test := range failTest {
require.ErrorContains(t, validateAllowedExtension(test), "Valid extensions are .yaml, .yml, .tpl, or .txt", "validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test)
}
var successTest = []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"}
successTest := []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"}
for _, test := range successTest {
assert.NoError(t, validateAllowedExtension(test), "validateAllowedExtension('%s') to return no error", test)
}
@ -47,8 +47,10 @@ func TestValidateAllowedExtension(t *testing.T) {
var values = map[string]any{"nameOverride": "", "httpPort": 80}
const namespace = "testNamespace"
const strict = false
const (
namespace = "testNamespace"
strict = false
)
func TestTemplateParsing(t *testing.T) {
linter := support.Linter{ChartDir: templateTestBasedir}
@ -59,8 +61,10 @@ func TestTemplateParsing(t *testing.T) {
assert.ErrorContains(t, res[0].Err, "deliberateSyntaxError")
}
var wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml")
var ignoredTemplatePath = filepath.Join(templateTestBasedir, "fail.yaml.ignored")
var (
wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml")
ignoredTemplatePath = filepath.Join(templateTestBasedir, "fail.yaml.ignored")
)
// Test a template with all the existing features:
// namespaces, partial templates
@ -382,6 +386,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) {
}
require.Empty(t, linter.Messages, "Expected 0 lint errors")
}
func TestValidateListAnnotations(t *testing.T) {
md := &k8sYamlStruct{
APIVersion: "v1",

@ -27,7 +27,7 @@ import (
var errLint = errors.New("lint failed")
func TestRunLinterRule(t *testing.T) {
var tests = []struct {
tests := []struct {
Severity int
LintError error
ExpectedMessages int

@ -26,7 +26,6 @@ var ErrHostnameNotProvided = errors.New("no hostname provided")
// Client represents a client capable of communicating with the Monocular API.
type Client struct {
// The base URL for requests
BaseURL string
}

@ -173,7 +173,7 @@ func TestExtract(t *testing.T) {
// Write a tarball to a buffer for us to extract
var tarbuf bytes.Buffer
tw := tar.NewWriter(&tarbuf)
var files = []struct {
files := []struct {
Name, Body string
Mode int64
}{
@ -293,7 +293,7 @@ func TestExtractWithNestedDirectories(t *testing.T) {
// Write a tarball with nested directory structure
var tarbuf bytes.Buffer
tw := tar.NewWriter(&tarbuf)
var files = []struct {
files := []struct {
Name string
Body string
Mode int64

@ -105,6 +105,7 @@ func TestVCSInstallerNonExistentVersion(t *testing.T) {
}
require.EqualErrorf(t, err, fmt.Sprintf("requested version %q does not exist for plugin %q", version, source), "expected error for version does not exists")
}
func TestVCSInstallerUpdate(t *testing.T) {
ensure.HelmHome(t)

@ -216,7 +216,6 @@ func findPlugins(pluginsDirs []string, findFn findFunc, filterFn filterFunc) ([]
var found []Plugin
for _, pluginsDir := range pluginsDirs {
ps, err := findFn(pluginsDir)
if err != nil {
return nil, err
}

@ -154,8 +154,7 @@ func buildLegacyConfig(m MetadataLegacy, pluginType string) Config {
func buildLegacyRuntimeConfig(m MetadataLegacy) RuntimeConfig {
var protocolCommands []SubprocessProtocolCommand
if len(m.Downloaders) > 0 {
protocolCommands =
make([]SubprocessProtocolCommand, 0, len(m.Downloaders))
protocolCommands = make([]SubprocessProtocolCommand, 0, len(m.Downloaders))
for _, d := range m.Downloaders {
protocolCommands = append(protocolCommands, SubprocessProtocolCommand{
Protocols: d.Protocols,

@ -26,8 +26,10 @@ import (
"helm.sh/helm/v4/pkg/provenance"
)
const testKeyFile = "../../pkg/cmd/testdata/helm-test-key.secret"
const testPubFile = "../../pkg/cmd/testdata/helm-test-key.pub"
const (
testKeyFile = "../../pkg/cmd/testdata/helm-test-key.secret"
testPubFile = "../../pkg/cmd/testdata/helm-test-key.pub"
)
const testPluginYAML = `apiVersion: v1
name: test-plugin

@ -22,8 +22,10 @@ import (
type ApplyMethod string
const ApplyMethodClientSideApply ApplyMethod = "csa"
const ApplyMethodServerSideApply ApplyMethod = "ssa"
const (
ApplyMethodClientSideApply ApplyMethod = "csa"
ApplyMethodServerSideApply ApplyMethod = "ssa"
)
// Release describes a deployment of a chart, together with the chart
// and the variables used to deploy that chart.

@ -61,7 +61,8 @@ metadata:
annotations:
"helm.sh/hook": post-install
`,
}, {
},
{
name: []string{"third"},
path: "three",
kind: []string{"ReplicaSet"},
@ -73,7 +74,8 @@ metadata:
annotations:
"helm.sh/hook": no-such-hook
`,
}, {
},
{
name: []string{"fourth"},
path: "four",
kind: []string{"Pod"},
@ -84,7 +86,8 @@ metadata:
name: fourth
annotations:
nothing: here`,
}, {
},
{
name: []string{"fifth"},
path: "five",
kind: []string{"ReplicaSet"},
@ -96,14 +99,16 @@ metadata:
annotations:
"helm.sh/hook": post-delete, post-install
`,
}, {
},
{
// Regression test: files with an underscore in the base name should be skipped.
name: []string{"sixth"},
path: "six/_six",
kind: []string{"ReplicaSet"},
hooks: map[string][]release.HookEvent{"sixth": nil},
manifest: `invalid manifest`, // This will fail if partial is not skipped.
}, {
},
{
// Regression test: files with no content should be skipped.
name: []string{"seventh"},
path: "seven",

@ -126,7 +126,7 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) {
t.Skip("skipping on windows")
}
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible
@ -155,7 +155,7 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) {
t.Skip("skipping on windows")
}
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible
@ -217,7 +217,7 @@ func TestCopyDirFailOpen(t *testing.T) {
t.Skip("skipping on windows")
}
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible
@ -319,7 +319,7 @@ func TestCopyFileFail(t *testing.T) {
t.Skip("skipping on windows")
}
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible
@ -389,7 +389,7 @@ func setupInaccessibleDir(t *testing.T, op func(dir string) error) func() {
}
func TestIsDir(t *testing.T) {
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible
@ -441,7 +441,7 @@ func TestIsDir(t *testing.T) {
}
func TestIsSymlink(t *testing.T) {
var currentUID = os.Getuid()
currentUID := os.Getuid()
if currentUID == 0 {
// Skipping if root, because all files are accessible

@ -19,10 +19,9 @@ package tlsutil
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"os"
"errors"
)
type TLSConfigOptions struct {

@ -546,7 +546,7 @@ func TestMetadata_FormattedDepNames(t *testing.T) {
}
func convertDeps(deps []*chart.Dependency) []ci.Dependency {
var newDeps = make([]ci.Dependency, len(deps))
newDeps := make([]ci.Dependency, len(deps))
for i, c := range deps {
newDeps[i] = c
}

@ -34,7 +34,8 @@ import (
// execHook executes all of the hooks for the given hook event.
func (cfg *Configuration) execHook(rl *release.Release, hook release.HookEvent,
waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption,
timeout time.Duration, serverSideApply bool) error {
timeout time.Duration, serverSideApply bool,
) error {
shutdown, err := cfg.execHookWithDelayedShutdown(rl, hook, waitStrategy, waitOptions, timeout, serverSideApply)
if shutdown == nil {
return err
@ -57,7 +58,8 @@ func shutdownNoOp() error {
// execHookWithDelayedShutdown executes all of the hooks for the given hook event and returns a shutdownHook function to trigger deletions after doing other things like e.g. retrieving logs.
func (cfg *Configuration) execHookWithDelayedShutdown(rl *release.Release, hook release.HookEvent,
waitStrategy kube.WaitStrategy, waitOptions []kube.WaitOption, timeout time.Duration,
serverSideApply bool) (ExecuteShutdownFunc, error) {
serverSideApply bool,
) (ExecuteShutdownFunc, error) {
executingHooks := []*release.Hook{}
for _, h := range rl.Hooks {
@ -176,7 +178,8 @@ 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 {
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" {
@ -210,7 +213,8 @@ 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 {
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

@ -252,7 +252,6 @@ func (*HookFailingKubeClient) Build(reader io.Reader, _ bool) (kube.ResourceList
configMap := &v1.ConfigMap{}
err := yaml.NewYAMLOrJSONDecoder(reader, 1000).Decode(configMap)
if err != nil {
return kube.ResourceList{}, err
}
@ -358,10 +357,12 @@ data:
},
},
},
}, resource.Info{
},
resource.Info{
Name: "build-config-2",
Namespace: "test",
}, []resource.Info{
},
[]resource.Info{
{
// This should be in the record for `before-hook-creation`
Name: "build-config-1",
@ -382,7 +383,8 @@ data:
Name: "build-config-1",
Namespace: "test",
},
}, true,
},
true,
},
}

@ -733,7 +733,6 @@ func writeToFile(outputDir string, name string, data string, appendData bool) er
defer f.Close()
_, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, data)
if err != nil {
return err
}

@ -631,6 +631,7 @@ func TestInstallRelease_Wait(t *testing.T) {
is.Equal(goroutines, instAction.getGoroutineCount())
}
func TestInstallRelease_Wait_Interrupted(t *testing.T) {
is := assert.New(t)
req := require.New(t)
@ -652,9 +653,12 @@ func TestInstallRelease_Wait_Interrupted(t *testing.T) {
req.ErrorContains(err, "context canceled")
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())
// Poll until the background installation goroutine has finished.
is.Eventually(func() bool {
return instAction.getGoroutineCount() == goroutines
}, 30*time.Second, 10*time.Millisecond)
}
func TestInstallRelease_WaitForJobs(t *testing.T) {
is := assert.New(t)
req := require.New(t)
@ -722,6 +726,7 @@ func TestInstallRelease_RollbackOnFailure(t *testing.T) {
is.ErrorContains(err, "an error occurred while uninstalling the release")
})
}
func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) {
is := assert.New(t)
req := require.New(t)
@ -751,9 +756,12 @@ func TestInstallRelease_RollbackOnFailure_Interrupted(t *testing.T) {
req.Error(err)
is.Equal(err, driver.ErrReleaseNotFound)
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())
// Poll until the background installation goroutine has finished.
is.Eventually(func() bool {
return instAction.getGoroutineCount() == goroutines
}, 30*time.Second, 10*time.Millisecond)
}
func TestNameTemplate(t *testing.T) {
testCases := []nameTemplateTestCase{
// Just a straight up nop please

@ -172,7 +172,6 @@ func (l *List) Run() ([]ri.Releaser, error) {
return true
})
if err != nil {
return nil, err
}
@ -264,7 +263,7 @@ func filterLatestReleases(releases []*release.Release) []*release.Release {
latestReleases[key] = rls
}
var list = make([]*release.Release, 0, len(latestReleases))
list := make([]*release.Release, 0, len(latestReleases))
for _, rls := range latestReleases {
list = append(list, rls)
}

@ -107,7 +107,6 @@ func (r *ReleaseTesting) Run(name string) (ri.Releaser, ExecuteShutdownFunc, err
serverSideApply := rel.ApplyMethod == string(release.ApplyMethodServerSideApply)
shutdown, err := r.cfg.execHookWithDelayedShutdown(rel, release.HookTest, kube.StatusWatcherStrategy, r.WaitOptions, r.Timeout, serverSideApply)
if err != nil {
rel.Hooks = append(skippedHooks, rel.Hooks...)
r.cfg.Releases.Update(reli)

@ -249,7 +249,6 @@ func (r *Rollback) performRollback(currentRelease, targetRelease *release.Releas
kube.ClientUpdateOptionServerSideApply(serverSideApply, r.ForceConflicts),
kube.ClientUpdateOptionThreeWayMergeForUnstructured(false),
kube.ClientUpdateOptionUpgradeClientSideFieldManager(true))
if err != nil {
msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err)
r.cfg.Logger().Warn(msg)

@ -77,7 +77,6 @@ func (u *Uninstall) Run(name string) (*releasei.UninstallReleaseResponse, error)
if u.DryRun {
ri, err := u.cfg.releaseContent(name, 0)
if err != nil {
if u.IgnoreNotFound && errors.Is(err, driver.ErrReleaseNotFound) {
return nil, nil

@ -59,6 +59,7 @@ func TestUninstallRelease_ignoreNotFound(t *testing.T) {
is.Nil(res)
is.NoError(err)
}
func TestUninstallRelease_deleteRelease(t *testing.T) {
is := assert.New(t)
req := require.New(t)

@ -85,7 +85,7 @@ func (r *v2Accessor) IsLibraryChart() bool {
}
func (r *v2Accessor) Dependencies() []Charter {
var deps = make([]Charter, len(r.chrt.Dependencies()))
deps := make([]Charter, len(r.chrt.Dependencies()))
for i, c := range r.chrt.Dependencies() {
deps[i] = c
}
@ -93,7 +93,7 @@ func (r *v2Accessor) Dependencies() []Charter {
}
func (r *v2Accessor) MetaDependencies() []Dependency {
var deps = make([]Dependency, len(r.chrt.Metadata.Dependencies))
deps := make([]Dependency, len(r.chrt.Metadata.Dependencies))
for i, c := range r.chrt.Metadata.Dependencies {
deps[i] = c
}
@ -154,7 +154,7 @@ func (r *v3Accessor) IsLibraryChart() bool {
}
func (r *v3Accessor) Dependencies() []Charter {
var deps = make([]Charter, len(r.chrt.Dependencies()))
deps := make([]Charter, len(r.chrt.Dependencies()))
for i, c := range r.chrt.Dependencies() {
deps[i] = c
}
@ -162,7 +162,7 @@ func (r *v3Accessor) Dependencies() []Charter {
}
func (r *v3Accessor) MetaDependencies() []Dependency {
var deps = make([]Dependency, len(r.chrt.Dependencies()))
deps := make([]Dependency, len(r.chrt.Dependencies()))
for i, c := range r.chrt.Metadata.Dependencies {
deps[i] = c
}

@ -47,7 +47,6 @@ var (
panic(fmt.Sprintf("failed to create default capabilities: %v", err))
}
return caps
}()
)

@ -30,14 +30,16 @@ import (
const namespace = "testNamespace"
const badChartDir = "rules/testdata/badchartfile"
const badValuesFileDir = "rules/testdata/badvaluesfile"
const badYamlFileDir = "rules/testdata/albatross"
const badCrdFileDir = "rules/testdata/badcrdfile"
const goodChartDir = "rules/testdata/goodone"
const subChartValuesDir = "rules/testdata/withsubchart"
const malformedTemplate = "rules/testdata/malformed-template"
const invalidChartFileDir = "rules/testdata/invalidchartfile"
const (
badChartDir = "rules/testdata/badchartfile"
badValuesFileDir = "rules/testdata/badvaluesfile"
badYamlFileDir = "rules/testdata/albatross"
badCrdFileDir = "rules/testdata/badcrdfile"
goodChartDir = "rules/testdata/goodone"
subChartValuesDir = "rules/testdata/withsubchart"
malformedTemplate = "rules/testdata/malformed-template"
invalidChartFileDir = "rules/testdata/invalidchartfile"
)
func TestBadChart(t *testing.T) {
var values map[string]any

@ -161,7 +161,6 @@ func validateChartVersion(cf *chart.Metadata) error {
func validateChartVersionStrictSemVerV2(cf *chart.Metadata) error {
_, err := semver.StrictNewVersion(cf.Version)
if err != nil {
return fmt.Errorf("version '%s' is not a valid SemVerV2", cf.Version)
}

@ -42,8 +42,10 @@ var (
nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
)
var badChart, _ = chartutil.LoadChartfile(badChartFilePath)
var badChartName, _ = chartutil.LoadChartfile(badChartNamePath)
var (
badChart, _ = chartutil.LoadChartfile(badChartFilePath)
badChartName, _ = chartutil.LoadChartfile(badChartNamePath)
)
// Validation functions Test
func TestValidateChartYamlNotDirectory(t *testing.T) {
@ -63,7 +65,7 @@ func TestValidateChartName(t *testing.T) {
}
func TestValidateChartVersion(t *testing.T) {
var failTest = []struct {
failTest := []struct {
Version string
ErrorMsg string
}{
@ -73,7 +75,7 @@ func TestValidateChartVersion(t *testing.T) {
{"-3", "'-3' is not a valid SemVer"},
}
var successTest = []string{"0.0.1", "0.0.1+build", "0.0.1-beta"}
successTest := []string{"0.0.1", "0.0.1+build", "0.0.1-beta"}
for _, test := range failTest {
badChart.Version = test.Version
@ -87,7 +89,7 @@ func TestValidateChartVersion(t *testing.T) {
}
func TestValidateChartVersionStrictSemVerV2(t *testing.T) {
var failTest = []struct {
failTest := []struct {
Version string
ErrorMsg string
}{
@ -96,7 +98,7 @@ func TestValidateChartVersionStrictSemVerV2(t *testing.T) {
{"1.1", "version '1.1' is not a valid SemVerV2"},
}
var successTest = []string{"1.1.1", "0.0.1+build", "0.0.1-beta"}
successTest := []string{"1.1.1", "0.0.1+build", "0.0.1-beta"}
for _, test := range failTest {
badChart.Version = test.Version
@ -110,7 +112,7 @@ func TestValidateChartVersionStrictSemVerV2(t *testing.T) {
}
func TestValidateChartMaintainer(t *testing.T) {
var failTest = []struct {
failTest := []struct {
Name string
Email string
ErrorMsg string
@ -120,7 +122,7 @@ func TestValidateChartMaintainer(t *testing.T) {
{"John Snow", "wrongFormatEmail.com", "invalid email"},
}
var successTest = []struct {
successTest := []struct {
Name string
Email string
}{
@ -144,8 +146,8 @@ func TestValidateChartMaintainer(t *testing.T) {
}
func TestValidateChartSources(t *testing.T) {
var failTest = []string{"", "RiverRun", "john@winterfell", "riverrun.io"}
var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"}
failTest := []string{"", "RiverRun", "john@winterfell", "riverrun.io"}
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"}
for _, test := range failTest {
badChart.Sources = []string{test}
require.ErrorContainsf(t, validateChartSources(badChart), "invalid source URL", "validateChartSources(%s) to return \"invalid source URL\", got no error", test)
@ -174,8 +176,8 @@ func TestValidateChartIconPresence(t *testing.T) {
}
func TestValidateChartIconURL(t *testing.T) {
var failTest = []string{"RiverRun", "john@winterfell", "riverrun.io"}
var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"}
failTest := []string{"RiverRun", "john@winterfell", "riverrun.io"}
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"}
for _, test := range failTest {
badChart.Icon = test
require.ErrorContainsf(t, validateChartIconURL(badChart), "invalid icon URL", "validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test)

@ -35,11 +35,11 @@ import (
const templateTestBasedir = "./testdata/albatross"
func TestValidateAllowedExtension(t *testing.T) {
var failTest = []string{"/foo", "/test.toml"}
failTest := []string{"/foo", "/test.toml"}
for _, test := range failTest {
require.ErrorContainsf(t, validateAllowedExtension(test), "Valid extensions are .yaml, .yml, .tpl, or .txt", "validateAllowedExtension('%s') to return \"Valid extensions are .yaml, .yml, .tpl, or .txt\", got no error", test)
}
var successTest = []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"}
successTest := []string{"/foo.yaml", "foo.yaml", "foo.tpl", "/foo/bar/baz.yaml", "NOTES.txt"}
for _, test := range successTest {
assert.NoError(t, validateAllowedExtension(test), "validateAllowedExtension('%s') to return no error", test)
}
@ -62,8 +62,10 @@ func TestTemplateParsing(t *testing.T) {
assert.ErrorContains(t, res[0].Err, "deliberateSyntaxError")
}
var wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml")
var ignoredTemplatePath = filepath.Join(templateTestBasedir, "fail.yaml.ignored")
var (
wrongTemplatePath = filepath.Join(templateTestBasedir, "templates", "fail.yaml")
ignoredTemplatePath = filepath.Join(templateTestBasedir, "fail.yaml.ignored")
)
// Test a template with all the existing features:
// namespaces, partial templates
@ -406,6 +408,7 @@ func TestEmptyWithCommentsManifests(t *testing.T) {
}
require.Empty(t, linter.Messages, "Expected 0 lint errors")
}
func TestValidateListAnnotations(t *testing.T) {
md := &k8sYamlStruct{
APIVersion: "v1",

@ -27,7 +27,7 @@ import (
var errLint = errors.New("lint failed")
func TestRunLinterRule(t *testing.T) {
var tests = []struct {
tests := []struct {
Severity int
LintError error
ExpectedMessages int

@ -182,7 +182,8 @@ func TestLoadFiles_BadCases(t *testing.T) {
Data: []byte(""),
},
},
expectError: "validation: chart.metadata.apiVersion is required"},
expectError: "validation: chart.metadata.apiVersion is required",
},
} {
_, err := LoadFiles(tt.bufferedFiles)
require.Error(t, err, "expected error when load illegal files")

@ -29,6 +29,7 @@ import (
const completionDesc = `
Generate autocompletion scripts for Helm for the specified shell.
`
const bashCompDesc = `
Generate the autocompletion script for Helm for the bash shell.

@ -59,7 +59,6 @@ func TestDependencyBuildCmd(t *testing.T) {
cmd := fmt.Sprintf("dependency build '%s' --repository-config %s --repository-cache %s --plain-http", filepath.Join(rootDir, chartname), repoFile, rootDir)
_, out, err := executeActionCommand(cmd)
// In the first pass, we basically want the same results as an update.
if err != nil {
t.Logf("Output: %s", out)
@ -105,7 +104,6 @@ func TestDependencyBuildCmd(t *testing.T) {
skipRefreshCmd := fmt.Sprintf("dependency build '%s' --skip-refresh --repository-config %s --repository-cache %s --plain-http", filepath.Join(rootDir, chartname), repoFile, rootDir)
_, out, err = executeActionCommand(skipRefreshCmd)
// In this pass, we check --skip-refresh option becomes effective.
if err != nil {
t.Logf("Output: %s", out)
@ -136,7 +134,6 @@ func TestDependencyBuildCmdWithHelmV2Hash(t *testing.T) {
cmd := fmt.Sprintf("dependency build '%s'", chartName)
_, out, err := executeActionCommand(cmd)
// Want to make sure the build can verify Helm v2 hash
if err != nil {
t.Logf("Output: %s", out)

@ -39,16 +39,20 @@ func TestDependencyListCmd(t *testing.T) {
noDependencies.golden = "output/dependency-list-no-requirements-windows.txt"
}
tests := []cmdTestCase{noSuchChart,
noDependencies, {
tests := []cmdTestCase{
noSuchChart,
noDependencies,
{
name: "Dependencies in chart dir",
cmd: "dependency list testdata/testcharts/reqtest",
golden: "output/dependency-list.txt",
}, {
},
{
name: "Dependencies in chart archive",
cmd: "dependency list testdata/testcharts/reqtest-0.1.0.tgz",
golden: "output/dependency-list-archive.txt",
}}
},
}
runTestCmd(t, tests)
}

@ -209,7 +209,6 @@ func TestDependencyUpdateCmd_WithRepoThatWasNotAdded(t *testing.T) {
fmt.Sprintf("dependency update '%s' --repository-config %s --repository-cache %s --content-cache %s", dir(chartname),
dir("repositories.yaml"), dir(), contentCache),
)
if err != nil {
t.Logf("Output: %s", out)
t.Fatal(err)

@ -152,7 +152,6 @@ func bindOutputFlag(cmd *cobra.Command, varRef *output.Format) {
sort.Strings(formatNames)
return formatNames, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -75,7 +75,6 @@ func newGetHooksCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -71,7 +71,6 @@ func newGetManifestCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -66,7 +66,6 @@ func newGetMetadataCmd(cfg *action.Configuration, out io.Writer) *cobra.Command
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -70,7 +70,6 @@ func newGetNotesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -69,7 +69,6 @@ func newGetValuesCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}

@ -221,7 +221,6 @@ type pluginCommand struct {
func loadCompletionForPlugin(pluginCmd *cobra.Command, plug plugin.Plugin) {
// Parse the yaml file providing the plugin's sub-commands and flags
cmds, err := loadFile(plug.Dir() + string(filepath.Separator) + pluginStaticCompletionFile)
if err != nil {
// The file could be missing or invalid. No static completion for this plugin.
slog.Debug("plugin completion file loading", slog.String("error", err.Error()))

@ -97,7 +97,6 @@ func newPullCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
return compVersionFlag(args[0], toComplete)
})
if err != nil {
log.Fatal(err)
}

@ -268,7 +268,8 @@ func runPullTests(t *testing.T, tests []struct {
wantErrorMsg string
expectFile string
expectDir bool
}, outdir string, additionalFlags string) {
}, outdir string, additionalFlags string,
) {
t.Helper()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

@ -73,7 +73,6 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
registryClient, err := newRegistryClient(
out, 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)
}

@ -76,7 +76,7 @@ func TestRepoRemove(t *testing.T) {
assert.Falsef(t, f.Has(testRepoName), "%s was not successfully removed from repositories list", testRepoName)
// Test removal of multiple repos in one go
var testRepoNames = []string{"foo", "bar", "baz"}
testRepoNames := []string{"foo", "bar", "baz"}
cacheFiles := make(map[string][]string, len(testRepoNames))
// Add test repos
@ -151,7 +151,7 @@ func TestRepoRemoveCompletion(t *testing.T) {
repoFile := filepath.Join(rootDir, "repositories.yaml")
repoCache := filepath.Join(rootDir, "cache")
var testRepoNames = []string{"foo", "bar", "baz"}
testRepoNames := []string{"foo", "bar", "baz"}
// Add test repos
for _, repoName := range testRepoNames {

@ -159,7 +159,7 @@ func TestUpdateChartsFailWithError(t *testing.T) {
)
defer ts.Stop()
var invalidURL = ts.URL() + "55"
invalidURL := ts.URL() + "55"
r1, err := repo.NewChartRepository(&repo.Entry{
Name: "charts",
URL: invalidURL,

@ -229,7 +229,6 @@ func newRootCmdWithConfig(actionConfig *action.Configuration, out io.Writer, arg
}
return nil, cobra.ShellCompDirectiveDefault
})
if err != nil {
log.Fatal(err)
}
@ -253,7 +252,6 @@ func newRootCmdWithConfig(actionConfig *action.Configuration, out io.Writer, arg
}
return nil, cobra.ShellCompDirectiveNoFileComp
})
if err != nil {
log.Fatal(err)
}
@ -446,7 +444,6 @@ func newRegistryClientWithTLS(
tlsutil.WithCertKeyPairFiles(certFile, keyFile),
tlsutil.WithCAFile(caFile),
)
if err != nil {
return nil, fmt.Errorf("can't create TLS config for client: %w", err)
}

@ -28,7 +28,7 @@ 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"}}}}]}`
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) {
fmt.Fprintln(w, searchResult)
}))
@ -37,7 +37,7 @@ func TestSearchHubCmd(t *testing.T) {
// The expected output has the URL to the mocked search service in it
// Trailing spaces are necessary to preserve in "expected" as the uitable package adds
// them during printing.
var expected = fmt.Sprintf(`URL CHART VERSION APP VERSION DESCRIPTION
expected := fmt.Sprintf(`URL CHART VERSION APP VERSION DESCRIPTION
%s/charts/stable/phpmyadmin 3.0.0 4.9.0-1 phpMyAdmin is an mysql administration frontend
%s/charts/bitnami/phpmyadmin 3.0.0 4.9.0-1 phpMyAdmin is an mysql administration frontend
`, ts.URL, ts.URL)
@ -51,7 +51,7 @@ 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"}}}}]}`
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) {
fmt.Fprintln(w, searchResult)
}))
@ -60,7 +60,7 @@ func TestSearchHubListRepoCmd(t *testing.T) {
// The expected output has the URL to the mocked search service in it
// Trailing spaces are necessary to preserve in "expected" as the uitable package adds
// them during printing.
var expected = fmt.Sprintf(`URL CHART VERSION APP VERSION DESCRIPTION REPO URL
expected := fmt.Sprintf(`URL CHART VERSION APP VERSION DESCRIPTION REPO URL
%s/charts/stable/phpmyadmin 3.0.0 4.9.0-1 phpMyAdmin is an mysql administration frontend https://charts.helm.sh/stable
%s/charts/bitnami/phpmyadmin 3.0.0 4.9.0-1 phpMyAdmin is an mysql administration frontend https://charts.bitnami.com
`, ts.URL, ts.URL)
@ -96,7 +96,7 @@ func TestSearchHubCmd_FailOnNoResponseTests(t *testing.T) {
wantErr bool
}
var tests = []testCase{
tests := []testCase{
{
name: "Search hub with no results in response",
cmd: `search hub maria`,

@ -61,7 +61,8 @@ func TestSearchRepositoriesCmd(t *testing.T) {
cmd: "search repo syzygy --fail-on-no-result",
golden: "output/search-not-found-error.txt",
wantError: true,
}, {name: "search for 'syzygy' with json output and --fail-on-no-result, expect failure for no results",
}, {
name: "search for 'syzygy' with json output and --fail-on-no-result, expect failure for no results",
cmd: "search repo syzygy --output json --fail-on-no-result",
golden: "output/search-not-found-error.txt",
wantError: true,

@ -205,7 +205,6 @@ func addShowFlags(subCmd *cobra.Command, client *action.Show) {
}
return compVersionFlag(args[0], toComplete)
})
if err != nil {
log.Fatal(err)
}

@ -185,7 +185,8 @@ func TestStatusCompletion(t *testing.T) {
Version: "1.2.3-prerelease",
},
},
}}
},
}
tests := []cmdTestCase{{
name: "completion for status",

@ -254,7 +254,6 @@ func writeToFile(outputDir string, name string, data string, appendData bool) er
defer f.Close()
_, err = fmt.Fprintf(f, "---\n# Source: %s\n%s\n", name, data)
if err != nil {
return err
}

@ -143,9 +143,11 @@ type renderable struct {
basePath string
}
const warnStartDelim = "HELM_ERR_START"
const warnEndDelim = "HELM_ERR_END"
const recursionMaxNums = 1000
const (
warnStartDelim = "HELM_ERR_START"
warnEndDelim = "HELM_ERR_END"
recursionMaxNums = 1000
)
var warnRegex = regexp.MustCompile(warnStartDelim + `((?s).*)` + warnEndDelim)

@ -1278,6 +1278,7 @@ func TestTraceableError_SimpleForm(t *testing.T) {
assert.Equal(t, "error calling include", trace.message, "Expected %q, got %q", errString, trace.message)
}
}
func TestTraceableError_ExecutingForm(t *testing.T) {
testStrings := [][]string{
{"function_not_found/templates/secret.yaml:6:11: executing \"function_not_found/templates/secret.yaml\" at <include \"name\" .>: ", "function_not_found/templates/secret.yaml:6:11"},

@ -130,7 +130,6 @@ func toYAMLPretty(v any) string {
encoder := goYaml.NewEncoder(&data)
encoder.SetIndent(2)
err := encoder.Encode(v)
if err != nil {
// Swallow errors inside of a template.
return ""

@ -147,39 +147,40 @@ keyInElement1 = "valueInElement1"`,
tpl string
expect any
vars any
}{{
tpl: `{{ mustToYaml . }}`,
vars: loopMap,
}, {
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
vars: loopMap,
}, {
tpl: `{{ toJson . }}`,
expect: "", // should return empty string and swallow error
vars: loopMap,
}, {
tpl: `{{ mustToToml . }}`,
vars: map[int]string{1: "one"}, // non-string key is invalid in TOML
}, {
tpl: `{{ mustToToml . }}`,
expect: "foo = \"bar\"\n", // should succeed and return TOML string
vars: map[string]string{"foo": "bar"},
},
}{
{
tpl: `{{ mustToYaml . }}`,
vars: loopMap,
}, {
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
vars: loopMap,
}, {
tpl: `{{ toJson . }}`,
expect: "", // should return empty string and swallow error
vars: loopMap,
}, {
tpl: `{{ mustToToml . }}`,
vars: map[int]string{1: "one"}, // non-string key is invalid in TOML
}, {
tpl: `{{ mustToToml . }}`,
expect: "foo = \"bar\"\n", // should succeed and return TOML string
vars: map[string]string{"foo": "bar"},
},
}
for _, tt := range mustFuncsTests {
@ -368,48 +369,49 @@ func TestDurationHelpers(t *testing.T) {
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),
},
}{
{
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 {

@ -165,7 +165,6 @@ func (g *OCIGetter) newRegistryClient() (*registry.Client, error) {
}
client, err := registry.NewClient(opts...)
if err != nil {
return nil, err
}

@ -19,7 +19,6 @@ import (
"bytes"
"context"
"fmt"
"net/url"
"helm.sh/helm/v4/internal/plugin"

@ -17,7 +17,6 @@ package getter
import (
"context"
"testing"
"time"

@ -127,8 +127,10 @@ const (
FieldValidationDirectiveStrict FieldValidationDirective = "Strict"
)
type CreateApplyFunc func(target *resource.Info) error
type UpdateApplyFunc func(original, target *resource.Info) error
type (
CreateApplyFunc func(target *resource.Info) error
UpdateApplyFunc func(original, target *resource.Info) error
)
func init() {
// Add CRDs to the scheme. They are missing by default.

@ -2260,7 +2260,8 @@ metadata:
}
func createManifest(t *testing.T, manifest string,
fakeMapper meta.RESTMapper, fakeClient *dynamicfake.FakeDynamicClient) {
fakeMapper meta.RESTMapper, fakeClient *dynamicfake.FakeDynamicClient,
) {
t.Helper()
m := make(map[string]any)

@ -28,8 +28,10 @@ import (
"k8s.io/client-go/kubernetes/scheme"
)
var k8sNativeScheme *runtime.Scheme
var k8sNativeSchemeOnce sync.Once
var (
k8sNativeScheme *runtime.Scheme
k8sNativeSchemeOnce sync.Once
)
// AsVersioned converts the given info into a runtime.Object with the correct
// group and version set
@ -41,7 +43,7 @@ func AsVersioned(info *resource.Info) runtime.Object {
// RESTMapping. If no mapping is provided, the default schema versioner is used
func convertWithMapper(obj runtime.Object, mapping *meta.RESTMapping) runtime.Object {
s := kubernetesNativeScheme()
var gv = runtime.GroupVersioner(schema.GroupVersions(s.PrioritizedVersionsAllGroups()))
gv := runtime.GroupVersioner(schema.GroupVersions(s.PrioritizedVersionsAllGroups()))
if mapping != nil {
gv = mapping.GroupVersionKind.GroupVersion()
}

@ -218,7 +218,6 @@ func (s *Signatory) ClearSign(archiveData []byte, filename string, metadataBytes
}
_, err = io.Copy(w, b)
if err != nil {
// NB: We intentionally don't call `w.Close()` here! `w.Close()` is the method which
// actually does the PGP signing, and therefore is the part which uses the private key.

@ -329,7 +329,6 @@ func ensureTLSConfig(client *auth.Client, setConfig *tls.Config) (*tls.Config, e
func LoginOptInsecure(insecure bool) LoginOption {
return func(o *loginOperation) {
tlsConfig, err := ensureTLSConfig(o.client.authorizer, nil)
if err != nil {
panic(err)
}
@ -909,7 +908,8 @@ func (c *Client) ValidateReference(ref, version string, u *url.URL) (string, *ur
// tagManifest prepares and tags a manifest in memory storage
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) {
ociAnnotations map[string]string, parsedRef reference,
) (ocispec.Descriptor, error) {
manifest := ocispec.Manifest{
Versioned: specs.Versioned{SchemaVersion: 2},
Config: configDescriptor,

@ -40,6 +40,7 @@ func (suite *RegistryScopeTestSuite) SetupSuite() {
// when the registry itself was reached over https.
setup(&suite.TestRegistry, false, false, "token")
}
func (suite *RegistryScopeTestSuite) TearDownSuite() {
teardown(&suite.TestRegistry)
os.RemoveAll(suite.WorkspaceDir)

@ -77,7 +77,7 @@ func (a *v1Accessor) Version() int {
}
func (a *v1Accessor) Hooks() []Hook {
var hooks = make([]Hook, len(a.rel.Hooks))
hooks := make([]Hook, len(a.rel.Hooks))
for i, h := range a.rel.Hooks {
hooks[i] = h
}
@ -141,7 +141,7 @@ func (a *v2Accessor) Version() int {
}
func (a *v2Accessor) Hooks() []Hook {
var hooks = make([]Hook, len(a.rel.Hooks))
hooks := make([]Hook, len(a.rel.Hooks))
for i, h := range a.rel.Hooks {
hooks[i] = h
}

@ -22,8 +22,10 @@ import (
type ApplyMethod string
const ApplyMethodClientSideApply ApplyMethod = "csa"
const ApplyMethodServerSideApply ApplyMethod = "ssa"
const (
ApplyMethodClientSideApply ApplyMethod = "csa"
ApplyMethodServerSideApply ApplyMethod = "ssa"
)
// Release describes a deployment of a chart, together with the chart
// and the variables used to deploy that chart.

@ -61,7 +61,8 @@ metadata:
annotations:
"helm.sh/hook": post-install
`,
}, {
},
{
name: []string{"third"},
path: "three",
kind: []string{"ReplicaSet"},
@ -73,7 +74,8 @@ metadata:
annotations:
"helm.sh/hook": no-such-hook
`,
}, {
},
{
name: []string{"fourth"},
path: "four",
kind: []string{"Pod"},
@ -84,7 +86,8 @@ metadata:
name: fourth
annotations:
nothing: here`,
}, {
},
{
name: []string{"fifth"},
path: "five",
kind: []string{"ReplicaSet"},
@ -96,14 +99,16 @@ metadata:
annotations:
"helm.sh/hook": post-delete, post-install
`,
}, {
},
{
// Regression test: files with an underscore in the base name should be skipped.
name: []string{"sixth"},
path: "six/_six",
kind: []string{"ReplicaSet"},
hooks: map[string][]release.HookEvent{"sixth": nil},
manifest: `invalid manifest`, // This will fail if partial is not skipped.
}, {
},
{
// Regression test: files with no content should be skipped.
name: []string{"seventh"},
path: "seven",

@ -424,7 +424,6 @@ func TestIndexAdd(t *testing.T) {
baseURL string
digest string
}{
{&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"},
{&chart.Metadata{APIVersion: "v2", Name: "alpine", Version: "0.1.0"}, "/home/charts/alpine-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"},
{&chart.Metadata{APIVersion: "v2", Name: "deis", Version: "0.1.0"}, "/home/charts/deis-0.1.0.tgz", "http://example.com/charts/", "sha256:1234567890"},
@ -536,6 +535,7 @@ entries:
home: https://github.com/something/else
digest: "sha256:1234567890abcdef"
`
var indexWithDuplicatesInLastChartDeps = `
apiVersion: v1
entries:

@ -137,15 +137,17 @@ func TestUpdateRepository(t *testing.T) {
},
)
newRepoName := "sample"
sampleRepository.Update(&Entry{Name: newRepoName,
URL: "https://example.com/sample",
sampleRepository.Update(&Entry{
Name: newRepoName,
URL: "https://example.com/sample",
})
assert.Truef(t, sampleRepository.Has(newRepoName), "expected repository %s not found", newRepoName)
repoCount := len(sampleRepository.Repositories)
sampleRepository.Update(&Entry{Name: newRepoName,
URL: "https://example.com/sample",
sampleRepository.Update(&Entry{
Name: newRepoName,
URL: "https://example.com/sample",
})
assert.Lenf(t, sampleRepository.Repositories, repoCount, "invalid number of repositories found %d, expected number of repositories %d", len(sampleRepository.Repositories), repoCount)

@ -23,7 +23,7 @@ import (
)
func TestLabelsMatch(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
set1 labels
set2 labels

@ -34,7 +34,7 @@ func TestMemoryName(t *testing.T) {
}
func TestMemoryCreate(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
rls *rspb.Release
err bool
@ -76,7 +76,7 @@ func TestMemoryCreate(t *testing.T) {
}
func TestMemoryGet(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
key string
namespace string
@ -133,7 +133,7 @@ func TestMemoryList(t *testing.T) {
}
func TestMemoryQuery(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
xlen int
namespace string
@ -164,7 +164,7 @@ func TestMemoryQuery(t *testing.T) {
}
func TestMemoryUpdate(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
key string
rls *rspb.Release
@ -215,7 +215,7 @@ func TestMemoryUpdate(t *testing.T) {
}
func TestMemoryDelete(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
key string
namespace string

@ -31,7 +31,7 @@ func TestRecordsAdd(t *testing.T) {
newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)),
})
var tests = []struct {
tests := []struct {
desc string
key string
ok bool
@ -62,7 +62,7 @@ func TestRecordsAdd(t *testing.T) {
}
func TestRecordsRemove(t *testing.T) {
var tests = []struct {
tests := []struct {
desc string
key string
ok bool
@ -112,7 +112,7 @@ func TestRecordsGet(t *testing.T) {
newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)),
})
var tests = []struct {
tests := []struct {
desc string
key string
rec *record
@ -141,7 +141,7 @@ func TestRecordsIndex(t *testing.T) {
newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)),
})
var tests = []struct {
tests := []struct {
desc string
key string
sort int
@ -170,7 +170,7 @@ func TestRecordsExists(t *testing.T) {
newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)),
})
var tests = []struct {
tests := []struct {
desc string
key string
ok bool
@ -199,7 +199,7 @@ func TestRecordsReplace(t *testing.T) {
newRecord("rls-a.v2", releaseStub("rls-a", 2, "default", common.StatusDeployed)),
})
var tests = []struct {
tests := []struct {
desc string
key string
rec *record

@ -53,8 +53,10 @@ const postgreSQLDialect = "postgres"
// SQLDriverName is the string name of this driver.
const SQLDriverName = "SQL"
const sqlReleaseTableName = "releases_v1"
const sqlCustomLabelsTableName = "custom_labels_v1"
const (
sqlReleaseTableName = "releases_v1"
sqlCustomLabelsTableName = "custom_labels_v1"
)
const (
sqlReleaseTableKeyColumn = "key"
@ -359,7 +361,7 @@ func (s *SQL) List(filter func(release.Releaser) bool) ([]release.Releaser, erro
return nil, err
}
var records = []SQLReleaseWrapper{}
records := []SQLReleaseWrapper{}
if err := s.db.Select(&records, query, args...); err != nil {
s.Logger().Debug("failed to list", slog.Any("error", err))
return nil, err
@ -424,7 +426,7 @@ func (s *SQL) Query(labels map[string]string) ([]release.Releaser, error) {
return nil, err
}
var records = []SQLReleaseWrapper{}
records := []SQLReleaseWrapper{}
if err := s.db.Select(&records, query, args...); err != nil {
s.Logger().Debug("failed to query with labels", slog.Any("error", err))
return nil, err
@ -556,7 +558,6 @@ func (s *SQL) Create(key string, rel release.Releaser) error {
k,
v,
).ToSql()
if err != nil {
defer transaction.Rollback()
s.Logger().Debug("failed to build insert query", slog.Any("error", err))
@ -603,7 +604,6 @@ func (s *SQL) Update(key string, rel release.Releaser) error {
Where(sq.Eq{sqlReleaseTableKeyColumn: key}).
Where(sq.Eq{sqlReleaseTableNamespaceColumn: namespace}).
ToSql()
if err != nil {
s.Logger().Debug("failed to build update query", slog.Any("error", err))
return err
@ -681,7 +681,6 @@ func (s *SQL) Delete(key string) (release.Releaser, error) {
Where(sq.Eq{sqlCustomLabelsTableReleaseKeyColumn: key}).
Where(sq.Eq{sqlCustomLabelsTableReleaseNamespaceColumn: s.namespace}).
ToSql()
if err != nil {
s.Logger().Debug("failed to build delete Labels query", slog.Any("error", err))
return nil, err
@ -695,14 +694,16 @@ func (s *SQL) getReleaseCustomLabels(key string, _ string) (map[string]string, e
query, args, err := s.statementBuilder.
Select(sqlCustomLabelsTableKeyColumn, sqlCustomLabelsTableValueColumn).
From(sqlCustomLabelsTableName).
Where(sq.Eq{sqlCustomLabelsTableReleaseKeyColumn: key,
sqlCustomLabelsTableReleaseNamespaceColumn: s.namespace}).
Where(sq.Eq{
sqlCustomLabelsTableReleaseKeyColumn: key,
sqlCustomLabelsTableReleaseNamespaceColumn: s.namespace,
}).
ToSql()
if err != nil {
return nil, err
}
var labelsList = []SQLReleaseCustomLabelWrapper{}
labelsList := []SQLReleaseCustomLabelWrapper{}
if err := s.db.Select(&labelsList, query, args...); err != nil {
return nil, err
}

@ -38,7 +38,7 @@ func TestIsSystemLabel(t *testing.T) {
}
func TestFilterSystemLabels(t *testing.T) {
var tests = [][2]map[string]string{
tests := [][2]map[string]string{
{nil, map[string]string{}},
{map[string]string{}, map[string]string{}},
{map[string]string{
@ -73,7 +73,7 @@ func TestFilterSystemLabels(t *testing.T) {
}
func TestContainsSystemLabels(t *testing.T) {
var tests = []struct {
tests := []struct {
input map[string]string
output bool
}{

@ -137,7 +137,7 @@ func TestStorageList(t *testing.T) {
require.NoError(t, storage.Create(rls6), "Storing release 'rls6'")
}
var listTests = []struct {
listTests := []struct {
Description string
NumExpected int
ListFunc func() ([]release.Releaser, error)
@ -263,24 +263,31 @@ type MaxHistoryMockDriver struct {
func NewMaxHistoryMockDriver(d driver.Driver) *MaxHistoryMockDriver {
return &MaxHistoryMockDriver{Driver: d}
}
func (d *MaxHistoryMockDriver) Create(key string, rls release.Releaser) error {
return d.Driver.Create(key, rls)
}
func (d *MaxHistoryMockDriver) Update(key string, rls release.Releaser) error {
return d.Driver.Update(key, rls)
}
func (d *MaxHistoryMockDriver) Delete(_ string) (release.Releaser, error) {
return nil, errMaxHistoryMockDriverSomethingHappened
}
func (d *MaxHistoryMockDriver) Get(key string) (release.Releaser, error) {
return d.Driver.Get(key)
}
func (d *MaxHistoryMockDriver) List(filter func(release.Releaser) bool) ([]release.Releaser, error) {
return d.Driver.List(filter)
}
func (d *MaxHistoryMockDriver) Query(labels map[string]string) ([]release.Releaser, error) {
return d.Driver.Query(labels)
}
func (d *MaxHistoryMockDriver) Name() string {
return d.Driver.Name()
}

@ -316,7 +316,8 @@ func TestParseLiteralInto(t *testing.T) {
"outer": map[string]any{
"inner1": "value1,outer.inner3=value3,outer.inner4=4",
"inner2": "value2",
}},
},
},
err: false,
},
{

@ -439,7 +439,8 @@ func TestParseInto(t *testing.T) {
"inner2": "value2",
"inner3": "value3",
"inner4": 4,
}},
},
},
err: false,
},
{

@ -114,12 +114,15 @@ verifySupported() {
checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL
local latest_release_url="https://get.helm.sh/helm3-latest-version"
# Cache behavior is provider-specific, so this mitigation is best effort.
# The current CDN does not revalidate on the request no-cache directive,
# so use a unique query while retaining no-cache for compliant intermediaries.
local latest_release_url="https://get.helm.sh/helm3-latest-version?ts=$(date +%s)"
local latest_release_response=""
if [ "${HAS_CURL}" == "true" ]; then
latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true )
latest_release_response=$( curl -L --silent --show-error --fail --header "Cache-Control: no-cache" "$latest_release_url" 2>&1 || true )
elif [ "${HAS_WGET}" == "true" ]; then
latest_release_response=$( wget "$latest_release_url" -q -O - 2>&1 || true )
latest_release_response=$( wget "$latest_release_url" --header="Cache-Control: no-cache" -q -O - 2>&1 || true )
fi
TAG=$( echo "$latest_release_response" | grep '^v[0-9]' )
if [ "x$TAG" == "x" ]; then

@ -114,12 +114,15 @@ verifySupported() {
checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL
local latest_release_url="https://get.helm.sh/helm4-latest-version"
# Cache behavior is provider-specific, so this mitigation is best effort.
# The current CDN does not revalidate on the request no-cache directive,
# so use a unique query while retaining no-cache for compliant intermediaries.
local latest_release_url="https://get.helm.sh/helm4-latest-version?ts=$(date +%s)"
local latest_release_response=""
if [ "${HAS_CURL}" == "true" ]; then
latest_release_response=$( curl -L --silent --show-error --fail "$latest_release_url" 2>&1 || true )
latest_release_response=$( curl -L --silent --show-error --fail --header "Cache-Control: no-cache" "$latest_release_url" 2>&1 || true )
elif [ "${HAS_WGET}" == "true" ]; then
latest_release_response=$( wget "$latest_release_url" -q -O - 2>&1 || true )
latest_release_response=$( wget "$latest_release_url" --header="Cache-Control: no-cache" -q -O - 2>&1 || true )
fi
TAG=$( echo "$latest_release_response" | grep '^v[0-9]' )
if [ "x$TAG" == "x" ]; then

Loading…
Cancel
Save