-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathpredicate.go
95 lines (81 loc) · 3.33 KB
/
predicate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package securityscanutils
import (
"github.com/Masterminds/semver/v3"
"github.com/google/go-github/v32/github"
"github.com/solo-io/go-utils/githubutils"
"github.com/solo-io/go-utils/log"
"github.com/solo-io/go-utils/versionutils"
)
// The securityScanRepositoryReleasePredicate is responsible for defining which
// github.RepositoryRelease artifacts should be included in the bulk security scan
// At the moment, the two requirements are that:
// 1. The release is not a pre-release or draft, unless explicitly enabled
// 2. The release matches the configured version constraint
type securityScanRepositoryReleasePredicate struct {
versionConstraint *semver.Constraints
enablePreRelease bool
}
func NewSecurityScanRepositoryReleasePredicate(
constraint *semver.Constraints,
enablePreRelease bool,
) *securityScanRepositoryReleasePredicate {
return &securityScanRepositoryReleasePredicate{
versionConstraint: constraint,
enablePreRelease: enablePreRelease,
}
}
func (s *securityScanRepositoryReleasePredicate) Apply(release *github.RepositoryRelease) bool {
// Note: GetPrerelease() is referring to a pre-release in GitHub. The term pre-release is
// slightly overloaded between GitHub and semver. We _do_ want to scan semver pre-releases
// as those correspond to GitHub releases whose tag matches the pattern of a semver pre-release.
if (release.GetPrerelease() && !s.enablePreRelease) || release.GetDraft() {
// Do not include drafts or pre-releases unless explicitly enabled
return false
}
versionToTest, err := semver.NewVersion(release.GetTagName())
if err != nil {
// If we are unable to parse the release version, we do not include it in the filtered list
log.Warnf("unable to parse release version %s", release.GetTagName())
return false
}
if !s.versionConstraint.Check(versionToTest) {
// If the release version does not pass the version constraint, do not include
return false
}
// If all checks have passed, include the release
return true
}
// The latestPatchRepositoryReleasePredicate returns true if a provided RepositoryRelease
// is the latest patch release on a long-term support (LTS) branch
// For example: The latest patch release of v1.0.0, v1.0.1, v1.0.2 is v1.0.2 (https://semver.org/)
type latestPatchRepositoryReleasePredicate struct {
releasesByTagName map[string]*github.RepositoryRelease
}
func NewLatestPatchRepositoryReleasePredicate(releases []*github.RepositoryRelease) *latestPatchRepositoryReleasePredicate {
githubutils.SortReleasesBySemver(releases)
// We could use maxint but we dont really care
// as we can just check if major minor changed
latestPatchReleasesByTagName := make(map[string]*github.RepositoryRelease)
recentMajor := -1
recentMinor := -1
for _, release := range releases {
version, err := versionutils.ParseVersion(release.GetTagName())
if err != nil {
continue
}
if version.Major == recentMajor && version.Minor == recentMinor {
continue
}
// This is the largest patch release
recentMajor = version.Major
recentMinor = version.Minor
latestPatchReleasesByTagName[release.GetTagName()] = release
}
return &latestPatchRepositoryReleasePredicate{
releasesByTagName: latestPatchReleasesByTagName,
}
}
func (s *latestPatchRepositoryReleasePredicate) Apply(release *github.RepositoryRelease) bool {
_, ok := s.releasesByTagName[release.GetTagName()]
return ok
}