feat: support cooldown for Golang module#8966
Conversation
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
* Update spec documentation * Add test cases
Signed-off-by: Olblak <me@olblak.com>
Signed-off-by: Olblak <me@olblak.com>
There was a problem hiding this comment.
Pull request overview
Adds support for an age filter (with minimum / maximum duration constraints) to Golang module and Golang language source/condition plugins, so users can implement "cooldown" semantics that exclude releases that are too recent or too old. A new shared pkg/plugins/utils/age package introduces the spec, validation, duration parsing (with h/d/w/mo/y units), and IsOlderThan / IsNewerThan helpers. For the Golang language plugin, when age filtering is enabled, version dates are obtained by cloning the upstream Go git repository and using committer dates.
Changes:
- Introduce reusable
age.Spec(parser, validator, comparator) plus tests. - Wire age filtering into
go/modulesource and condition via Go proxy@v/<ver>.infometadata. - Wire age filtering into
go/languagesource/condition with a new git-tag-based release-date lookup (age.go).
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/plugins/utils/age/main.go | New shared age filter Spec with duration parsing and comparison helpers |
| pkg/plugins/utils/age/main_test.go | Unit tests for parser, Validate, IsOlderThan, IsNewerThan, IsZero |
| pkg/plugins/resources/go/module/spec.go | Adds Age field and documents per-mode compatibility |
| pkg/plugins/resources/go/module/main.go | Validates Age spec in constructor; includes it in ReportConfig |
| pkg/plugins/resources/go/module/version.go | Filters proxy versions/pseudo versions by release age; extracts versionInfo struct |
| pkg/plugins/resources/go/module/condition.go | Branches on Age to additionally check release date for Version |
| pkg/plugins/resources/go/module/source_test.go | Adds age-based source test cases |
| pkg/plugins/resources/go/module/condition_test.go | Adds age-based condition test cases |
| pkg/plugins/resources/go/language/spec.go | Adds Age field with documentation |
| pkg/plugins/resources/go/language/main.go | Includes Age in ReportConfig |
| pkg/plugins/resources/go/language/source.go | Selects between proxy and git-based version lookup based on Age |
| pkg/plugins/resources/go/language/condition.go | Same selection logic for condition path |
| pkg/plugins/resources/go/language/age.go | New git-clone-based tag enumeration to obtain release dates |
| pkg/plugins/resources/go/language/source_test.go | Adds age-based source tests |
| pkg/plugins/resources/go/language/condition_test.go | Adds age-based condition tests |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _, err := l.versions(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("retrieving golang version: %w", err) | ||
| } | ||
|
|
||
| switch l.Spec.Age.IsZero() { | ||
| case true: | ||
| _, err = l.versions(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("searching golang version: %w", err) | ||
| } | ||
| case false: | ||
| _, err = l.getTagsFromRepository() | ||
| if err != nil { | ||
| return fmt.Errorf("searching golang version from repository: %w", err) | ||
| } | ||
| } |
| panic(err) | ||
| } | ||
|
|
||
| refs, err := repo.Tags() | ||
| if err != nil { | ||
| panic(err) |
|
|
||
| if !isPseudoVersionMatchingAge(pseudoVersion, g.Spec.Age) { | ||
| logrus.Debugf("ignoring pseudo version %q from proxy %q because it doesn't match the age filter\n", pseudoVersion, proxy) | ||
| return "", nil, nil |
| name: "hours via standard Go duration", | ||
| input: "24h", | ||
| expected: 24 * time.Hour, | ||
| }, | ||
| { |
| } | ||
|
|
||
| if releaseAge.Minimum != "" && releaseAge.IsOlderThan(releaseDate, nil) { | ||
| logrus.Debugf("ignoring version %q from proxy %q because its age is below %q (released on %s)\n", versions[v], proxy, releaseAge.Minimum, releaseDate) |
| return false, fmt.Sprintf("version %q available but failed to parse release date", versionToCheck), nil | ||
| } | ||
| if g.Spec.Age.Minimum != "" && g.Spec.Age.IsOlderThan(releaseDate, nil) { | ||
| logrus.Debugf("ignoring version %q from proxy %q because its age is below %q (released on %s)\n", versionToCheck, proxy, g.Spec.Age.Minimum, releaseDate) |
| if !releaseAge.IsZero() { | ||
| sanitizedVersions := []string{} | ||
|
|
||
| for v := range versions { | ||
| getVersionInfo, err := getVersionInfoFromProxy(ctx, client, proxy, module, versions[v]) | ||
| if err != nil { | ||
| logrus.Debugf("ignoring version %q from proxy %q due to %q\n", versions[v], proxy, err) | ||
| continue | ||
| } | ||
|
|
||
| releaseDate, err := time.Parse(time.RFC3339, getVersionInfo.Time) | ||
| if err != nil { | ||
| logrus.Debugf("ignoring version %q from proxy %q due to invalid release date format: %q\n", versions[v], proxy, err) | ||
| continue | ||
| } | ||
|
|
||
| if releaseAge.Minimum != "" && releaseAge.IsOlderThan(releaseDate, nil) { | ||
| logrus.Debugf("ignoring version %q from proxy %q because its age is below %q (released on %s)\n", versions[v], proxy, releaseAge.Minimum, releaseDate) | ||
| continue | ||
| } | ||
|
|
||
| if releaseAge.Maximum != "" && releaseAge.IsNewerThan(releaseDate, nil) { | ||
| logrus.Debugf("ignoring version %q from proxy %q because its age is above %q (released on %s)\n", versions[v], proxy, releaseAge.Maximum, releaseDate) | ||
| continue | ||
| } | ||
|
|
||
| sanitizedVersions = append(sanitizedVersions, versions[v]) | ||
| } | ||
| versions = sanitizedVersions | ||
| } |
Related to #7866
Implement the ability to filter out version newer or older than a specific date.
This pullrequest add support for Golange module.
Here is an example of a source definition:
Test
To test this pull request, you can run the following commands:
Or test manually the example above.
Additional Information
Checklist
Tradeoff
Potential improvement