Skip to content

Commit d6a04a3

Browse files
fix: Check for semver constraint matching in application webhook handler (cherry-pick #21648) (#22507)
Signed-off-by: eadred <[email protected]> Co-authored-by: Eadred <[email protected]>
1 parent 4f37dd8 commit d6a04a3

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

util/webhook/webhook.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212
"sync"
1313

14+
"github.com/Masterminds/semver/v3"
1415
"github.com/go-playground/webhooks/v6/azuredevops"
1516
"github.com/go-playground/webhooks/v6/bitbucket"
1617
bitbucketserver "github.com/go-playground/webhooks/v6/bitbucket-server"
@@ -413,11 +414,33 @@ func sourceRevisionHasChanged(source v1alpha1.ApplicationSource, revision string
413414
targetRevisionHasPrefixList := []string{"refs/heads/", "refs/tags/"}
414415
for _, prefix := range targetRevisionHasPrefixList {
415416
if strings.HasPrefix(source.TargetRevision, prefix) {
416-
return revision == targetRev
417+
return compareRevisions(revision, targetRev)
417418
}
418419
}
419420

420-
return source.TargetRevision == revision
421+
return compareRevisions(revision, source.TargetRevision)
422+
}
423+
424+
func compareRevisions(revision string, targetRevision string) bool {
425+
if revision == targetRevision {
426+
return true
427+
}
428+
429+
// If basic equality checking fails, it might be that the target revision is
430+
// a semver version constraint
431+
constraint, err := semver.NewConstraint(targetRevision)
432+
if err != nil {
433+
// The target revision is not a constraint
434+
return false
435+
}
436+
437+
version, err := semver.NewVersion(revision)
438+
if err != nil {
439+
// The new revision is not a valid semver version, so it can't match the constraint.
440+
return false
441+
}
442+
443+
return constraint.Check(version)
421444
}
422445

423446
func sourceUsesURL(source v1alpha1.ApplicationSource, webURL string, repoRegexp *regexp.Regexp) bool {

util/webhook/webhook_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,15 @@ func TestAppRevisionHasChanged(t *testing.T) {
466466
{"dev target revision, dev, did not touch head", getSource("dev"), "dev", false, true},
467467
{"refs/heads/dev target revision, master, touched head", getSource("refs/heads/dev"), "master", true, false},
468468
{"refs/heads/dev target revision, dev, did not touch head", getSource("refs/heads/dev"), "dev", false, true},
469+
{"refs/tags/dev target revision, dev, did not touch head", getSource("refs/tags/dev"), "dev", false, true},
469470
{"env/test target revision, env/test, did not touch head", getSource("env/test"), "env/test", false, true},
470471
{"refs/heads/env/test target revision, env/test, did not touch head", getSource("refs/heads/env/test"), "env/test", false, true},
472+
{"refs/tags/env/test target revision, env/test, did not touch head", getSource("refs/tags/env/test"), "env/test", false, true},
473+
{"three/part/rev target revision, rev, did not touch head", getSource("three/part/rev"), "rev", false, false},
474+
{"1.* target revision (matching), 1.1.0, did not touch head", getSource("1.*"), "1.1.0", false, true},
475+
{"refs/tags/1.* target revision (matching), 1.1.0, did not touch head", getSource("refs/tags/1.*"), "1.1.0", false, true},
476+
{"1.* target revision (not matching), 2.0.0, did not touch head", getSource("1.*"), "2.0.0", false, false},
477+
{"1.* target revision, dev (not semver), did not touch head", getSource("1.*"), "dev", false, false},
471478
}
472479

473480
for _, tc := range testCases {

0 commit comments

Comments
 (0)