diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 738026142b94..1b8b6cc7efb9 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -16,6 +16,7 @@ import ( "github.com/gobwas/glob" "github.com/nektos/act/pkg/jobparser" "github.com/nektos/act/pkg/model" + "github.com/nektos/act/pkg/workflowpattern" ) func ListWorkflows(commit *git.Commit) (git.Entries, error) { @@ -152,40 +153,94 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa } matchTimes := 0 + hasBranchFilter := false + hasTagFilter := false + refName := git.RefName(pushPayload.Ref) // all acts conditions should be satisfied for cond, vals := range evt.Acts { switch cond { - case "branches", "tags": - refShortName := git.RefName(pushPayload.Ref).ShortName() - for _, val := range vals { - if glob.MustCompile(val, '/').Match(refShortName) { - matchTimes++ - break - } + case "branches": + hasBranchFilter = true + if !refName.IsBranch() { + break + } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + case "branches-ignore": + hasBranchFilter = true + if !refName.IsBranch() { + break + } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + case "tags": + hasTagFilter = true + if !refName.IsTag() { + break + } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + case "tags-ignore": + hasTagFilter = true + if !refName.IsTag() { + break + } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ } case "paths": filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) if err != nil { log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) } else { - for _, val := range vals { - matched := false - for _, file := range filesChanged { - if glob.MustCompile(val, '/').Match(file) { - matched = true - break - } - } - if matched { - matchTimes++ - break - } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Skip(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + } + case "paths-ignore": + filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) + if err != nil { + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + } else { + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Filter(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ } } default: log.Warn("push event unsupported condition %q", cond) } } + // if both branch and tag filter are defined in the workflow only one needs to match + if hasBranchFilter && hasTagFilter { + matchTimes++ + } return matchTimes == len(evt.Acts) } @@ -237,30 +292,47 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload } } case "branches": - refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName() - for _, val := range vals { - if glob.MustCompile(val, '/').Match(refShortName) { - matchTimes++ - break - } + refName := git.RefName(prPayload.PullRequest.Base.Ref) + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Skip(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + case "branches-ignore": + refName := git.RefName(prPayload.PullRequest.Base.Ref) + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Filter(patterns, []string{refName.ShortName()}, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ } case "paths": filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) if err != nil { log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) } else { - for _, val := range vals { - matched := false - for _, file := range filesChanged { - if glob.MustCompile(val, '/').Match(file) { - matched = true - break - } - } - if matched { - matchTimes++ - break - } + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Skip(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ + } + } + case "paths-ignore": + filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + if err != nil { + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + } else { + patterns, err := workflowpattern.CompilePatterns(vals...) + if err != nil { + break + } + if !workflowpattern.Filter(patterns, filesChanged, &workflowpattern.EmptyTraceWriter{}) { + matchTimes++ } } default: