Skip to content

Commit 35039b8

Browse files
Use GitHub Actions compatible globbing for branches, tag, path filter (#22804) (#23740)
Backport #22804 by @ChristopherHX Replaces the current globbing library with a https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet compatible one. This adds support for - `paths-ignore`, `tags-ignore` and `branches-ignore` filters. - negative patterns in `paths`, `tags` and `branches` filters - using both `tags` and `paths` filter on the push event Original PR https://gitea.com/gitea/act/pulls/13. nektos/act PR nektos/act#1618 for the workflowpattern package (It can take some months for it to appear in https://gitea.com/gitea/act) Related to #13539 Co-authored-by: ChristopherHX <christopher.homberger@web.de>
1 parent 62afc0a commit 35039b8

File tree

1 file changed

+107
-35
lines changed

1 file changed

+107
-35
lines changed

modules/actions/workflows.go

+107-35
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/gobwas/glob"
1717
"github.com/nektos/act/pkg/jobparser"
1818
"github.com/nektos/act/pkg/model"
19+
"github.com/nektos/act/pkg/workflowpattern"
1920
)
2021

2122
func ListWorkflows(commit *git.Commit) (git.Entries, error) {
@@ -136,40 +137,94 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
136137
}
137138

138139
matchTimes := 0
140+
hasBranchFilter := false
141+
hasTagFilter := false
142+
refName := git.RefName(pushPayload.Ref)
139143
// all acts conditions should be satisfied
140144
for cond, vals := range evt.Acts {
141145
switch cond {
142-
case "branches", "tags":
143-
refShortName := git.RefName(pushPayload.Ref).ShortName()
144-
for _, val := range vals {
145-
if glob.MustCompile(val, '/').Match(refShortName) {
146-
matchTimes++
146+
case "branches":
147+
hasBranchFilter = true
148+
if !refName.IsBranch() {
149+
break
150+
}
151+
patterns, err := workflowpattern.CompilePatterns(vals...)
152+
if err != nil {
153+
break
154+
}
155+
if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
156+
matchTimes++
157+
}
158+
case "branches-ignore":
159+
hasBranchFilter = true
160+
if !refName.IsBranch() {
161+
break
162+
}
163+
patterns, err := workflowpattern.CompilePatterns(vals...)
164+
if err != nil {
165+
break
166+
}
167+
if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
168+
matchTimes++
169+
}
170+
case "tags":
171+
hasTagFilter = true
172+
if !refName.IsTag() {
173+
break
174+
}
175+
patterns, err := workflowpattern.CompilePatterns(vals...)
176+
if err != nil {
177+
break
178+
}
179+
if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
180+
matchTimes++
181+
}
182+
case "tags-ignore":
183+
hasTagFilter = true
184+
if !refName.IsTag() {
185+
break
186+
}
187+
patterns, err := workflowpattern.CompilePatterns(vals...)
188+
if err != nil {
189+
break
190+
}
191+
if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
192+
matchTimes++
193+
}
194+
case "paths":
195+
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
196+
if err != nil {
197+
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
198+
} else {
199+
patterns, err := workflowpattern.CompilePatterns(vals...)
200+
if err != nil {
147201
break
148202
}
203+
if !workflowpattern.Skip(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) {
204+
matchTimes++
205+
}
149206
}
150-
case "paths":
207+
case "paths-ignore":
151208
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
152209
if err != nil {
153210
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
154211
} else {
155-
for _, val := range vals {
156-
matched := false
157-
for _, file := range filesChanged {
158-
if glob.MustCompile(val, '/').Match(file) {
159-
matched = true
160-
break
161-
}
162-
}
163-
if matched {
164-
matchTimes++
165-
break
166-
}
212+
patterns, err := workflowpattern.CompilePatterns(vals...)
213+
if err != nil {
214+
break
215+
}
216+
if !workflowpattern.Filter(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) {
217+
matchTimes++
167218
}
168219
}
169220
default:
170221
log.Warn("push event unsupported condition %q", cond)
171222
}
172223
}
224+
// if both branch and tag filter are defined in the workflow only one needs to match
225+
if hasBranchFilter && hasTagFilter {
226+
matchTimes++
227+
}
173228
return matchTimes == len(evt.Acts)
174229
}
175230

@@ -221,30 +276,47 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload
221276
}
222277
}
223278
case "branches":
224-
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
225-
for _, val := range vals {
226-
if glob.MustCompile(val, '/').Match(refShortName) {
227-
matchTimes++
279+
refName := git.RefName(prPayload.PullRequest.Base.Ref)
280+
patterns, err := workflowpattern.CompilePatterns(vals...)
281+
if err != nil {
282+
break
283+
}
284+
if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
285+
matchTimes++
286+
}
287+
case "branches-ignore":
288+
refName := git.RefName(prPayload.PullRequest.Base.Ref)
289+
patterns, err := workflowpattern.CompilePatterns(vals...)
290+
if err != nil {
291+
break
292+
}
293+
if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) {
294+
matchTimes++
295+
}
296+
case "paths":
297+
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
298+
if err != nil {
299+
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
300+
} else {
301+
patterns, err := workflowpattern.CompilePatterns(vals...)
302+
if err != nil {
228303
break
229304
}
305+
if !workflowpattern.Skip(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) {
306+
matchTimes++
307+
}
230308
}
231-
case "paths":
309+
case "paths-ignore":
232310
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
233311
if err != nil {
234312
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
235313
} else {
236-
for _, val := range vals {
237-
matched := false
238-
for _, file := range filesChanged {
239-
if glob.MustCompile(val, '/').Match(file) {
240-
matched = true
241-
break
242-
}
243-
}
244-
if matched {
245-
matchTimes++
246-
break
247-
}
314+
patterns, err := workflowpattern.CompilePatterns(vals...)
315+
if err != nil {
316+
break
317+
}
318+
if !workflowpattern.Filter(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) {
319+
matchTimes++
248320
}
249321
}
250322
default:

0 commit comments

Comments
 (0)