Convert GitHub event on actions and fix some pull_request events. (#23037) (#23471)

Backport #23037 by @lunny

Follow #22680

Partially Fix #22958, on pull_request, `opened`, `reopened`,
`synchronize` supported, `edited` hasn't been supported yet because
Gitea doesn't trigger that events.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: yp05327 <576951401@qq.com>
release
Giteabot 2023-03-14 22:43:10 -04:00 committed by GitHub
parent 28af02eea0
commit 31efbafbe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 212 additions and 114 deletions

@ -0,0 +1,41 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package actions
import (
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/nektos/act/pkg/jobparser"
)
const (
githubEventPullRequest = "pull_request"
githubEventPullRequestTarget = "pull_request_target"
githubEventPullRequestReviewComment = "pull_request_review_comment"
githubEventPullRequestReview = "pull_request_review"
githubEventRegistryPackage = "registry_package"
githubEventCreate = "create"
githubEventDelete = "delete"
githubEventFork = "fork"
githubEventPush = "push"
githubEventIssues = "issues"
githubEventIssueComment = "issue_comment"
githubEventRelease = "release"
githubEventPullRequestComment = "pull_request_comment"
)
func convertFromGithubEvent(evt *jobparser.Event) string {
switch evt.Name {
case githubEventPullRequest, githubEventPullRequestTarget, githubEventPullRequestReview,
githubEventPullRequestReviewComment:
return string(webhook_module.HookEventPullRequest)
case githubEventRegistryPackage:
return string(webhook_module.HookEventPackage)
case githubEventCreate, githubEventDelete, githubEventFork, githubEventPush,
githubEventIssues, githubEventIssueComment, githubEventRelease, githubEventPullRequestComment:
fallthrough
default:
return evt.Name
}
}

@ -72,9 +72,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
continue continue
} }
for _, evt := range events { for _, evt := range events {
if evt.Name != triggedEvent.Event() { log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
continue
}
if detectMatched(commit, triggedEvent, payload, evt) { if detectMatched(commit, triggedEvent, payload, evt) {
workflows[entry.Name()] = content workflows[entry.Name()] = content
} }
@ -85,138 +83,197 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
} }
func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
if len(evt.Acts) == 0 { if convertFromGithubEvent(evt) != string(triggedEvent) {
return true return false
} }
switch triggedEvent { switch triggedEvent {
case webhook_module.HookEventCreate: case webhook_module.HookEventCreate,
fallthrough webhook_module.HookEventDelete,
case webhook_module.HookEventDelete: webhook_module.HookEventFork,
fallthrough webhook_module.HookEventIssueAssign,
case webhook_module.HookEventFork: webhook_module.HookEventIssueLabel,
log.Warn("unsupported event %q", triggedEvent.Event()) webhook_module.HookEventIssueMilestone,
return false webhook_module.HookEventPullRequestAssign,
webhook_module.HookEventPullRequestLabel,
webhook_module.HookEventPullRequestMilestone,
webhook_module.HookEventPullRequestComment,
webhook_module.HookEventPullRequestReviewApproved,
webhook_module.HookEventPullRequestReviewRejected,
webhook_module.HookEventPullRequestReviewComment,
webhook_module.HookEventWiki,
webhook_module.HookEventRepository,
webhook_module.HookEventRelease,
webhook_module.HookEventPackage:
if len(evt.Acts) != 0 {
log.Warn("Ignore unsupported %s event arguments %q", triggedEvent, evt.Acts)
}
// no special filter parameters for these events, just return true if name matched
return true
case webhook_module.HookEventPush: case webhook_module.HookEventPush:
pushPayload := payload.(*api.PushPayload) return matchPushEvent(commit, payload.(*api.PushPayload), evt)
matchTimes := 0
// all acts conditions should be satisfied case webhook_module.HookEventIssues:
for cond, vals := range evt.Acts { return matchIssuesEvent(commit, payload.(*api.IssuePayload), evt)
switch cond {
case "branches", "tags": case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync:
refShortName := git.RefName(pushPayload.Ref).ShortName() return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt)
case webhook_module.HookEventIssueComment:
return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt)
default:
log.Warn("unsupported event %q", triggedEvent)
return false
}
}
func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool {
// with no special filter parameters
if len(evt.Acts) == 0 {
return true
}
matchTimes := 0
// 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 "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 { for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) { matched := false
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) {
matched = true
break
}
}
if matched {
matchTimes++ matchTimes++
break break
} }
} }
case "paths": }
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before) default:
if err != nil { log.Warn("push event unsupported condition %q", cond)
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) }
} else { }
for _, val := range vals { return matchTimes == len(evt.Acts)
matched := false }
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) { func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *jobparser.Event) bool {
matched = true // with no special filter parameters
break if len(evt.Acts) == 0 {
} return true
} }
if matched {
matchTimes++ matchTimes := 0
break // all acts conditions should be satisfied
} for cond, vals := range evt.Acts {
} switch cond {
case "types":
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(issuePayload.Action)) {
matchTimes++
break
} }
default:
log.Warn("unsupported condition %q", cond)
} }
default:
log.Warn("issue event unsupported condition %q", cond)
} }
return matchTimes == len(evt.Acts) }
return matchTimes == len(evt.Acts)
}
case webhook_module.HookEventIssues: func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
fallthrough // with no special filter parameters
case webhook_module.HookEventIssueAssign: if len(evt.Acts) == 0 {
fallthrough // defaultly, only pull request opened and synchronized will trigger workflow
case webhook_module.HookEventIssueLabel: return prPayload.Action == api.HookIssueSynchronized || prPayload.Action == api.HookIssueOpened
fallthrough }
case webhook_module.HookEventIssueMilestone:
fallthrough matchTimes := 0
case webhook_module.HookEventIssueComment: // all acts conditions should be satisfied
fallthrough for cond, vals := range evt.Acts {
case webhook_module.HookEventPullRequest: switch cond {
prPayload := payload.(*api.PullRequestPayload) case "types":
matchTimes := 0 action := prPayload.Action
// all acts conditions should be satisfied if prPayload.Action == api.HookIssueSynchronized {
for cond, vals := range evt.Acts { action = "synchronize"
switch cond { }
case "types": log.Trace("matching pull_request %s with %v", action, vals)
for _, val := range vals { for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(prPayload.Action)) { if glob.MustCompile(val, '/').Match(string(action)) {
matchTimes++ matchTimes++
break break
} }
}
case "branches":
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName()
for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) {
matchTimes++
break
} }
case "branches": }
refShortName := git.RefName(prPayload.PullRequest.Base.Ref).ShortName() 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 { for _, val := range vals {
if glob.MustCompile(val, '/').Match(refShortName) { matched := false
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) {
matched = true
break
}
}
if matched {
matchTimes++ matchTimes++
break break
} }
} }
case "paths": }
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) default:
if err != nil { log.Warn("pull request event unsupported condition %q", cond)
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) }
} else { }
for _, val := range vals { return matchTimes == len(evt.Acts)
matched := false }
for _, file := range filesChanged {
if glob.MustCompile(val, '/').Match(file) { func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool {
matched = true // with no special filter parameters
break if len(evt.Acts) == 0 {
} return true
} }
if matched {
matchTimes++ matchTimes := 0
break // all acts conditions should be satisfied
} for cond, vals := range evt.Acts {
} switch cond {
case "types":
for _, val := range vals {
if glob.MustCompile(val, '/').Match(string(issueCommentPayload.Action)) {
matchTimes++
break
} }
default:
log.Warn("unsupported condition %q", cond)
} }
default:
log.Warn("issue comment unsupported condition %q", cond)
} }
return matchTimes == len(evt.Acts)
case webhook_module.HookEventPullRequestAssign:
fallthrough
case webhook_module.HookEventPullRequestLabel:
fallthrough
case webhook_module.HookEventPullRequestMilestone:
fallthrough
case webhook_module.HookEventPullRequestComment:
fallthrough
case webhook_module.HookEventPullRequestReviewApproved:
fallthrough
case webhook_module.HookEventPullRequestReviewRejected:
fallthrough
case webhook_module.HookEventPullRequestReviewComment:
fallthrough
case webhook_module.HookEventPullRequestSync:
fallthrough
case webhook_module.HookEventWiki:
fallthrough
case webhook_module.HookEventRepository:
fallthrough
case webhook_module.HookEventRelease:
fallthrough
case webhook_module.HookEventPackage:
fallthrough
default:
log.Warn("unsupported event %q", triggedEvent.Event())
} }
return false return matchTimes == len(evt.Acts)
} }