Skip to content

Commit b064dc4

Browse files
committed
feat: add wildcard suport for repository
1 parent f05bcd0 commit b064dc4

3 files changed

Lines changed: 182 additions & 2 deletions

File tree

pkg/matcher/repo_runinfo_matcher.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ func MatchEventURLRepo(ctx context.Context, cs *params.Run, event *info.Event, n
2525
}
2626
for _, repo := range repositories.Items {
2727
repo.Spec.URL = strings.TrimSuffix(repo.Spec.URL, "/")
28-
if repo.Spec.URL == event.URL {
28+
match, err := matchRepo(event.URL, repo.Spec.URL)
29+
if err != nil {
30+
return nil, err
31+
}
32+
if match {
2933
return &repo, nil
3034
}
3135
}
32-
3336
return nil, nil
3437
}
3538

@@ -89,3 +92,20 @@ func matchTarget(branch, target string) (bool, error) {
8992

9093
return g.Match(branch), nil
9194
}
95+
96+
// matchTarget checks if a branch matches a target pattern using glob matching.
97+
// Supports both exact string matching and glob patterns.
98+
func matchRepo(repo, target string) (bool, error) {
99+
if target == repo {
100+
return true, nil
101+
}
102+
// Check unix glob match
103+
globPattern, err := glob.Compile(target)
104+
if err != nil {
105+
return false, err
106+
}
107+
if globPattern.Match(repo) {
108+
return true, nil
109+
}
110+
return false, nil
111+
}

pkg/matcher/repo_runinfo_matcher_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,103 @@ func TestIncomingWebhookRule(t *testing.T) {
468468
}
469469
}
470470

471+
func TestMatchRepo(t *testing.T) {
472+
tests := []struct {
473+
name string
474+
eventURL string
475+
repoURL string
476+
wantMatch bool
477+
wantError bool
478+
errorCheck string
479+
}{
480+
// Exact matching
481+
{
482+
name: "exact match",
483+
eventURL: "https://github.com/tektoncd/pipelines-as-code",
484+
repoURL: "https://github.com/tektoncd/pipelines-as-code",
485+
wantMatch: true,
486+
},
487+
{
488+
name: "no substring match",
489+
eventURL: "https://github.com/forked/pipelines-as-code",
490+
repoURL: "https://github.com/tektoncd/pipelines-as-code",
491+
wantMatch: false,
492+
},
493+
// Wildcard * - matches zero or more characters
494+
{
495+
name: "glob * - prefix pattern",
496+
eventURL: "https://github.com/tektoncd/pipelines-as-code",
497+
repoURL: "https://github.com/tektoncd/*",
498+
wantMatch: true,
499+
},
500+
{
501+
name: "glob * - must match from start",
502+
eventURL: "https://gitlab.com/tektoncd/pipelines-as-code",
503+
repoURL: "https://github.com/tektoncd/*",
504+
wantMatch: false,
505+
},
506+
{
507+
name: "glob * - substring match with wildcards",
508+
eventURL: "https://github.com/tektoncd/pipelines-as-code",
509+
repoURL: "*/tektoncd/*",
510+
wantMatch: true,
511+
},
512+
{
513+
name: "glob * - catch-all",
514+
eventURL: "https://github.com/tektoncd/pipelines-as-code",
515+
repoURL: "*",
516+
wantMatch: true,
517+
},
518+
// Wildcard ? - matches exactly one character
519+
{
520+
name: "glob ? - single char match",
521+
eventURL: "https://github.com/tektoncd/pipelines-as-code-v2",
522+
repoURL: "https://github.com/tektoncd/pipelines-as-code-v?",
523+
wantMatch: true,
524+
},
525+
// Character classes [...]
526+
{
527+
name: "glob [range] - character class",
528+
eventURL: "https://gitlab.com/tektoncd/pipelines-as-code",
529+
repoURL: "https://[a-z]*.com/tektoncd/pipelines-as-code",
530+
wantMatch: true,
531+
},
532+
// Error handling
533+
{
534+
name: "invalid glob - unclosed bracket",
535+
eventURL: "https://github.com/tektoncd/pipelines-as-code",
536+
repoURL: "https://[github.com/tektoncd/pipelines-as-code",
537+
wantMatch: false,
538+
wantError: true,
539+
errorCheck: "unexpected end of input",
540+
},
541+
}
542+
543+
for _, tt := range tests {
544+
t.Run(tt.name, func(t *testing.T) {
545+
gotMatch, err := matchRepo(tt.eventURL, tt.repoURL)
546+
547+
if tt.wantError {
548+
if err == nil {
549+
t.Errorf("matchRepo() expected error but got nil")
550+
return
551+
}
552+
if tt.errorCheck != "" {
553+
assert.ErrorContains(t, err, tt.errorCheck)
554+
}
555+
} else {
556+
if err != nil {
557+
t.Errorf("matchRepo() unexpected error = %v", err)
558+
return
559+
}
560+
if gotMatch != tt.wantMatch {
561+
t.Errorf("matchRepo() gotMatch = %v, want %v for eventURL=%q, repoURL=%q", gotMatch, tt.wantMatch, tt.eventURL, tt.repoURL)
562+
}
563+
}
564+
})
565+
}
566+
}
567+
471568
func TestMatchTarget(t *testing.T) {
472569
tests := []struct {
473570
name string

pkg/webhook/validation_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,66 @@ func TestReconcilerAdmit(t *testing.T) {
220220
})
221221
}
222222
}
223+
224+
func TestMatchRepo(t *testing.T) {
225+
tests := []struct {
226+
name string
227+
url string
228+
wantError bool
229+
errorCheck string
230+
}{
231+
// Exact matching
232+
{
233+
name: "std https",
234+
url: "https://github.com/tektoncd/pipelines-as-code",
235+
wantError: false,
236+
},
237+
{
238+
name: "std http",
239+
url: "http://github.com/tektoncd/pipelines-as-code",
240+
wantError: false,
241+
},
242+
// Wildcard * - matches zero or more characters
243+
{
244+
name: "glob * - prefix pattern",
245+
url: "https://github.com/tektoncd/*",
246+
wantError: false,
247+
},
248+
{
249+
name: "glob * - domain",
250+
url: "https://*/tektoncd/pipelines-as-code",
251+
wantError: false,
252+
},
253+
{
254+
name: "std not github ",
255+
url: "https://gitlab.com/tektoncd/pipelines-as-code",
256+
wantError: false,
257+
},
258+
{
259+
name: "std not github deep path",
260+
url: "https://gitlab.com/tektoncd/group/pipelines-as-code",
261+
wantError: false,
262+
},
263+
}
264+
265+
for _, tt := range tests {
266+
t.Run(tt.name, func(t *testing.T) {
267+
err := validateRepositoryURL(tt.url, "")
268+
269+
if tt.wantError {
270+
if err == nil {
271+
t.Errorf("validateRepositoryURL() expected error but got nil")
272+
return
273+
}
274+
if tt.errorCheck != "" {
275+
assert.ErrorContains(t, err, tt.errorCheck)
276+
}
277+
} else {
278+
if err != nil {
279+
t.Errorf("validateRepositoryURL() unexpected error = %v", err)
280+
return
281+
}
282+
}
283+
})
284+
}
285+
}

0 commit comments

Comments
 (0)