Merge pull request #32577 from mattfarina/bump-go-1.27

Updating the Go version
pull/32009/merge
Matt Farina 2 weeks ago committed by GitHub
commit d2de64e64b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

4
.github/env vendored

@ -1,2 +1,2 @@
GOLANG_VERSION=1.26
GOLANGCI_LINT_VERSION=v2.12.2
GOLANG_VERSION=1.27
GOLANGCI_LINT_VERSION=v2.13.1

@ -42,8 +42,7 @@ func main() {
}
if err := cmd.Execute(); err != nil {
var cerr helmcmd.CommandError
if errors.As(err, &cerr) {
if cerr, ok := errors.AsType[helmcmd.CommandError](err); ok {
os.Exit(cerr.ExitCode)
}
os.Exit(1)

@ -123,7 +123,7 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
}
fname := strings.TrimPrefix(f.Name, "charts/")
cname := strings.SplitN(fname, "/", 2)[0]
cname, _, _ := strings.Cut(fname, "/")
if slices.Index(subChartsKeys, cname) == -1 {
subChartsKeys = append(subChartsKeys, cname)
}

@ -46,7 +46,6 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
if c != "" {
// retrieve value
vv, err := cvals.PathValue(cpath + c)
var errNoValue common.ErrNoValue
if err == nil {
// if not bool, warn
if bv, ok := vv.(bool); ok {
@ -54,7 +53,7 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
break
}
slog.Warn("returned non-bool value", "path", c, "chart", r.Name)
} else if errors.As(err, &errNoValue) {
} else if _, ok := errors.AsType[common.ErrNoValue](err); ok {
// this is a real error
slog.Warn("the method PathValue returned error", slog.Any("error", err))
}

@ -42,4 +42,4 @@ into a Chart.
When creating charts in memory, use the 'helm.sh/helm/pkg/chart'
package directly.
*/
package util // import "helm.sh/helm/v4/internal/chart/v3/util"
package util

@ -231,13 +231,10 @@ func TestSaveDir(t *testing.T) {
}
func TestRepeatableSave(t *testing.T) {
tmp := t.TempDir()
defer os.RemoveAll(tmp)
modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC)
tests := []struct {
name string
chart *chart.Chart
want string
}{
{
name: "Package 1 file",
@ -258,7 +255,6 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime,
},
want: "5bfea18cc3c8cbc265744bc32bffa9489a4dbe87d6b51b90f4255e4839d35e03",
},
{
name: "Package 2 files",
@ -280,20 +276,26 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime,
},
want: "a240365c21e0a2f4a57873132a9b686566a612d08bcb3f20c9446bfff005ccce",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// create package
dest := path.Join(tmp, "newdir")
where, err := Save(test.chart, dest)
// Package the same chart twice, into separate directories so the
// second Save does not simply overwrite the first.
first, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
second, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
// get shasum for package
result, err := sha256Sum(where)
firstSum, err := sha256Sum(first)
require.NoError(t, err, "Failed to check shasum")
// assert that the package SHA is what we wanted.
assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want)
secondSum, err := sha256Sum(second)
require.NoError(t, err, "Failed to check shasum")
// Packaging a chart must be reproducible. The digest itself is not
// pinned here because the bytes depend on the compression
// implementation of the Go release Helm is built with.
assert.Equal(t, firstSum, secondSum, "Save() is not repeatable")
})
}
}

@ -41,7 +41,7 @@ func TestUnmarshaConfig(t *testing.T) {
ShortHelp: "short help string",
LongHelp: "long help string",
IgnoreFlags: true,
}, *(config.(*schema.ConfigCLIV1)))
}, *config.(*schema.ConfigCLIV1))
}
// Test unmarshalling invalid config data

@ -74,7 +74,7 @@ func (r *RuntimeSubprocess) CreatePlugin(pluginDir string, metadata *Metadata) (
return &SubprocessPluginRuntime{
metadata: *metadata,
pluginDir: pluginDir,
RuntimeConfig: *(metadata.RuntimeConfig.(*RuntimeConfigSubprocess)),
RuntimeConfig: *metadata.RuntimeConfig.(*RuntimeConfigSubprocess),
EnvVars: maps.Clone(r.EnvVars),
}, nil
}
@ -153,8 +153,7 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
slog.Debug("executing plugin hook command", slog.String("pluginName", r.metadata.Name), slog.String("command", cmd.String()))
if err := cmd.Run(); err != nil {
var eerr *exec.ExitError
if errors.As(err, &eerr) {
if eerr, ok := errors.AsType[*exec.ExitError](err); ok {
os.Stderr.Write(eerr.Stderr)
return fmt.Errorf("plugin %s hook for %q exited with error", event, r.metadata.Name)
}
@ -168,8 +167,7 @@ func (r *SubprocessPluginRuntime) InvokeHook(event string) error {
// then replace the other three with a call to this func
func executeCmd(prog *exec.Cmd, pluginName string) error {
if err := prog.Run(); err != nil {
var eerr *exec.ExitError
if errors.As(err, &eerr) {
if eerr, ok := errors.AsType[*exec.ExitError](err); ok {
slog.Debug(
"plugin execution failed",
slog.String("pluginName", pluginName),

@ -42,7 +42,7 @@ func getProtocolCommand(commands []SubprocessProtocolCommand, protocol string) *
// TODO can we replace a lot of this func with RuntimeSubprocess.invokeWithEnv?
func (r *SubprocessPluginRuntime) runGetter(ctx context.Context, input *Input) (*Output, error) {
msg, ok := (input.Message).(schema.InputMessageGetterV1)
msg, ok := input.Message.(schema.InputMessageGetterV1)
if !ok {
return nil, fmt.Errorf("expected input type schema.InputMessageGetterV1, got %T", input)
}

@ -136,11 +136,11 @@ func IsRollingUpdate(deployment *apps.Deployment) bool {
// MaxUnavailable returns the maximum unavailable pods a rolling deployment can take.
func MaxUnavailable(deployment apps.Deployment) int32 {
if !IsRollingUpdate(&deployment) || *(deployment.Spec.Replicas) == 0 {
if !IsRollingUpdate(&deployment) || *deployment.Spec.Replicas == 0 {
return int32(0)
}
// Error caught by validation
_, maxUnavailable, _ := ResolveFenceposts(deployment.Spec.Strategy.RollingUpdate.MaxSurge, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable, *(deployment.Spec.Replicas))
_, maxUnavailable, _ := ResolveFenceposts(deployment.Spec.Strategy.RollingUpdate.MaxSurge, deployment.Spec.Strategy.RollingUpdate.MaxUnavailable, *deployment.Spec.Replicas)
if maxUnavailable > *deployment.Spec.Replicas {
return *deployment.Spec.Replicas
}

@ -17,14 +17,20 @@ limitations under the License.
package version
import (
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestK8sClientGoModVersion(t *testing.T) {
// Unfortunately, test builds don't include debug info / module info
// So we expect "K8sIOClientGoModVersion" to return error
_, err := K8sIOClientGoModVersion()
// Whether module info is embedded in a test binary depends on the Go
// release: builds before Go 1.27 omit it, so the lookup fails. Accept
// either outcome, but require that a successful lookup returns a version.
v, err := K8sIOClientGoModVersion()
if err != nil {
require.ErrorContains(t, err, "k8s.io/client-go not found in build info")
return
}
require.True(t, strings.HasPrefix(v, "v"), "expected a semver-like version, got %q", v)
}

@ -153,7 +153,7 @@ func LoadFiles(files []*archive.BufferedFile) (*chart.Chart, error) {
}
fname := strings.TrimPrefix(f.Name, "charts/")
cname := strings.SplitN(fname, "/", 2)[0]
cname, _, _ := strings.Cut(fname, "/")
subcharts[cname] = append(subcharts[cname], &archive.BufferedFile{Name: fname, ModTime: f.ModTime, Data: f.Data})
default:
c.Files = append(c.Files, &common.File{Name: f.Name, ModTime: f.ModTime, Data: f.Data})

@ -46,7 +46,6 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
if c != "" {
// retrieve value
vv, err := cvals.PathValue(cpath + c)
var errNoValue common.ErrNoValue
if err == nil {
// if not bool, warn
if bv, ok := vv.(bool); ok {
@ -54,7 +53,7 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals common.Values,
break
}
slog.Warn("returned non-bool value", "path", c, "chart", r.Name)
} else if !errors.As(err, &errNoValue) {
} else if _, ok := errors.AsType[common.ErrNoValue](err); !ok {
// this is a real error
slog.Warn("the method PathValue returned error", slog.Any("error", err))
}

@ -42,4 +42,4 @@ into a Chart.
When creating charts in memory, use the 'helm.sh/helm/pkg/chart'
package directly.
*/
package util // import "helm.sh/helm/v4/pkg/chart/v2/util"
package util

@ -298,13 +298,10 @@ func TestSaveDir(t *testing.T) {
}
func TestRepeatableSave(t *testing.T) {
tmp := t.TempDir()
defer os.RemoveAll(tmp)
modTime := time.Date(2021, 9, 1, 20, 34, 58, 651387237, time.UTC)
tests := []struct {
name string
chart *chart.Chart
want string
}{
{
name: "Package 1 file",
@ -325,7 +322,6 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime,
},
want: "63358874b93ea095c857cd66bcf5d0a4464840cf84a07547db744d81d6c5af59",
},
{
name: "Package 2 files",
@ -347,20 +343,26 @@ func TestRepeatableSave(t *testing.T) {
Schema: []byte("{\n \"title\": \"Values\"\n}"),
SchemaModTime: modTime,
},
want: "c2a43990053da788ad4e260d3b00d52a0b103ccc67ab9f48278a7b6dcfb2a4bd",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// create package
dest := path.Join(tmp, "newdir")
where, err := Save(test.chart, dest)
// Package the same chart twice, into separate directories so the
// second Save does not simply overwrite the first.
first, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
second, err := Save(test.chart, t.TempDir())
require.NoError(t, err, "Failed to save")
// get shasum for package
result, err := sha256Sum(where)
firstSum, err := sha256Sum(first)
require.NoError(t, err, "Failed to check shasum")
// assert that the package SHA is what we wanted.
assert.Equal(t, test.want, result, "FormatName() result = %v, want %v", result, test.want)
secondSum, err := sha256Sum(second)
require.NoError(t, err, "Failed to check shasum")
// Packaging a chart must be reproducible. The digest itself is not
// pinned here because the bytes depend on the compression
// implementation of the Go release Helm is built with.
assert.Equal(t, firstSum, secondSum, "Save() is not repeatable")
})
}
}

@ -83,8 +83,7 @@ func newDependencyBuildCmd(out io.Writer) *cobra.Command {
man.Verify = downloader.VerifyIfPossible
}
err = man.Build()
var e downloader.ErrRepoNotFound
if errors.As(err, &e) {
if e, ok := errors.AsType[downloader.ErrRepoNotFound](err); ok {
return fmt.Errorf("%s. Please add the missing repos via 'helm repo add'", e.Error())
}
return err

@ -482,8 +482,7 @@ func reformatExecErrorMsg(filename string, err error) error {
// If it can parse out details from that error message such as the line number, template it failed on,
// and error description, then it will construct a new error that displays these details in a structured way.
// If there are issues with parsing the error message, the err passed into the function should return instead.
var execError template.ExecError
if !errors.As(err, &execError) {
if _, ok := errors.AsType[template.ExecError](err); !ok {
return err
}

@ -447,7 +447,7 @@ func verifyInsecureSkipVerify(t *testing.T, g *HTTPGetter, caseName string, expe
require.NoError(t, err)
require.NotNil(t, returnVal, "Expected non nil value for http client")
transport := (returnVal.Transport).(*http.Transport)
transport := returnVal.Transport.(*http.Transport)
gotValue := false
if transport.TLSClientConfig != nil {
gotValue = transport.TLSClientConfig.InsecureSkipVerify
@ -465,7 +465,7 @@ func TestDefaultHTTPTransportReuse(t *testing.T) {
require.NotNil(t, httpClient1, "Expected non nil value for http client")
transport1 := (httpClient1.Transport).(*http.Transport)
transport1 := httpClient1.Transport.(*http.Transport)
httpClient2, err := g.httpClient(g.opts)
@ -473,7 +473,7 @@ func TestDefaultHTTPTransportReuse(t *testing.T) {
require.NotNil(t, httpClient2, "Expected non nil value for http client")
transport2 := (httpClient2.Transport).(*http.Transport)
transport2 := httpClient2.Transport.(*http.Transport)
require.Equal(t, transport2, transport1, "Expected default transport to be reused")
}
@ -489,7 +489,7 @@ func TestHTTPTransportOption(t *testing.T) {
require.NotNil(t, httpClient1, "Expected non nil value for http client")
transport1 := (httpClient1.Transport).(*http.Transport)
transport1 := httpClient1.Transport.(*http.Transport)
require.Equal(t, transport, transport1, "Expected transport option to be applied")
@ -499,7 +499,7 @@ func TestHTTPTransportOption(t *testing.T) {
require.NotNil(t, httpClient2, "Expected non nil value for http client")
transport2 := (httpClient2.Transport).(*http.Transport)
transport2 := httpClient2.Transport.(*http.Transport)
require.Equal(t, transport2, transport1, "Expected applied transport to be reused")

@ -79,7 +79,6 @@ func newPodWithStatus(name string, status v1.PodStatus, namespace string) v1.Pod
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: ns,
SelfLink: "/api/v1/namespaces/default/pods/" + name,
},
Spec: v1.PodSpec{
Containers: []v1.Container{{

@ -231,7 +231,7 @@ type (
// Returns true if the host contains a path component (i.e., contains a '/').
func warnIfHostHasPath(host string) bool {
if strings.Contains(host, "/") {
registryHost := strings.Split(host, "/")[0]
registryHost, _, _ := strings.Cut(host, "/")
slog.Warn("registry login currently only supports registry hostname, not a repository path", "host", host, "suggested", registryHost)
return true
}
@ -322,6 +322,11 @@ func ensureTLSConfig(client *auth.Client, setConfig *tls.Config) (*tls.Config, e
transport.TLSClientConfig = &tls.Config{}
}
// Idle connections were established under the previous TLS configuration.
// Drop them so the settings being applied here take effect on the next
// request instead of being bypassed by a pooled connection.
transport.CloseIdleConnections()
return transport.TLSClientConfig, nil
}

@ -216,6 +216,19 @@ func (srv *OCIServer) RunWithReturn(t *testing.T, opts ...OCIServerOpt) *OCIServ
go srv.ListenAndServe()
// NewOCIServer released the port it reserved so the registry could claim
// it, and ListenAndServe binds asynchronously. Wait for the port to accept
// connections so the login below does not race the listener coming up.
dialer := &net.Dialer{Timeout: time.Second}
require.Eventually(t, func() bool {
conn, err := dialer.DialContext(t.Context(), "tcp", srv.RegistryURL)
if err != nil {
return false
}
conn.Close()
return true
}, 30*time.Second, 20*time.Millisecond, "test registry never started listening on %s", srv.RegistryURL)
credentialsFile := filepath.Join(srv.Dir, "config.json")
// init test client

Loading…
Cancel
Save