From 948cc8d58c5ba54e422e99f3f96265084376d37d Mon Sep 17 00:00:00 2001 From: Prucek Date: Mon, 30 Mar 2026 13:35:14 +0200 Subject: [PATCH] build(deps): bump sigs.k8s.io/prow to feedafda4290 Co-Authored-By: Claude Opus 4.6 --- go.mod | 4 +- go.sum | 4 +- vendor/modules.txt | 4 +- .../prow/pkg/apis/prowjobs/v1/types.go | 14 +++- .../apis/prowjobs/v1/zz_generated.deepcopy.go | 5 ++ .../sigs.k8s.io/prow/pkg/bugzilla/client.go | 2 - vendor/sigs.k8s.io/prow/pkg/cache/cache.go | 10 +-- vendor/sigs.k8s.io/prow/pkg/config/cache.go | 8 +-- vendor/sigs.k8s.io/prow/pkg/config/config.go | 24 +++---- vendor/sigs.k8s.io/prow/pkg/config/jobs.go | 22 ++---- .../pkg/config/prow-config-documented.yaml | 14 ++++ vendor/sigs.k8s.io/prow/pkg/config/tide.go | 17 ++--- .../sigs.k8s.io/prow/pkg/genyaml/genyaml.go | 17 +++-- .../prow/pkg/genyaml/populate_struct.go | 10 +-- .../prow/pkg/interrupts/interrupts.go | 24 +++---- vendor/sigs.k8s.io/prow/pkg/io/opener.go | 2 +- .../prow/pkg/jira/fakejira/fake.go | 28 ++++---- vendor/sigs.k8s.io/prow/pkg/jira/jira.go | 67 +++++++------------ vendor/sigs.k8s.io/prow/pkg/kube/config.go | 5 +- .../prow/pkg/logrusutil/logrusutil.go | 11 ++- vendor/sigs.k8s.io/prow/pkg/pjutil/filter.go | 3 + vendor/sigs.k8s.io/prow/pkg/pjutil/pjutil.go | 23 ++++--- vendor/sigs.k8s.io/prow/pkg/pjutil/tot.go | 2 +- vendor/sigs.k8s.io/prow/pkg/plugins/config.go | 41 ++++++------ .../pkg/plugins/plugin-config-documented.yaml | 4 ++ .../sigs.k8s.io/prow/pkg/plugins/plugins.go | 4 +- .../sigs.k8s.io/prow/pkg/plugins/respond.go | 2 +- .../prow/pkg/pod-utils/decorate/podspec.go | 9 +-- .../prow/pkg/pod-utils/downwardapi/jobspec.go | 16 ++--- .../prow/pkg/repoowners/repoowners.go | 6 +- vendor/sigs.k8s.io/prow/pkg/sidecar/censor.go | 8 +-- vendor/sigs.k8s.io/prow/pkg/sidecar/run.go | 15 ++--- vendor/sigs.k8s.io/prow/pkg/slack/client.go | 4 +- .../sigs.k8s.io/prow/pkg/throttle/throttle.go | 4 +- 34 files changed, 205 insertions(+), 228 deletions(-) diff --git a/go.mod b/go.mod index 0fe3087ac..a86166637 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/openshift/release-controller -go 1.25.5 +go 1.25.8 replace ( github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible @@ -52,7 +52,7 @@ require ( k8s.io/component-base v0.34.1 k8s.io/klog v1.0.0 k8s.io/klog/v2 v2.130.1 - sigs.k8s.io/prow v0.0.0-20260227184331-937f24a5dcd2 + sigs.k8s.io/prow v0.0.0-20260325094416-feedafda4290 ) require ( diff --git a/go.sum b/go.sum index 79108c71e..d98fc5af3 100644 --- a/go.sum +++ b/go.sum @@ -1185,8 +1185,8 @@ sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5Ztj sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/prow v0.0.0-20260227184331-937f24a5dcd2 h1:WmO1hZGFozg+27fZJe2Jw/LapRzfOPHtjIVGYcZCKdQ= -sigs.k8s.io/prow v0.0.0-20260227184331-937f24a5dcd2/go.mod h1:mp/tLCcvJyJAIk8+QL7zyS2SzI28HDP0LPV91Z73pGU= +sigs.k8s.io/prow v0.0.0-20260325094416-feedafda4290 h1:XKV3mq/MRwNR0R49qNXIV1rCrTN/auYCBYyZ1cqbK/o= +sigs.k8s.io/prow v0.0.0-20260325094416-feedafda4290/go.mod h1:LkFUWvukcR88tO0JBhMpKFh0rnzBkWa3fbM37/1eBjU= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/vendor/modules.txt b/vendor/modules.txt index f986aa384..191e544ee 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2255,8 +2255,8 @@ sigs.k8s.io/controller-runtime/pkg/reconcile ## explicit; go 1.23 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json -# sigs.k8s.io/prow v0.0.0-20260227184331-937f24a5dcd2 -## explicit; go 1.25.5 +# sigs.k8s.io/prow v0.0.0-20260325094416-feedafda4290 +## explicit; go 1.25.8 sigs.k8s.io/prow/pkg/apis/prowjobs sigs.k8s.io/prow/pkg/apis/prowjobs/v1 sigs.k8s.io/prow/pkg/bugzilla diff --git a/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/types.go b/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/types.go index 22a1a6a36..0c981bac8 100644 --- a/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/types.go +++ b/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/types.go @@ -20,6 +20,7 @@ import ( "encoding/json" "errors" "fmt" + "maps" "mime" "net/url" "strings" @@ -502,6 +503,12 @@ type DecorationConfig struct { // BloblessFetch tells Prow to avoid fetching objects when cloning using // the --filter=blob:none flag. BloblessFetch *bool `json:"blobless_fetch,omitempty"` + // SparseCheckoutFiles limits the working tree to only the listed paths. + // Accepts the same patterns as git sparse-checkout set (file names, + // directory names, gitignore-style globs). When set, clonerefs performs a + // sparse checkout instead of a full clone. Applied to the primary ref for + // presubmit/postsubmit jobs. Not applied to extra refs. + SparseCheckoutFiles []string `json:"sparse_checkout_files,omitempty"` // SkipCloning determines if we should clone source code in the // initcontainers for jobs that specify refs SkipCloning *bool `json:"skip_cloning,omitempty"` @@ -853,6 +860,9 @@ func (d *DecorationConfig) ApplyDefault(def *DecorationConfig) *DecorationConfig if merged.BloblessFetch == nil { merged.BloblessFetch = def.BloblessFetch } + if len(merged.SparseCheckoutFiles) == 0 { + merged.SparseCheckoutFiles = def.SparseCheckoutFiles + } if merged.SchedulingOptions == nil { merged.SchedulingOptions = def.SchedulingOptions } @@ -1025,9 +1035,7 @@ func (g *GCSConfiguration) ApplyDefault(def *GCSConfiguration) *GCSConfiguration merged.MediaTypes = map[string]string{} } - for extension, mediaType := range def.MediaTypes { - merged.MediaTypes[extension] = mediaType - } + maps.Copy(merged.MediaTypes, def.MediaTypes) if merged.JobURLPrefix == "" { merged.JobURLPrefix = def.JobURLPrefix diff --git a/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/zz_generated.deepcopy.go b/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/zz_generated.deepcopy.go index 328b63025..800f272dd 100644 --- a/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/zz_generated.deepcopy.go +++ b/vendor/sigs.k8s.io/prow/pkg/apis/prowjobs/v1/zz_generated.deepcopy.go @@ -129,6 +129,11 @@ func (in *DecorationConfig) DeepCopyInto(out *DecorationConfig) { *out = new(bool) **out = **in } + if in.SparseCheckoutFiles != nil { + in, out := &in.SparseCheckoutFiles, &out.SparseCheckoutFiles + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.SkipCloning != nil { in, out := &in.SkipCloning, &out.SkipCloning *out = new(bool) diff --git a/vendor/sigs.k8s.io/prow/pkg/bugzilla/client.go b/vendor/sigs.k8s.io/prow/pkg/bugzilla/client.go index a9c5b6468..c340d7057 100644 --- a/vendor/sigs.k8s.io/prow/pkg/bugzilla/client.go +++ b/vendor/sigs.k8s.io/prow/pkg/bugzilla/client.go @@ -378,7 +378,6 @@ func getAllLinkedBugs(c Client, bugID int, bugCache *bugDetailsCache, errGroup * func traverseUp(c Client, bug *Bug, bugCache *bugDetailsCache, errGroup *errgroup.Group) error { for _, dependsOnID := range bug.DependsOn { - dependsOnID := dependsOnID errGroup.Go(func() error { _, alreadyFetched := bugCache.get(dependsOnID) if alreadyFetched { @@ -400,7 +399,6 @@ func traverseUp(c Client, bug *Bug, bugCache *bugDetailsCache, errGroup *errgrou func traverseDown(c Client, bug *Bug, bugCache *bugDetailsCache, errGroup *errgroup.Group) error { for _, childID := range bug.Blocks { - childID := childID errGroup.Go(func() error { _, alreadyFetched := bugCache.get(childID) if alreadyFetched { diff --git a/vendor/sigs.k8s.io/prow/pkg/cache/cache.go b/vendor/sigs.k8s.io/prow/pkg/cache/cache.go index 5398af4d6..36cbd23c5 100644 --- a/vendor/sigs.k8s.io/prow/pkg/cache/cache.go +++ b/vendor/sigs.k8s.io/prow/pkg/cache/cache.go @@ -70,7 +70,7 @@ type Callbacks struct { // EventCallback is similar to simplelru.EvictCallback, except that it doesn't // take a value argument. -type EventCallback func(key interface{}) +type EventCallback func(key any) // ValConstructor is used to construct a value. The assumption is that this // ValConstructor is expensive to compute, and that we need to memoize it via @@ -79,7 +79,7 @@ type EventCallback func(key interface{}) // arbitrary function whose resulting value needs to be memoized (saved in the // cache). This type also allows us to delay running the expensive computation // until we actually need it (after a cache miss). -type ValConstructor func() (interface{}, error) +type ValConstructor func() (any, error) // Promise is a wrapper around cache value construction; it is used to // synchronize the to-be-cached value between the first thread that undergoes a @@ -90,7 +90,7 @@ type ValConstructor func() (interface{}, error) type Promise struct { valConstructor ValConstructor valConstructionPending chan struct{} - val interface{} + val any err error } @@ -142,8 +142,8 @@ func NewLRUCache(size int, // This cache is resistant to cache stampedes because it uses a duplicate // suppression strategy. This is also called request coalescing. func (lruCache *LRUCache) GetOrAdd( - key interface{}, - valConstructor ValConstructor) (interface{}, bool, error) { + key any, + valConstructor ValConstructor) (any, bool, error) { // Cache lookup. if lruCache.callbacks.LookupsCallback != nil { diff --git a/vendor/sigs.k8s.io/prow/pkg/config/cache.go b/vendor/sigs.k8s.io/prow/pkg/config/cache.go index 50450eef7..bdccd42b1 100644 --- a/vendor/sigs.k8s.io/prow/pkg/config/cache.go +++ b/vendor/sigs.k8s.io/prow/pkg/config/cache.go @@ -120,7 +120,7 @@ func init() { } func mkCacheEventCallback(counterVec *prometheus.CounterVec) cache.EventCallback { - callback := func(key interface{}) { + callback := func(key any) { org, repo, err := keyToOrgRepo(key) if err != nil { return @@ -164,7 +164,7 @@ func NewInRepoConfigCache( lookupsCallback := mkCacheEventCallback(inRepoConfigCacheMetrics.lookups) hitsCallback := mkCacheEventCallback(inRepoConfigCacheMetrics.hits) missesCallback := mkCacheEventCallback(inRepoConfigCacheMetrics.misses) - forcedEvictionsCallback := func(key interface{}, _ interface{}) { + forcedEvictionsCallback := func(key any, _ any) { org, repo, err := keyToOrgRepo(key) if err != nil { return @@ -278,7 +278,7 @@ func (cacheKey CacheKey) toCacheKeyParts() (CacheKeyParts, error) { return kp, nil } -func keyToOrgRepo(key interface{}) (string, string, error) { +func keyToOrgRepo(key any) (string, string, error) { cacheKey, ok := key.(CacheKey) if !ok { @@ -414,7 +414,7 @@ func (cache *InRepoConfigCache) getProwYAML( return nil, err } - valConstructor := func() (interface{}, error) { + valConstructor := func() (any, error) { return valConstructorHelper(cache.gitClient, identifier, baseBranch, baseSHAGetter, headSHAGetters...) } diff --git a/vendor/sigs.k8s.io/prow/pkg/config/config.go b/vendor/sigs.k8s.io/prow/pkg/config/config.go index 22a393b2a..cc58ee65f 100644 --- a/vendor/sigs.k8s.io/prow/pkg/config/config.go +++ b/vendor/sigs.k8s.io/prow/pkg/config/config.go @@ -24,12 +24,14 @@ import ( "errors" "fmt" "io" + "maps" "net/url" "os" "path" "path/filepath" "regexp" "runtime/debug" + "slices" "sort" "strconv" "strings" @@ -272,10 +274,8 @@ func (c *Config) InRepoConfigEnabled(identifier string) bool { // Assumes that config will not include http:// or https:// func (c *Config) InRepoConfigAllowsCluster(clusterName, identifier string) bool { for _, key := range keysForIdentifier(identifier) { - for _, allowedCluster := range c.InRepoConfig.AllowedClusters[key] { - if allowedCluster == clusterName { - return true - } + if slices.Contains(c.InRepoConfig.AllowedClusters[key], clusterName) { + return true } } return false @@ -1920,7 +1920,7 @@ func loadConfig(prowConfig, jobConfig string, additionalProwConfigDirs []string, } // yamlToConfig converts a yaml file into a Config object. -func yamlToConfig(path string, nc interface{}, opts ...yaml.JSONOpt) error { +func yamlToConfig(path string, nc any, opts ...yaml.JSONOpt) error { b, err := ReadFileMaybeGZIP(path) if err != nil { return fmt.Errorf("error reading %s: %w", path, err) @@ -2031,18 +2031,14 @@ func mergeJobConfigs(a, b JobConfig) (JobConfig, error) { // *** Presubmits *** c.PresubmitsStatic = make(map[string][]Presubmit) - for repo, jobs := range a.PresubmitsStatic { - c.PresubmitsStatic[repo] = jobs - } + maps.Copy(c.PresubmitsStatic, a.PresubmitsStatic) for repo, jobs := range b.PresubmitsStatic { c.PresubmitsStatic[repo] = append(c.PresubmitsStatic[repo], jobs...) } // *** Postsubmits *** c.PostsubmitsStatic = make(map[string][]Postsubmit) - for repo, jobs := range a.PostsubmitsStatic { - c.PostsubmitsStatic[repo] = jobs - } + maps.Copy(c.PostsubmitsStatic, a.PostsubmitsStatic) for repo, jobs := range b.PostsubmitsStatic { c.PostsubmitsStatic[repo] = append(c.PostsubmitsStatic[repo], jobs...) } @@ -2869,10 +2865,8 @@ func parseTideMergeType(tideMergeTypes map[string]TideOrgMergeType) utilerrors.A func validateLabels(labels map[string]string) error { for label, value := range labels { - for _, prowLabel := range decorate.Labels() { - if label == prowLabel { - return fmt.Errorf("label %s is reserved for decoration", label) - } + if slices.Contains(decorate.Labels(), label) { + return fmt.Errorf("label %s is reserved for decoration", label) } if errs := validation.IsQualifiedName(label); len(errs) != 0 { return fmt.Errorf("invalid label %s: %v", label, errs) diff --git a/vendor/sigs.k8s.io/prow/pkg/config/jobs.go b/vendor/sigs.k8s.io/prow/pkg/config/jobs.go index 45ac73f28..61edb4891 100644 --- a/vendor/sigs.k8s.io/prow/pkg/config/jobs.go +++ b/vendor/sigs.k8s.io/prow/pkg/config/jobs.go @@ -21,6 +21,7 @@ import ( "fmt" "net/url" "regexp" + "slices" "strings" "time" @@ -427,12 +428,7 @@ func (br Brancher) Intersects(other Brancher) bool { // Actually test our branches against the other brancher - if there are regex skip lists, simple comparison // is insufficient. - for _, b := range sets.List(baseBranches) { - if other.ShouldRun(b) { - return true - } - } - return false + return slices.ContainsFunc(sets.List(baseBranches), other.ShouldRun) } if len(other.Branches) == 0 { // There can only be one Brancher with skip_branches. @@ -692,11 +688,8 @@ func (c *JobConfig) AllStaticPresubmits(repos []string) []Presubmit { if len(repos) == 0 { res = append(res, v...) } else { - for _, r := range repos { - if r == repo { - res = append(res, v...) - break - } + if slices.Contains(repos, repo) { + res = append(res, v...) } } } @@ -716,11 +709,8 @@ func (c *JobConfig) AllStaticPostsubmits(repos []string) []Postsubmit { if len(repos) == 0 { res = append(res, v...) } else { - for _, r := range repos { - if r == repo { - res = append(res, v...) - break - } + if slices.Contains(repos, repo) { + res = append(res, v...) } } } diff --git a/vendor/sigs.k8s.io/prow/pkg/config/prow-config-documented.yaml b/vendor/sigs.k8s.io/prow/pkg/config/prow-config-documented.yaml index 7dae5e503..420b507ff 100644 --- a/vendor/sigs.k8s.io/prow/pkg/config/prow-config-documented.yaml +++ b/vendor/sigs.k8s.io/prow/pkg/config/prow-config-documented.yaml @@ -921,6 +921,13 @@ plank: # SkipCloning determines if we should clone source code in the # initcontainers for jobs that specify refs skip_cloning: false + # SparseCheckoutFiles limits the working tree to only the listed paths. + # Accepts the same patterns as git sparse-checkout set (file names, + # directory names, gitignore-style globs). When set, clonerefs performs a + # sparse checkout instead of a full clone. Applied to the primary ref for + # presubmit/postsubmit jobs. Not applied to extra refs. + sparse_checkout_files: + - "" # SSHHostFingerprints are the fingerprints of known SSH hosts # that the cloning process can trust. # Create with ssh-keyscan [-t rsa] host @@ -1282,6 +1289,13 @@ plank: # SkipCloning determines if we should clone source code in the # initcontainers for jobs that specify refs skip_cloning: false + # SparseCheckoutFiles limits the working tree to only the listed paths. + # Accepts the same patterns as git sparse-checkout set (file names, + # directory names, gitignore-style globs). When set, clonerefs performs a + # sparse checkout instead of a full clone. Applied to the primary ref for + # presubmit/postsubmit jobs. Not applied to extra refs. + sparse_checkout_files: + - "" # SSHHostFingerprints are the fingerprints of known SSH hosts # that the cloning process can trust. # Create with ssh-keyscan [-t rsa] host diff --git a/vendor/sigs.k8s.io/prow/pkg/config/tide.go b/vendor/sigs.k8s.io/prow/pkg/config/tide.go index d65303167..46f0a08aa 100644 --- a/vendor/sigs.k8s.io/prow/pkg/config/tide.go +++ b/vendor/sigs.k8s.io/prow/pkg/config/tide.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "regexp" + "slices" "sort" "strings" "sync" @@ -583,7 +584,7 @@ func (tq *TideQuery) constructQuery() (map[string][]string, string) { } for _, l := range tq.Labels { var orOperands []string - for _, alt := range strings.Split(l, ",") { + for alt := range strings.SplitSeq(l, ",") { orOperands = append(orOperands, fmt.Sprintf("\"%s\"", alt)) } queryString = append(queryString, fmt.Sprintf("label:%s", strings.Join(orOperands, ","))) @@ -639,19 +640,9 @@ func (tq TideQuery) ForRepo(repo OrgRepo) bool { continue } // Check for repos excluded from the org. - for _, excludedRepo := range tq.ExcludedRepos { - if excludedRepo == repo.String() { - return false - } - } - return true + return !slices.Contains(tq.ExcludedRepos, repo.String()) } - for _, queryRepo := range tq.Repos { - if queryRepo == repo.String() { - return true - } - } - return false + return slices.Contains(tq.Repos, repo.String()) } func reposInOrg(org string, repos []string) []string { diff --git a/vendor/sigs.k8s.io/prow/pkg/genyaml/genyaml.go b/vendor/sigs.k8s.io/prow/pkg/genyaml/genyaml.go index bc1808d27..452b333d1 100644 --- a/vendor/sigs.k8s.io/prow/pkg/genyaml/genyaml.go +++ b/vendor/sigs.k8s.io/prow/pkg/genyaml/genyaml.go @@ -71,6 +71,7 @@ import ( "go/doc" "go/parser" "go/token" + "maps" "path/filepath" "reflect" "regexp" @@ -161,7 +162,7 @@ type Comment struct { } // marshal marshals the object into JSON then converts JSON to YAML and returns the YAML. -func marshal(o interface{}) ([]byte, error) { +func marshal(o any) ([]byte, error) { j, err := json.Marshal(o) if err != nil { return nil, fmt.Errorf("error marshaling into JSON: %w", err) @@ -178,7 +179,7 @@ func marshal(o interface{}) ([]byte, error) { // jsonToYaml Converts JSON to YAML. func jsonToYaml(j []byte) ([]byte, error) { // Convert the JSON to an object. - var jsonObj interface{} + var jsonObj any // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the // Go JSON library doesn't try to pick the right number type (int, float, // etc.) when unmarshalling to interface{}, it just picks float64 @@ -228,7 +229,7 @@ func fmtRawDoc(rawDoc string) string { // Ignore all lines after ---. rawDoc = strings.Split(rawDoc, "---")[0] - for _, line := range strings.Split(rawDoc, "\n") { + for line := range strings.SplitSeq(rawDoc, "\n") { line = strings.TrimSpace(line) // Trim leading and trailing whitespace. switch { case strings.HasPrefix(line, "TODO"): // Ignore one line TODOs. @@ -331,7 +332,7 @@ func isBuiltinType(typeName string) bool { } // getType returns the type's name within its package for a defined type. For other (non-defined) types it returns the empty string. -func getType(typ interface{}) string { +func getType(typ any) string { t := reflect.TypeOf(typ) if t.Kind() == reflect.Ptr { return t.Elem().Name() @@ -397,9 +398,7 @@ func (cm *CommentMap) genDocMap(packageFiles []string, rawFiles map[string][]byt // struct is missing for typeSpecName, inlined := range inlineFields { for _, inlinedType := range inlined { - for tagName, comment := range cm.comments[inlinedType] { - cm.comments[typeSpecName][tagName] = comment - } + maps.Copy(cm.comments[typeSpecName], cm.comments[inlinedType]) } } @@ -478,7 +477,7 @@ func (cm *CommentMap) addPackage(paths []string, rawFiles map[string][]byte, imp } // GenYaml generates a fully commented YAML snippet for a given plugin configuration. -func (cm *CommentMap) GenYaml(config interface{}) (string, error) { +func (cm *CommentMap) GenYaml(config any) (string, error) { var buffer bytes.Buffer encoder := yaml3.NewEncoder(&buffer) @@ -493,7 +492,7 @@ func (cm *CommentMap) GenYaml(config interface{}) (string, error) { // EncodeYaml encodes a fully commented YAML snippet for a given plugin configuration // using the given encoder. -func (cm *CommentMap) EncodeYaml(config interface{}, encoder *yaml3.Encoder) error { +func (cm *CommentMap) EncodeYaml(config any, encoder *yaml3.Encoder) error { cm.RLock() defer cm.RUnlock() diff --git a/vendor/sigs.k8s.io/prow/pkg/genyaml/populate_struct.go b/vendor/sigs.k8s.io/prow/pkg/genyaml/populate_struct.go index 927c8740e..369ed7913 100644 --- a/vendor/sigs.k8s.io/prow/pkg/genyaml/populate_struct.go +++ b/vendor/sigs.k8s.io/prow/pkg/genyaml/populate_struct.go @@ -32,7 +32,7 @@ import ( // NOTE: PopulateStruct will panic if not fed a pointer. Generally if you care about // the stability of the app that runs this code, it is strongly recommended to recover panics: // defer func(){if r := recover(); r != nil { fmt.Printf("Recovered panic: %v", r } }( -func PopulateStruct(in interface{}) interface{} { +func PopulateStruct(in any) any { typeOf := reflect.TypeOf(in) if typeOf.Kind() != reflect.Ptr { panic(fmt.Sprintf("got nonpointer type %T", in)) @@ -83,7 +83,7 @@ func PopulateStruct(in interface{}) interface{} { // Create a one element slice slice := reflect.MakeSlice(typeOf.Elem().Field(i).Type, 1, 1) // Get a pointer to the value - var sliceElementPtr interface{} + var sliceElementPtr any if slice.Index(0).Type().Kind() == reflect.Ptr { // Slice of pointers, make it a non-nil pointer, then pass on its address slice.Index(0).Set(createNonNilPtr(slice.Index(0).Type())) @@ -102,7 +102,7 @@ func PopulateStruct(in interface{}) interface{} { key := reflect.New(keyType).Elem() value := reflect.New(valueType).Elem() - var keyPtr, valPtr interface{} + var keyPtr, valPtr any if key.Kind() == reflect.Ptr { key.Set(createNonNilPtr(key.Type())) keyPtr = key.Interface() @@ -142,5 +142,5 @@ func createNonNilPtr(in reflect.Type) reflect.Value { return ptr } -var typeOfBytes = reflect.TypeOf([]byte(nil)) -var typeOfJSONRawMessage = reflect.TypeOf(json.RawMessage{}) +var typeOfBytes = reflect.TypeFor[[]byte]() +var typeOfJSONRawMessage = reflect.TypeFor[json.RawMessage]() diff --git a/vendor/sigs.k8s.io/prow/pkg/interrupts/interrupts.go b/vendor/sigs.k8s.io/prow/pkg/interrupts/interrupts.go index 704f393b1..18c2a892b 100644 --- a/vendor/sigs.k8s.io/prow/pkg/interrupts/interrupts.go +++ b/vendor/sigs.k8s.io/prow/pkg/interrupts/interrupts.go @@ -143,11 +143,9 @@ func Context() context.Context { // of the wait group on shutdown. func Run(work func(ctx context.Context)) { ctx, cancel := context.WithCancel(context.Background()) - single.wg.Add(1) - go func() { - defer single.wg.Done() + single.wg.Go(func() { work(ctx) - }() + }) go wait(cancel) } @@ -163,11 +161,9 @@ type ListenAndServer interface { // are expected to exit only after WaitForGracefulShutdown returns to // ensure all servers have had time to shut down. func ListenAndServe(server ListenAndServer, gracePeriod time.Duration) { - single.wg.Add(1) - go func() { - defer single.wg.Done() + single.wg.Go(func() { logrus.WithError(server.ListenAndServe()).Info("Server exited.") - }() + }) go wait(shutdown(server, gracePeriod)) } @@ -177,11 +173,9 @@ func ListenAndServe(server ListenAndServer, gracePeriod time.Duration) { // are expected to exit only after WaitForGracefulShutdown returns to // ensure all servers have had time to shut down. func ListenAndServeTLS(server *http.Server, certFile, keyFile string, gracePeriod time.Duration) { - single.wg.Add(1) - go func() { - defer single.wg.Done() + single.wg.Go(func() { logrus.WithError(server.ListenAndServeTLS(certFile, keyFile)).Info("Server exited.") - }() + }) go wait(shutdown(server, gracePeriod)) } @@ -210,9 +204,7 @@ func shutdown(server Shutdownable, gracePeriod time.Duration) func() { func Tick(work func(), interval func() time.Duration) { before := time.Time{} // we want to do work right away sig := make(chan int, 1) - single.wg.Add(1) - go func() { - defer single.wg.Done() + single.wg.Go(func() { for { nextInterval := interval() nextTick := before.Add(nextInterval) @@ -231,7 +223,7 @@ func Tick(work func(), interval func() time.Duration) { return } } - }() + }) go wait(func() { sig <- 1 diff --git a/vendor/sigs.k8s.io/prow/pkg/io/opener.go b/vendor/sigs.k8s.io/prow/pkg/io/opener.go index c535f3aa8..a0c4fba1a 100644 --- a/vendor/sigs.k8s.io/prow/pkg/io/opener.go +++ b/vendor/sigs.k8s.io/prow/pkg/io/opener.go @@ -304,7 +304,7 @@ func (o *opener) Writer(ctx context.Context, p string, opts ...WriterOptions) (i options.apply(nil, &wOpts) if options.PreconditionDoesNotExist != nil && *options.PreconditionDoesNotExist { - wOpts.BeforeWrite = func(asFunc func(interface{}) bool) error { + wOpts.BeforeWrite = func(asFunc func(any) bool) error { _, err := o.Reader(ctx, p) if err != nil { // we got an error, but not object not exists diff --git a/vendor/sigs.k8s.io/prow/pkg/jira/fakejira/fake.go b/vendor/sigs.k8s.io/prow/pkg/jira/fakejira/fake.go index ddd1ed629..9804189de 100644 --- a/vendor/sigs.k8s.io/prow/pkg/jira/fakejira/fake.go +++ b/vendor/sigs.k8s.io/prow/pkg/jira/fakejira/fake.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "maps" "strconv" "strings" @@ -174,8 +175,8 @@ func (f *FakeClient) CreateIssue(issue *jira.Issue) (*jira.Issue, error) { if intID > highestID { highestID = intID } - if strings.HasPrefix(issue.Key, keyPrefix) { - stringID := strings.TrimPrefix(issue.Key, keyPrefix) + if after, ok := strings.CutPrefix(issue.Key, keyPrefix); ok { + stringID := after intID, _ := strconv.Atoi(stringID) if intID > highestKeyID { highestKeyID = intID @@ -280,6 +281,15 @@ func (f *FakeClient) DoTransition(issueID, transitionID string) error { return nil } +func (f *FakeClient) GetUser(accountID string) (*jira.User, error) { + for _, user := range f.Users { + if user.AccountID == accountID { + return user, nil + } + } + return nil, jiraclient.NewNotFoundError(fmt.Errorf("no user with accountId %s found", accountID)) +} + func (f *FakeClient) FindUser(property string) ([]*jira.User, error) { var foundUsers []*jira.User for _, user := range f.Users { @@ -301,14 +311,6 @@ func (f *FakeClient) GetIssueSecurityLevel(issue *jira.Issue) (*jiraclient.Secur return jiraclient.GetIssueSecurityLevel(issue) } -func (f *FakeClient) GetIssueQaContact(issue *jira.Issue) (*jira.User, error) { - return jiraclient.GetIssueQaContact(issue) -} - -func (f *FakeClient) GetIssueTargetVersion(issue *jira.Issue) (*[]*jira.Version, error) { - return jiraclient.GetIssueTargetVersion(issue) -} - func (f *FakeClient) UpdateIssue(issue *jira.Issue) (*jira.Issue, error) { if f.UpdateIssueError != nil { if err, ok := f.UpdateIssueError[issue.Key]; ok { @@ -321,7 +323,7 @@ func (f *FakeClient) UpdateIssue(issue *jira.Issue) (*jira.Issue, error) { } // convert `fields` field of both retrieved and provided issue to interfaces and update the non-nil // fields from the provided issue to the retrieved one - var issueFields, retrievedFields map[string]interface{} + var issueFields, retrievedFields map[string]any issueBytes, err := json.Marshal(issue.Fields) if err != nil { return nil, fmt.Errorf("error converting provided issue to json: %v", err) @@ -336,9 +338,7 @@ func (f *FakeClient) UpdateIssue(issue *jira.Issue) (*jira.Issue, error) { if err := json.Unmarshal(retrievedIssueBytes, &retrievedFields); err != nil { return nil, fmt.Errorf("failed converting original issue to map: %v", err) } - for key, value := range issueFields { - retrievedFields[key] = value - } + maps.Copy(retrievedFields, issueFields) updatedIssueBytes, err := json.Marshal(retrievedFields) if err != nil { return nil, fmt.Errorf("error converting updated issue to json: %v", err) diff --git a/vendor/sigs.k8s.io/prow/pkg/jira/jira.go b/vendor/sigs.k8s.io/prow/pkg/jira/jira.go index 276a70cf9..a728df1dd 100644 --- a/vendor/sigs.k8s.io/prow/pkg/jira/jira.go +++ b/vendor/sigs.k8s.io/prow/pkg/jira/jira.go @@ -73,10 +73,8 @@ type Client interface { // is set for the issue, the returned SecurityLevel and error will both be nil and // the issue will follow the default project security level. GetIssueSecurityLevel(*jira.Issue) (*SecurityLevel, error) - // GetIssueQaContact get the user details for the QA contact. The QA contact is a custom field in Jira - GetIssueQaContact(*jira.Issue) (*jira.User, error) - // GetIssueTargetVersion get the issue Target Release. The target release is a custom field in Jira - GetIssueTargetVersion(issue *jira.Issue) (*[]*jira.Version, error) + // GetUser returns a single user by their Jira account ID. + GetUser(accountID string) (*jira.User, error) // FindUser returns all users with a field matching the queryParam (ex: email, display name, etc.) FindUser(queryParam string) ([]*jira.User, error) GetRemoteLinks(id string) ([]jira.RemoteLink, error) @@ -395,6 +393,17 @@ func (jc *client) DeleteRemoteLinkViaURL(issueID, url string) (bool, error) { return DeleteRemoteLinkViaURL(jc, issueID, url) } +func (jc *client) GetUser(accountID string) (*jira.User, error) { + user, response, err := jc.upstream.User.Get(accountID) + if err != nil { + if response != nil && response.StatusCode == http.StatusNotFound { + return nil, NotFoundError{err} + } + return nil, HandleJiraError(response, err) + } + return user, nil +} + func (jc *client) FindUser(queryParam string) ([]*jira.User, error) { // JIRA's own documentation here is incorrect; it specifies that either 'accountID', // 'query', or 'property' must be used. However, JIRA throws an error unless 'username' @@ -572,11 +581,11 @@ func unsetProblematicFields(issue *jira.Issue, responseBody string) (*jira.Issue if err != nil { return nil, err } - issueMap := make(map[string]interface{}) + issueMap := make(map[string]any) if err := json.Unmarshal(marshalledIssue, &issueMap); err != nil { return nil, err } - fieldsMap := issueMap["fields"].(map[string]interface{}) + fieldsMap := issueMap["fields"].(map[string]any) for field := range processedResponse.Errors { delete(fieldsMap, field) } @@ -774,14 +783,14 @@ func HandleJiraError(response *jira.Response, err error) error { // toCurl is a slightly adjusted copy of https://github.com/kubernetes/kubernetes/blob/74053d555d71a14e3853b97e204d7d6415521375/staging/src/k8s.io/client-go/transport/round_trippers.go#L339 func toCurl(r *http.Request) string { - headers := "" + var headers strings.Builder for key, values := range r.Header { for _, value := range values { - headers += fmt.Sprintf(` -H %q`, fmt.Sprintf("%s: %s", key, maskAuthorizationHeader(key, value))) + headers.WriteString(fmt.Sprintf(` -H %q`, fmt.Sprintf("%s: %s", key, maskAuthorizationHeader(key, value)))) } } - return fmt.Sprintf("curl -k -v -X%s %s '%s'", r.Method, headers, r.URL.String()) + return fmt.Sprintf("curl -k -v -X%s %s '%s'", r.Method, headers.String(), r.URL.String()) } type retryableHTTPLogrusWrapper struct { @@ -791,7 +800,7 @@ type retryableHTTPLogrusWrapper struct { // fieldsForContext translates a list of context fields to a // logrus format; any items that don't conform to our expectations // are omitted -func (l *retryableHTTPLogrusWrapper) fieldsForContext(context ...interface{}) logrus.Fields { +func (l *retryableHTTPLogrusWrapper) fieldsForContext(context ...any) logrus.Fields { fields := logrus.Fields{} for i := 0; i < len(context)-1; i += 2 { key, ok := context[i].(string) @@ -803,19 +812,19 @@ func (l *retryableHTTPLogrusWrapper) fieldsForContext(context ...interface{}) lo return fields } -func (l *retryableHTTPLogrusWrapper) Error(msg string, context ...interface{}) { +func (l *retryableHTTPLogrusWrapper) Error(msg string, context ...any) { l.log.WithFields(l.fieldsForContext(context...)).Error(msg) } -func (l *retryableHTTPLogrusWrapper) Info(msg string, context ...interface{}) { +func (l *retryableHTTPLogrusWrapper) Info(msg string, context ...any) { l.log.WithFields(l.fieldsForContext(context...)).Info(msg) } -func (l *retryableHTTPLogrusWrapper) Debug(msg string, context ...interface{}) { +func (l *retryableHTTPLogrusWrapper) Debug(msg string, context ...any) { l.log.WithFields(l.fieldsForContext(context...)).Debug(msg) } -func (l *retryableHTTPLogrusWrapper) Warn(msg string, context ...interface{}) { +func (l *retryableHTTPLogrusWrapper) Warn(msg string, context ...any) { l.log.WithFields(l.fieldsForContext(context...)).Warn(msg) } @@ -841,7 +850,7 @@ func (jc *client) SearchV2JqlWithContext(ctx context.Context, jql string, option return issues, response, nil } -func GetUnknownField(field string, issue *jira.Issue, fn func() interface{}) error { +func GetUnknownField(field string, issue *jira.Issue, fn func() any) error { obj := fn() unknownField, ok := issue.Fields.Unknowns[field] if !ok { @@ -866,7 +875,7 @@ func GetIssueSecurityLevel(issue *jira.Issue) (*SecurityLevel, error) { // as part of the issue fields // See https://github.com/andygrunwald/go-jira/issues/456 var obj *SecurityLevel - err := GetUnknownField("security", issue, func() interface{} { + err := GetUnknownField("security", issue, func() any { obj = &SecurityLevel{} return obj }) @@ -877,32 +886,6 @@ func (jc *client) GetIssueSecurityLevel(issue *jira.Issue) (*SecurityLevel, erro return GetIssueSecurityLevel(issue) } -func GetIssueQaContact(issue *jira.Issue) (*jira.User, error) { - var obj *jira.User - err := GetUnknownField("customfield_12316243", issue, func() interface{} { - obj = &jira.User{} - return obj - }) - return obj, err -} - -func (jc *client) GetIssueQaContact(issue *jira.Issue) (*jira.User, error) { - return GetIssueQaContact(issue) -} - -func GetIssueTargetVersion(issue *jira.Issue) (*[]*jira.Version, error) { - var obj *[]*jira.Version - err := GetUnknownField("customfield_12319940", issue, func() interface{} { - obj = &[]*jira.Version{{}} - return obj - }) - return obj, err -} - -func (jc *client) GetIssueTargetVersion(issue *jira.Issue) (*[]*jira.Version, error) { - return GetIssueTargetVersion(issue) -} - // GetProjectVersions returns the list of all the Versions defined in a Project func (jc *client) GetProjectVersions(project string) ([]*jira.Version, error) { req, err := jc.upstream.NewRequest("GET", "rest/api/2/project/"+project+"/versions", nil) diff --git a/vendor/sigs.k8s.io/prow/pkg/kube/config.go b/vendor/sigs.k8s.io/prow/pkg/kube/config.go index e5ccdb12a..270017698 100644 --- a/vendor/sigs.k8s.io/prow/pkg/kube/config.go +++ b/vendor/sigs.k8s.io/prow/pkg/kube/config.go @@ -19,6 +19,7 @@ package kube import ( "errors" "fmt" + "maps" "os" "path/filepath" "strings" @@ -51,9 +52,7 @@ func kubeConfigs(loader clientcmd.ClientConfigLoader) (map[string]rest.Config, s func mergeConfigs(local *rest.Config, foreign map[string]rest.Config, currentContext string) (map[string]rest.Config, error) { ret := map[string]rest.Config{} - for ctx, cfg := range foreign { - ret[ctx] = cfg - } + maps.Copy(ret, foreign) if local != nil { ret[InClusterContext] = *local } else if currentContext != "" { diff --git a/vendor/sigs.k8s.io/prow/pkg/logrusutil/logrusutil.go b/vendor/sigs.k8s.io/prow/pkg/logrusutil/logrusutil.go index ef6f050a3..65f35610b 100644 --- a/vendor/sigs.k8s.io/prow/pkg/logrusutil/logrusutil.go +++ b/vendor/sigs.k8s.io/prow/pkg/logrusutil/logrusutil.go @@ -18,6 +18,7 @@ limitations under the License. package logrusutil import ( + "maps" "sync" "time" @@ -72,12 +73,8 @@ func (f *DefaultFieldsFormatter) Format(entry *logrus.Entry) ([]byte, error) { data := make(logrus.Fields, len(entry.Data)+len(f.DefaultFields)+1) // GCP's log collection expects a "severity" field instead of "level" data["severity"] = entry.Level - for k, v := range f.DefaultFields { - data[k] = v - } - for k, v := range entry.Data { - data[k] = v - } + maps.Copy(data, f.DefaultFields) + maps.Copy(data, entry.Data) return f.WrappedFormatter.Format(&logrus.Entry{ Logger: entry.Logger, Data: data, @@ -128,7 +125,7 @@ func NewFormatterWithCensor(f logrus.Formatter, censorer secretutil.Censorer) Ce } // ThrottledWarnf prints a warning the first time called and if at most `period` has elapsed since the last time. -func ThrottledWarnf(last *time.Time, period time.Duration, format string, args ...interface{}) { +func ThrottledWarnf(last *time.Time, period time.Duration, format string, args ...any) { if throttleCheck(last, period) { logrus.Warnf(format, args...) } diff --git a/vendor/sigs.k8s.io/prow/pkg/pjutil/filter.go b/vendor/sigs.k8s.io/prow/pkg/pjutil/filter.go index 763607a30..40a86c5ff 100644 --- a/vendor/sigs.k8s.io/prow/pkg/pjutil/filter.go +++ b/vendor/sigs.k8s.io/prow/pkg/pjutil/filter.go @@ -37,6 +37,9 @@ var RetestRequiredRe = regexp.MustCompile(`(?m)^/retest-required\s*$`) var OkToTestRe = regexp.MustCompile(`(?m)^/ok-to-test\s*$`) +// OkToTestCancelRe checks for cancellation of the `/ok-to-test` approval +var OkToTestCancelRe = regexp.MustCompile(`(?m)^/ok-to-test\s+cancel\s*$`) + // AvailablePresubmits returns 3 sets of presubmits: // 1. presubmits that can be run with '/test all' command. // 2. optional presubmits commands that can be run with their trigger, e.g. '/test job' diff --git a/vendor/sigs.k8s.io/prow/pkg/pjutil/pjutil.go b/vendor/sigs.k8s.io/prow/pkg/pjutil/pjutil.go index 28ee541f5..ca2a8ac75 100644 --- a/vendor/sigs.k8s.io/prow/pkg/pjutil/pjutil.go +++ b/vendor/sigs.k8s.io/prow/pkg/pjutil/pjutil.go @@ -20,6 +20,7 @@ package pjutil import ( "bytes" "fmt" + "maps" "net/url" "path" "strconv" @@ -112,6 +113,10 @@ func setReportDefault(spec *prowapi.ProwJobSpec) { if spec.ReporterConfig == nil || spec.ReporterConfig.Slack == nil { return } + // If `report` is explicitly set, we should respect it. + if spec.ReporterConfig.Slack.Report != nil { + return + } // `job_states_to_report: []` means false if spec.ReporterConfig.Slack.JobStatesToReport != nil && len(spec.ReporterConfig.Slack.JobStatesToReport) == 0 { spec.ReporterConfig.Slack.Report = boolPtr(false) @@ -154,18 +159,12 @@ func createRefs(pr github.PullRequest, baseSHA string) prowapi.Refs { func NewPresubmit(pr github.PullRequest, baseSHA string, job config.Presubmit, eventGUID string, additionalLabels map[string]string, modifiers ...Modifier) prowapi.ProwJob { refs := createRefs(pr, baseSHA) labels := make(map[string]string) - for k, v := range job.Labels { - labels[k] = v - } - for k, v := range additionalLabels { - labels[k] = v - } + maps.Copy(labels, job.Labels) + maps.Copy(labels, additionalLabels) labels[github.EventGUID] = eventGUID labels[kube.IsOptionalLabel] = strconv.FormatBool(job.Optional) annotations := make(map[string]string) - for k, v := range job.Annotations { - annotations[k] = v - } + maps.Copy(annotations, job.Annotations) return NewProwJob(PresubmitSpec(job, refs), labels, annotations, modifiers...) } @@ -288,7 +287,11 @@ func CompletePrimaryRefs(refs prowapi.Refs, jb config.JobBase) *prowapi.Refs { if jb.SkipFetchHead { refs.SkipFetchHead = jb.SkipFetchHead } - return DecorateRefs(refs, jb) + drefs := DecorateRefs(refs, jb) + if dc := jb.DecorationConfig; dc != nil && len(dc.SparseCheckoutFiles) > 0 { + drefs.SparseCheckoutFiles = dc.SparseCheckoutFiles + } + return drefs } // PartitionActive separates the provided prowjobs into pending and triggered diff --git a/vendor/sigs.k8s.io/prow/pkg/pjutil/tot.go b/vendor/sigs.k8s.io/prow/pkg/pjutil/tot.go index d1a1d5456..1e95d56da 100644 --- a/vendor/sigs.k8s.io/prow/pkg/pjutil/tot.go +++ b/vendor/sigs.k8s.io/prow/pkg/pjutil/tot.go @@ -88,7 +88,7 @@ func GetBuildID(name, totURL string) (string, error) { } url.Path = path.Join(url.Path, "vend", name) sleepDuration := 100 * time.Millisecond - for retries := 0; retries < 10; retries++ { + for retries := range 10 { if retries > 0 { sleep(sleepDuration) sleepDuration = sleepDuration * 2 diff --git a/vendor/sigs.k8s.io/prow/pkg/plugins/config.go b/vendor/sigs.k8s.io/prow/pkg/plugins/config.go index 3efe3d0c0..4806c3f53 100644 --- a/vendor/sigs.k8s.io/prow/pkg/plugins/config.go +++ b/vendor/sigs.k8s.io/prow/pkg/plugins/config.go @@ -84,6 +84,7 @@ type Configuration struct { Lgtm []Lgtm `json:"lgtm,omitempty"` Jira *Jira `json:"jira,omitempty"` MilestoneApplier map[string]BranchToMilestone `json:"milestone_applier,omitempty"` + ReleaseNote ReleaseNote `json:"release_note,omitempty"` RepoMilestone map[string]Milestone `json:"repo_milestone,omitempty"` Project ProjectConfig `json:"project_config,omitempty"` ProjectManager ProjectManager `json:"project_manager,omitempty"` @@ -343,7 +344,7 @@ type Approve struct { // CommandHelpLink is the link to the help page which shows the available commands for each repo. // The default value is "https://go.k8s.io/bot-commands". The command help page is served by Deck // and available under https:///command-help, e.g. "https://prow.k8s.io/command-help" - CommandHelpLink string `json:"commandHelpLink"` + CommandHelpLink string `json:"commandHelpLink,omitempty"` // PrProcessLink is the link to the help page which explains the code review process. // The default value is "https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process". PrProcessLink string `json:"pr_process_link,omitempty"` @@ -462,12 +463,7 @@ func (l Label) RestrictedLabelsFor(org, repo string) map[string]RestrictedLabel } func (l Label) IsRestrictedLabelInAdditionalLabels(restricted string) bool { - for _, additional := range l.AdditionalLabels { - if restricted == additional { - return true - } - } - return false + return slices.Contains(l.AdditionalLabels, restricted) } type RestrictedLabel struct { @@ -527,6 +523,19 @@ type Heart struct { CommentRe *regexp.Regexp `json:"-"` } +// ReleaseNote contains the configuration options for the release note plugin +type ReleaseNote struct { + // GuidelinesURL is the URL to the release note guidelines that users should follow + // Defaults to the Kubernetes community guide: https://git.k8s.io/community/contributors/guide/release-notes.md + GuidelinesURL string `json:"guidelines_url,omitempty"` +} + +func (r *ReleaseNote) setDefaults() { + if r.GuidelinesURL == "" { + r.GuidelinesURL = "https://git.k8s.io/community/contributors/guide/release-notes.md" + } +} + // Milestone contains the configuration options for the milestone and // milestonestatus plugins. type Milestone struct { @@ -1076,13 +1085,7 @@ func (p *Plugins) UnmarshalJSON(d []byte) error { func (c *Configuration) EnabledReposForPlugin(plugin string) (orgs, repos []string, orgExceptions map[string]sets.Set[string]) { orgExceptions = make(map[string]sets.Set[string]) for repo, plugins := range c.Plugins { - found := false - for _, candidate := range plugins.Plugins { - if candidate == plugin { - found = true - break - } - } + found := slices.Contains(plugins.Plugins, plugin) if found { if strings.Contains(repo, "/") { repos = append(repos, repo) @@ -1206,6 +1209,8 @@ func (c *Configuration) setDefaults() { c.RequireMatchingLabel[i].GracePeriod = "5s" } } + + c.ReleaseNote.setDefaults() } // validatePluginsDupes will return an error if there are duplicated plugins. @@ -1406,10 +1411,8 @@ func validateProjectManager(pm ProjectManager) error { return fmt.Errorf("Org/repo: %s, project %s, column %s, has no org configured", orgRepoName, projectName, managedColumn.Name) } sSet := sets.New[string](managedColumn.Labels...) - for _, labels := range labelSets { - if sSet.Equal(labels) { - return fmt.Errorf("Org/repo: %s, project %s, column %s has same labels configured as another column", orgRepoName, projectName, managedColumn.Name) - } + if slices.ContainsFunc(labelSets, sSet.Equal) { + return fmt.Errorf("Org/repo: %s, project %s, column %s has same labels configured as another column", orgRepoName, projectName, managedColumn.Name) } labelSets = append(labelSets, sSet) } @@ -1768,7 +1771,7 @@ type BugzillaBranchOptions struct { AllowedGroups []string `json:"allowed_groups,omitempty"` } -type BugzillaBugStateSet map[BugzillaBugState]interface{} +type BugzillaBugStateSet map[BugzillaBugState]any func NewBugzillaBugStateSet(states []BugzillaBugState) BugzillaBugStateSet { set := make(BugzillaBugStateSet, len(states)) diff --git a/vendor/sigs.k8s.io/prow/pkg/plugins/plugin-config-documented.yaml b/vendor/sigs.k8s.io/prow/pkg/plugins/plugin-config-documented.yaml index a2e3390a7..3956e5360 100644 --- a/vendor/sigs.k8s.io/prow/pkg/plugins/plugin-config-documented.yaml +++ b/vendor/sigs.k8s.io/prow/pkg/plugins/plugin-config-documented.yaml @@ -553,6 +553,10 @@ project_manager: org: ' ' # State must be open, closed or all state: ' ' +release_note: + # GuidelinesURL is the URL to the release note guidelines that users should follow + # Defaults to the Kubernetes community guide: https://git.k8s.io/community/contributors/guide/release-notes.md + guidelines_url: ' ' repo_milestone: "": maintainers_friendly_name: ' ' diff --git a/vendor/sigs.k8s.io/prow/pkg/plugins/plugins.go b/vendor/sigs.k8s.io/prow/pkg/plugins/plugins.go index c107ff912..bd1277dbb 100644 --- a/vendor/sigs.k8s.io/prow/pkg/plugins/plugins.go +++ b/vendor/sigs.k8s.io/prow/pkg/plugins/plugins.go @@ -181,7 +181,7 @@ func RegisterGenericCommentHandler(name string, fn GenericCommentHandler, help H type PluginGitHubClient interface { github.Client - Query(ctx context.Context, q interface{}, vars map[string]interface{}) error + Query(ctx context.Context, q any, vars map[string]any) error } // Agent may be used concurrently, so each entry must be thread-safe. @@ -598,6 +598,6 @@ type githubV4OrgAddingWrapper struct { github.Client } -func (c *githubV4OrgAddingWrapper) Query(ctx context.Context, q interface{}, args map[string]interface{}) error { +func (c *githubV4OrgAddingWrapper) Query(ctx context.Context, q any, args map[string]any) error { return c.QueryWithGitHubAppsSupport(ctx, q, args, c.org) } diff --git a/vendor/sigs.k8s.io/prow/pkg/plugins/respond.go b/vendor/sigs.k8s.io/prow/pkg/plugins/respond.go index 031f1050d..da84b5e22 100644 --- a/vendor/sigs.k8s.io/prow/pkg/plugins/respond.go +++ b/vendor/sigs.k8s.io/prow/pkg/plugins/respond.go @@ -72,7 +72,7 @@ func FormatResponseRaw(body, bodyURL, login, reply string) string { ` // Quote the user's comment by prepending ">" to each line. var quoted []string - for _, l := range strings.Split(body, "\n") { + for l := range strings.SplitSeq(body, "\n") { quoted = append(quoted, ">"+l) } return FormatResponse(login, reply, fmt.Sprintf(format, bodyURL, strings.Join(quoted, "\n"))) diff --git a/vendor/sigs.k8s.io/prow/pkg/pod-utils/decorate/podspec.go b/vendor/sigs.k8s.io/prow/pkg/pod-utils/decorate/podspec.go index 9302a5fed..8bfdcdc69 100644 --- a/vendor/sigs.k8s.io/prow/pkg/pod-utils/decorate/podspec.go +++ b/vendor/sigs.k8s.io/prow/pkg/pod-utils/decorate/podspec.go @@ -18,6 +18,7 @@ package decorate import ( "fmt" + "maps" "path" "path/filepath" "sort" @@ -144,9 +145,7 @@ func LabelsAndAnnotationsForSpec(spec prowapi.ProwJobSpec, extraLabels, extraAnn } } - for k, v := range extraLabels { - labels[k] = v - } + maps.Copy(labels, extraLabels) // let's validate labels for key, value := range labels { @@ -166,9 +165,7 @@ func LabelsAndAnnotationsForSpec(spec prowapi.ProwJobSpec, extraLabels, extraAnn } } - for k, v := range extraAnnotations { - annotations[k] = v - } + maps.Copy(annotations, extraAnnotations) return labels, annotations } diff --git a/vendor/sigs.k8s.io/prow/pkg/pod-utils/downwardapi/jobspec.go b/vendor/sigs.k8s.io/prow/pkg/pod-utils/downwardapi/jobspec.go index 162862349..0e95490ef 100644 --- a/vendor/sigs.k8s.io/prow/pkg/pod-utils/downwardapi/jobspec.go +++ b/vendor/sigs.k8s.io/prow/pkg/pod-utils/downwardapi/jobspec.go @@ -150,18 +150,18 @@ func EnvForSpec(spec JobSpec) (map[string]string, error) { srcBase := fmt.Sprintf("%s/%s", spec.Refs.Org, spec.Refs.Repo) if spec.Refs.PathAlias != "" { - srcHost = spec.Refs.PathAlias - if idx := strings.Index(spec.Refs.PathAlias, "/"); idx != -1 { - srcHost = spec.Refs.PathAlias[:idx] - srcBase = spec.Refs.PathAlias[idx+1:] + if h, b, ok := strings.Cut(spec.Refs.PathAlias, "/"); ok { + srcHost, srcBase = h, b + } else { + srcHost = spec.Refs.PathAlias } } else if spec.Refs.RepoLink != "" { parts := strings.Split(spec.Refs.RepoLink, "://") hostAndPath := parts[len(parts)-1] - srcHost = hostAndPath - if idx := strings.Index(hostAndPath, "/"); idx != -1 { - srcHost = hostAndPath[:idx] - srcBase = hostAndPath[idx+1:] + if h, b, ok := strings.Cut(hostAndPath, "/"); ok { + srcHost, srcBase = h, b + } else { + srcHost = hostAndPath } } env[SrcHostEnv] = srcHost diff --git a/vendor/sigs.k8s.io/prow/pkg/repoowners/repoowners.go b/vendor/sigs.k8s.io/prow/pkg/repoowners/repoowners.go index d526aa4fb..24adf7bcb 100644 --- a/vendor/sigs.k8s.io/prow/pkg/repoowners/repoowners.go +++ b/vendor/sigs.k8s.io/prow/pkg/repoowners/repoowners.go @@ -663,7 +663,7 @@ func ParseAliasesConfig(b []byte) (RepoAliases, error) { result := make(RepoAliases) config := &struct { - Data map[string]interface{} `json:"aliases,omitempty"` + Data map[string]any `json:"aliases,omitempty"` }{} if err := yaml.Unmarshal(b, config); err != nil { return result, err @@ -671,7 +671,7 @@ func ParseAliasesConfig(b []byte) (RepoAliases, error) { for alias, expanded := range config.Data { switch v := expanded.(type) { - case []interface{}: + case []any: // Convert []interface{} to []string var members []string for _, member := range v { @@ -685,7 +685,7 @@ func ParseAliasesConfig(b []byte) (RepoAliases, error) { case string: // Alias group must contain a list of members. return result, fmt.Errorf("alias group '%s' must contain a list of members", alias) - case map[string]interface{}: + case map[string]any: // Handle Flow Style Mapping (Inline Dictionary/Object Syntax). Example - aliases: { alias-group: { alias1, alias2 } } var members []string for key := range v { diff --git a/vendor/sigs.k8s.io/prow/pkg/sidecar/censor.go b/vendor/sigs.k8s.io/prow/pkg/sidecar/censor.go index 46d78d2d5..71e8252e4 100644 --- a/vendor/sigs.k8s.io/prow/pkg/sidecar/censor.go +++ b/vendor/sigs.k8s.io/prow/pkg/sidecar/censor.go @@ -26,6 +26,7 @@ import ( "net/http" "os" "path/filepath" + "slices" "strings" "sync" "time" @@ -526,11 +527,8 @@ func loadSecrets(paths, iniFilenames []string) ([][]byte, error) { if info.Name() == ".dockerconfigjson" { parser = loadDockerconfigJsonAuths } - for _, filename := range iniFilenames { - if info.Name() == filename { - parser = loadIniData - break - } + if slices.Contains(iniFilenames, info.Name()) { + parser = loadIniData } extra, parseErr := parser(raw) if parseErr != nil { diff --git a/vendor/sigs.k8s.io/prow/pkg/sidecar/run.go b/vendor/sigs.k8s.io/prow/pkg/sidecar/run.go index 833ba568a..26d2f7791 100644 --- a/vendor/sigs.k8s.io/prow/pkg/sidecar/run.go +++ b/vendor/sigs.k8s.io/prow/pkg/sidecar/run.go @@ -23,6 +23,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "os" "os/signal" "strings" @@ -159,7 +160,6 @@ const errorKey = "sidecar-errors" func logReadersFuncs(entries []wrapper.Options) map[string]gcs.ReaderFunc { readerFuncs := make(map[string]gcs.ReaderFunc) for _, opt := range entries { - opt := opt f := func() (io.ReadCloser, error) { log, err := os.Open(opt.ProcessLog) if err != nil { @@ -179,9 +179,9 @@ func logReadersFuncs(entries []wrapper.Options) map[string]gcs.ReaderFunc { return readerFuncs } -func combineMetadata(entries []wrapper.Options) map[string]interface{} { +func combineMetadata(entries []wrapper.Options) map[string]any { errors := map[string]error{} - metadata := map[string]interface{}{} + metadata := map[string]any{} for i, opt := range entries { ent := nameEntry(i, opt) metadataFile := opt.MetadataFile @@ -199,16 +199,15 @@ func combineMetadata(entries []wrapper.Options) map[string]interface{} { continue } - piece := map[string]interface{}{} + piece := map[string]any{} if err := json.Unmarshal(metadataRaw, &piece); err != nil { logrus.WithError(err).Errorf("Failed to unmarshal %s", metadataFile) errors[ent] = err continue } - for k, v := range piece { - metadata[k] = v // TODO(fejta): consider deeper merge - } + // TODO(fejta): consider deeper merge + maps.Copy(metadata, piece) } if len(errors) > 0 { metadata[errorKey] = errors @@ -230,7 +229,7 @@ func (o Options) preUpload() { } } -func (o Options) doUpload(ctx context.Context, spec *downwardapi.JobSpec, passed, aborted bool, metadata map[string]interface{}, logReadersFuncs map[string]gcs.ReaderFunc, logFile *os.File, once *sync.Once) error { +func (o Options) doUpload(ctx context.Context, spec *downwardapi.JobSpec, passed, aborted bool, metadata map[string]any, logReadersFuncs map[string]gcs.ReaderFunc, logFile *os.File, once *sync.Once) error { startTime := time.Now() logrus.Info("Starting to upload") uploadTargets := make(map[string]gcs.UploadFunc) diff --git a/vendor/sigs.k8s.io/prow/pkg/slack/client.go b/vendor/sigs.k8s.io/prow/pkg/slack/client.go index ecd32b88c..165ce1a3c 100644 --- a/vendor/sigs.k8s.io/prow/pkg/slack/client.go +++ b/vendor/sigs.k8s.io/prow/pkg/slack/client.go @@ -57,7 +57,7 @@ func (h *HostsFlag) Set(value string) error { // Logger provides an interface to log debug messages. type Logger interface { - Debugf(s string, v ...interface{}) + Debugf(s string, v ...any) } // Client allows you to provide connection to Slack API Server @@ -92,7 +92,7 @@ func NewFakeClient() *Client { } } -func (sl *Client) log(methodName string, args ...interface{}) { +func (sl *Client) log(methodName string, args ...any) { if sl.logger == nil { return } diff --git a/vendor/sigs.k8s.io/prow/pkg/throttle/throttle.go b/vendor/sigs.k8s.io/prow/pkg/throttle/throttle.go index 5fe8481b5..67431823f 100644 --- a/vendor/sigs.k8s.io/prow/pkg/throttle/throttle.go +++ b/vendor/sigs.k8s.io/prow/pkg/throttle/throttle.go @@ -125,13 +125,13 @@ func (t *Throttler) Throttle(hourlyTokens, burst int, orgs ...string) error { period := time.Hour / time.Duration(hourlyTokens) // Duration between token refills ticker := time.NewTicker(period) throttle := make(chan time.Time, burst) - for i := 0; i < burst; i++ { // Fill up the channel + for range burst { // Fill up the channel throttle <- time.Now() } go func() { // Before refilling, wait the amount of time it would have taken to refill the burst channel. // This prevents granting too many tokens in the first hour due to the initial burst. - for i := 0; i < burst; i++ { + for range burst { <-ticker.C } // Refill the channel