From adf0ecd4c0f8e714e98e874d3ad4d238d3412943 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 13 Jun 2023 15:01:34 +0800 Subject: [PATCH 01/19] add DetectedWorkflow struct --- modules/actions/workflows.go | 17 ++++++++++++++--- services/actions/notifier_helper.go | 12 ++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index d9459288b183..f99865071c02 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -29,6 +29,12 @@ func init() { } } +type DetectedWorkflow struct { + Name string + Event *jobparser.Event + Content []byte +} + func IsWorkflow(path string) bool { if (!strings.HasSuffix(path, ".yaml")) && (!strings.HasSuffix(path, ".yml")) { return false @@ -89,13 +95,13 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { return events, nil } -func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) (map[string][]byte, error) { +func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { entries, err := ListWorkflows(commit) if err != nil { return nil, err } - workflows := make(map[string][]byte, len(entries)) + workflows := make([]*DetectedWorkflow, 0, len(entries)) for _, entry := range entries { content, err := GetContentFromEntry(entry) if err != nil { @@ -109,7 +115,12 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy for _, evt := range events { log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { - workflows[entry.Name()] = content + dw := &DetectedWorkflow{ + Name: entry.Name(), + Event: evt, + Content: content, + } + workflows = append(workflows, dw) } } } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 5e41241d18f0..643d228d63dd 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -172,14 +172,18 @@ func notify(ctx context.Context, input *notifyInput) error { } } - for id, content := range workflows { + for _, wf := range workflows { + wfRef := ref + if wf.Event.Name == "pull_request_target" { + wfRef = git.BranchPrefix + input.PullRequest.BaseBranch + } run := &actions_model.ActionRun{ Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], RepoID: input.Repo.ID, OwnerID: input.Repo.OwnerID, - WorkflowID: id, + WorkflowID: wf.Name, TriggerUserID: input.Doer.ID, - Ref: ref, + Ref: wfRef, CommitSHA: commit.ID.String(), IsForkPullRequest: isForkPullRequest, Event: input.Event, @@ -193,7 +197,7 @@ func notify(ctx context.Context, input *notifyInput) error { run.NeedApproval = need } - jobs, err := jobparser.Parse(content) + jobs, err := jobparser.Parse(wf.Content) if err != nil { log.Error("jobparser.Parse: %v", err) continue From 4b75014486a4d321283be285f69450104affb3fe Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Jun 2023 14:17:25 +0800 Subject: [PATCH 02/19] add HookEventPullRequestTarget --- modules/actions/github.go | 1 + modules/actions/workflows.go | 12 ++++-------- modules/webhook/type.go | 3 +++ services/actions/notifier.go | 2 +- services/actions/notifier_helper.go | 22 ++++++++++++++-------- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/modules/actions/github.go b/modules/actions/github.go index f3cb335da98c..5630628e16d8 100644 --- a/modules/actions/github.go +++ b/modules/actions/github.go @@ -49,6 +49,7 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent case githubEventPullRequest, githubEventPullRequestTarget: switch triggedEvent { case webhook_module.HookEventPullRequest, + webhook_module.HookEventPullRequestTarget, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel: diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index f99865071c02..4aa3b59ee69b 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -95,13 +95,13 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { return events, nil } -func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { +func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) (map[string][]byte, error) { entries, err := ListWorkflows(commit) if err != nil { return nil, err } - workflows := make([]*DetectedWorkflow, 0, len(entries)) + workflows := make(map[string][]byte, len(entries)) for _, entry := range entries { content, err := GetContentFromEntry(entry) if err != nil { @@ -115,12 +115,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy for _, evt := range events { log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { - dw := &DetectedWorkflow{ - Name: entry.Name(), - Event: evt, - Content: content, - } - workflows = append(workflows, dw) + workflows[entry.Name()] = content } } } @@ -165,6 +160,7 @@ func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType case // pull_request webhook_module.HookEventPullRequest, + webhook_module.HookEventPullRequestTarget, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel: diff --git a/modules/webhook/type.go b/modules/webhook/type.go index 7042d391b7eb..8b415a728960 100644 --- a/modules/webhook/type.go +++ b/modules/webhook/type.go @@ -27,6 +27,7 @@ const ( HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment" HookEventPullRequestSync HookEventType = "pull_request_sync" HookEventPullRequestReviewRequest HookEventType = "pull_request_review_request" + HookEventPullRequestTarget HookEventType = "pull_request_target" HookEventWiki HookEventType = "wiki" HookEventRepository HookEventType = "repository" HookEventRelease HookEventType = "release" @@ -57,6 +58,8 @@ func (h HookEventType) Event() string { return "pull_request_rejected" case HookEventPullRequestReviewComment: return "pull_request_comment" + case HookEventPullRequestTarget: + return "pull_request_target" case HookEventWiki: return "wiki" case HookEventRepository: diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 536b430b4189..e3ccf47572bd 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -498,7 +498,7 @@ func (n *actionsNotifier) NotifyPullRequestSynchronized(ctx context.Context, doe Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(pr). - Notify(ctx) + NotifyPullRequest(ctx) } func (n *actionsNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 643d228d63dd..d7c6150cb2d6 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -95,6 +95,16 @@ func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyI return input } +func (input *notifyInput) NotifyPullRequest(ctx context.Context) { + // notify with the original event related to pull_request + input.Notify(ctx) + + // notify with the pull_request_target event + input.Event = webhook_module.HookEventPullRequestTarget + input.Ref = git.BranchPrefix + input.PullRequest.BaseBranch + input.Notify(ctx) +} + func (input *notifyInput) Notify(ctx context.Context) { log.Trace("execute %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name) @@ -172,18 +182,14 @@ func notify(ctx context.Context, input *notifyInput) error { } } - for _, wf := range workflows { - wfRef := ref - if wf.Event.Name == "pull_request_target" { - wfRef = git.BranchPrefix + input.PullRequest.BaseBranch - } + for id, content := range workflows { run := &actions_model.ActionRun{ Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], RepoID: input.Repo.ID, OwnerID: input.Repo.OwnerID, - WorkflowID: wf.Name, + WorkflowID: id, TriggerUserID: input.Doer.ID, - Ref: wfRef, + Ref: ref, CommitSHA: commit.ID.String(), IsForkPullRequest: isForkPullRequest, Event: input.Event, @@ -197,7 +203,7 @@ func notify(ctx context.Context, input *notifyInput) error { run.NeedApproval = need } - jobs, err := jobparser.Parse(wf.Content) + jobs, err := jobparser.Parse(content) if err != nil { log.Error("jobparser.Parse: %v", err) continue From 34af97caa6cd48b325c8a5b5d83a51c0e359fd43 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Jun 2023 18:01:01 +0800 Subject: [PATCH 03/19] check pull_request_target in getSecretsOfTask --- routers/api/actions/runner/utils.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index e90213964fd7..9e2a2507ff6b 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/log" secret_module "code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/setting" + webhook_module "code.gitea.io/gitea/modules/webhook" "code.gitea.io/gitea/services/actions" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" @@ -53,7 +54,7 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { secrets := map[string]string{} - if task.Job.Run.IsForkPullRequest { + if task.Job.Run.IsForkPullRequest && task.Job.Run.Event != webhook_module.HookEventPullRequestTarget { // ignore secrets for fork pull request return secrets } From d04133b9a81bf80aec9be7fc5d717bb1e0044ded Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Jun 2023 18:12:27 +0800 Subject: [PATCH 04/19] replace Notify with NotifyPullRequest --- services/actions/notifier.go | 10 +++++----- services/actions/notifier_helper.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index e3ccf47572bd..9d094acd878b 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -82,7 +82,7 @@ func (n *actionsNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *use WithDoer(doer). WithPayload(apiPullRequest). WithPullRequest(issue.PullRequest). - Notify(ctx) + NotifyPullRequest(ctx) return } apiIssue := &api.IssuePayload{ @@ -138,7 +138,7 @@ func (n *actionsNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *use Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(issue.PullRequest). - Notify(ctx) + NotifyPullRequest(ctx) return } newNotifyInputFromIssue(issue, webhook_module.HookEventIssueLabel). @@ -220,7 +220,7 @@ func (n *actionsNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues Sender: convert.ToUser(ctx, pull.Issue.Poster, nil), }). WithPullRequest(pull). - Notify(ctx) + NotifyPullRequest(ctx) } func (n *actionsNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { @@ -344,7 +344,7 @@ func (*actionsNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_m WithRef(pr.MergedCommitID). WithPayload(apiPullRequest). WithPullRequest(pr). - Notify(ctx) + NotifyPullRequest(ctx) } func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { @@ -529,7 +529,7 @@ func (n *actionsNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Contex Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(pr). - Notify(ctx) + NotifyPullRequest(ctx) } func (n *actionsNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index d7c6150cb2d6..12c3db2c0697 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -96,10 +96,10 @@ func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyI } func (input *notifyInput) NotifyPullRequest(ctx context.Context) { - // notify with the original event related to pull_request + // notify with the original `pull_request` related events input.Notify(ctx) - // notify with the pull_request_target event + // notify with the `pull_request_target` event input.Event = webhook_module.HookEventPullRequestTarget input.Ref = git.BranchPrefix + input.PullRequest.BaseBranch input.Notify(ctx) From a696d0825569cd19d42b6de394539c5b43d1f561 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Jun 2023 18:22:03 +0800 Subject: [PATCH 05/19] remove useless struct --- modules/actions/workflows.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 4aa3b59ee69b..a9a9ab89cc69 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -29,12 +29,6 @@ func init() { } } -type DetectedWorkflow struct { - Name string - Event *jobparser.Event - Content []byte -} - func IsWorkflow(path string) bool { if (!strings.HasSuffix(path, ".yaml")) && (!strings.HasSuffix(path, ".yml")) { return false From e44e8b442f2f5bb9a54106b16a8e5c0c52c9e443 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 14 Jun 2023 18:37:50 +0800 Subject: [PATCH 06/19] improve ifNeedApproval for pull_request_target --- services/actions/notifier_helper.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 12c3db2c0697..71e4c79debab 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -269,8 +269,10 @@ func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_mo } func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *repo_model.Repository, user *user_model.User) (bool, error) { - // don't need approval if it's not a fork PR - if !run.IsForkPullRequest { + // 1. don't need approval if it's not a fork PR + // 2. don't need approval if the event is `pull_request_target` since the workflow will run in the context of base branch + // see https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks + if !run.IsForkPullRequest || run.Event == webhook_module.HookEventPullRequestTarget { return false, nil } From 5ed6287d3d44cadd1a6a29b005566fbbb6c6918a Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Thu, 15 Jun 2023 15:50:57 +0800 Subject: [PATCH 07/19] remove HookEventPullRequestTarget and rename GithubEvents --- modules/actions/github.go | 39 ++++++++++++++--------------- modules/actions/github_test.go | 26 +++++++++---------- modules/actions/workflows.go | 1 - modules/actions/workflows_test.go | 22 ++++++++-------- modules/webhook/type.go | 3 --- services/actions/notifier_helper.go | 4 +-- 6 files changed, 45 insertions(+), 50 deletions(-) diff --git a/modules/actions/github.go b/modules/actions/github.go index 5630628e16d8..71f81a89034c 100644 --- a/modules/actions/github.go +++ b/modules/actions/github.go @@ -8,33 +8,33 @@ import ( ) 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" - githubEventGollum = "gollum" + 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" + GithubEventGollum = "gollum" ) // canGithubEventMatch check if the input Github event can match any Gitea event. func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEventType) bool { switch eventName { - case githubEventRegistryPackage: + case GithubEventRegistryPackage: return triggedEvent == webhook_module.HookEventPackage // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum - case githubEventGollum: + case GithubEventGollum: return triggedEvent == webhook_module.HookEventWiki - case githubEventIssues: + case GithubEventIssues: switch triggedEvent { case webhook_module.HookEventIssues, webhook_module.HookEventIssueAssign, @@ -46,10 +46,9 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent return false } - case githubEventPullRequest, githubEventPullRequestTarget: + case GithubEventPullRequest, GithubEventPullRequestTarget: switch triggedEvent { case webhook_module.HookEventPullRequest, - webhook_module.HookEventPullRequestTarget, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel: @@ -59,7 +58,7 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent return false } - case githubEventPullRequestReview: + case GithubEventPullRequestReview: switch triggedEvent { case webhook_module.HookEventPullRequestReviewApproved, webhook_module.HookEventPullRequestReviewComment, diff --git a/modules/actions/github_test.go b/modules/actions/github_test.go index e7f4158ae2d1..4bf55ae03fcc 100644 --- a/modules/actions/github_test.go +++ b/modules/actions/github_test.go @@ -21,85 +21,85 @@ func TestCanGithubEventMatch(t *testing.T) { // registry_package event { "registry_package matches", - githubEventRegistryPackage, + GithubEventRegistryPackage, webhook_module.HookEventPackage, true, }, { "registry_package cannot match", - githubEventRegistryPackage, + GithubEventRegistryPackage, webhook_module.HookEventPush, false, }, // issues event { "issue matches", - githubEventIssues, + GithubEventIssues, webhook_module.HookEventIssueLabel, true, }, { "issue cannot match", - githubEventIssues, + GithubEventIssues, webhook_module.HookEventIssueComment, false, }, // issue_comment event { "issue_comment matches", - githubEventIssueComment, + GithubEventIssueComment, webhook_module.HookEventIssueComment, true, }, { "issue_comment cannot match", - githubEventIssueComment, + GithubEventIssueComment, webhook_module.HookEventIssues, false, }, // pull_request event { "pull_request matches", - githubEventPullRequest, + GithubEventPullRequest, webhook_module.HookEventPullRequestSync, true, }, { "pull_request cannot match", - githubEventPullRequest, + GithubEventPullRequest, webhook_module.HookEventPullRequestComment, false, }, // pull_request_target event { "pull_request_target matches", - githubEventPullRequest, + GithubEventPullRequest, webhook_module.HookEventPullRequest, true, }, { "pull_request_target cannot match", - githubEventPullRequest, + GithubEventPullRequest, webhook_module.HookEventPullRequestComment, false, }, // pull_request_review event { "pull_request_review matches", - githubEventPullRequestReview, + GithubEventPullRequestReview, webhook_module.HookEventPullRequestReviewComment, true, }, { "pull_request_review cannot match", - githubEventPullRequestReview, + GithubEventPullRequestReview, webhook_module.HookEventPullRequestComment, false, }, // other events { "create event", - githubEventCreate, + GithubEventCreate, webhook_module.HookEventCreate, true, }, diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index a9a9ab89cc69..d9459288b183 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -154,7 +154,6 @@ func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType case // pull_request webhook_module.HookEventPullRequest, - webhook_module.HookEventPullRequestTarget, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel: diff --git a/modules/actions/workflows_test.go b/modules/actions/workflows_test.go index 6ef5d5994229..2c374d2c0d0f 100644 --- a/modules/actions/workflows_test.go +++ b/modules/actions/workflows_test.go @@ -23,77 +23,77 @@ func TestDetectMatched(t *testing.T) { expected bool }{ { - desc: "HookEventCreate(create) matches githubEventCreate(create)", + desc: "HookEventCreate(create) matches GithubEventCreate(create)", triggedEvent: webhook_module.HookEventCreate, payload: nil, yamlOn: "on: create", expected: true, }, { - desc: "HookEventIssues(issues) `opened` action matches githubEventIssues(issues)", + desc: "HookEventIssues(issues) `opened` action matches GithubEventIssues(issues)", triggedEvent: webhook_module.HookEventIssues, payload: &api.IssuePayload{Action: api.HookIssueOpened}, yamlOn: "on: issues", expected: true, }, { - desc: "HookEventIssues(issues) `milestoned` action matches githubEventIssues(issues)", + desc: "HookEventIssues(issues) `milestoned` action matches GithubEventIssues(issues)", triggedEvent: webhook_module.HookEventIssues, payload: &api.IssuePayload{Action: api.HookIssueMilestoned}, yamlOn: "on: issues", expected: true, }, { - desc: "HookEventPullRequestSync(pull_request_sync) matches githubEventPullRequest(pull_request)", + desc: "HookEventPullRequestSync(pull_request_sync) matches GithubEventPullRequest(pull_request)", triggedEvent: webhook_module.HookEventPullRequestSync, payload: &api.PullRequestPayload{Action: api.HookIssueSynchronized}, yamlOn: "on: pull_request", expected: true, }, { - desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match githubEventPullRequest(pull_request) with no activity type", + desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match GithubEventPullRequest(pull_request) with no activity type", triggedEvent: webhook_module.HookEventPullRequest, payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated}, yamlOn: "on: pull_request", expected: false, }, { - desc: "HookEventPullRequest(pull_request) `label_updated` action matches githubEventPullRequest(pull_request) with `label` activity type", + desc: "HookEventPullRequest(pull_request) `label_updated` action matches GithubEventPullRequest(pull_request) with `label` activity type", triggedEvent: webhook_module.HookEventPullRequest, payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated}, yamlOn: "on:\n pull_request:\n types: [labeled]", expected: true, }, { - desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches githubEventPullRequestReviewComment(pull_request_review_comment)", + desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches GithubEventPullRequestReviewComment(pull_request_review_comment)", triggedEvent: webhook_module.HookEventPullRequestReviewComment, payload: &api.PullRequestPayload{Action: api.HookIssueReviewed}, yamlOn: "on:\n pull_request_review_comment:\n types: [created]", expected: true, }, { - desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match githubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)", + desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match GithubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)", triggedEvent: webhook_module.HookEventPullRequestReviewRejected, payload: &api.PullRequestPayload{Action: api.HookIssueReviewed}, yamlOn: "on:\n pull_request_review:\n types: [dismissed]", expected: false, }, { - desc: "HookEventRelease(release) `published` action matches githubEventRelease(release) with `published` activity type", + desc: "HookEventRelease(release) `published` action matches GithubEventRelease(release) with `published` activity type", triggedEvent: webhook_module.HookEventRelease, payload: &api.ReleasePayload{Action: api.HookReleasePublished}, yamlOn: "on:\n release:\n types: [published]", expected: true, }, { - desc: "HookEventPackage(package) `created` action doesn't match githubEventRegistryPackage(registry_package) with `updated` activity type", + desc: "HookEventPackage(package) `created` action doesn't match GithubEventRegistryPackage(registry_package) with `updated` activity type", triggedEvent: webhook_module.HookEventPackage, payload: &api.PackagePayload{Action: api.HookPackageCreated}, yamlOn: "on:\n registry_package:\n types: [updated]", expected: false, }, { - desc: "HookEventWiki(wiki) matches githubEventGollum(gollum)", + desc: "HookEventWiki(wiki) matches GithubEventGollum(gollum)", triggedEvent: webhook_module.HookEventWiki, payload: nil, yamlOn: "on: gollum", diff --git a/modules/webhook/type.go b/modules/webhook/type.go index 8b415a728960..7042d391b7eb 100644 --- a/modules/webhook/type.go +++ b/modules/webhook/type.go @@ -27,7 +27,6 @@ const ( HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment" HookEventPullRequestSync HookEventType = "pull_request_sync" HookEventPullRequestReviewRequest HookEventType = "pull_request_review_request" - HookEventPullRequestTarget HookEventType = "pull_request_target" HookEventWiki HookEventType = "wiki" HookEventRepository HookEventType = "repository" HookEventRelease HookEventType = "release" @@ -58,8 +57,6 @@ func (h HookEventType) Event() string { return "pull_request_rejected" case HookEventPullRequestReviewComment: return "pull_request_comment" - case HookEventPullRequestTarget: - return "pull_request_target" case HookEventWiki: return "wiki" case HookEventRepository: diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 71e4c79debab..3d387239e46b 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -100,7 +100,7 @@ func (input *notifyInput) NotifyPullRequest(ctx context.Context) { input.Notify(ctx) // notify with the `pull_request_target` event - input.Event = webhook_module.HookEventPullRequestTarget + // input.Event = webhook_module.HookEventPullRequestTarget input.Ref = git.BranchPrefix + input.PullRequest.BaseBranch input.Notify(ctx) } @@ -272,7 +272,7 @@ func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *rep // 1. don't need approval if it's not a fork PR // 2. don't need approval if the event is `pull_request_target` since the workflow will run in the context of base branch // see https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks - if !run.IsForkPullRequest || run.Event == webhook_module.HookEventPullRequestTarget { + if !run.IsForkPullRequest { return false, nil } From b6ba2d76f963f3c9fb30ec8ce59f4a9dabda010a Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 16 Jun 2023 18:12:09 +0800 Subject: [PATCH 08/19] refactor DetectWorkflows --- modules/actions/workflows.go | 25 ++++++++++++++++++--- routers/api/actions/runner/utils.go | 4 ++-- services/actions/notifier_helper.go | 34 +++++++++++++++++++++++------ 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index d9459288b183..bd2b3dd5535d 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -20,6 +20,14 @@ import ( "gopkg.in/yaml.v3" ) +type DetectedWorkflow struct { + EntryName string + Event *jobparser.Event + Commit *git.Commit + Ref string + Content []byte +} + func init() { model.OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) { // Log the error instead of panic or fatal. @@ -89,13 +97,13 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { return events, nil } -func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) (map[string][]byte, error) { +func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module.HookEventType, payload api.Payloader, isPullRequestTarget bool) ([]*DetectedWorkflow, error) { entries, err := ListWorkflows(commit) if err != nil { return nil, err } - workflows := make(map[string][]byte, len(entries)) + workflows := make([]*DetectedWorkflow, 0, len(entries)) for _, entry := range entries { content, err := GetContentFromEntry(entry) if err != nil { @@ -107,9 +115,20 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy continue } for _, evt := range events { + if isPullRequestTarget && evt.Name != GithubEventPullRequestTarget { + continue + } log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { - workflows[entry.Name()] = content + dwf := &DetectedWorkflow{ + EntryName: entry.Name(), + Event: evt, + Commit: commit, + Ref: ref, + Content: content, + } + workflows = append(workflows, dwf) + // workflows[entry.Name()] = content } } } diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 20a21119cfb7..103819d5680b 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -14,7 +14,6 @@ import ( "code.gitea.io/gitea/modules/log" secret_module "code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/setting" - webhook_module "code.gitea.io/gitea/modules/webhook" "code.gitea.io/gitea/services/actions" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" @@ -54,7 +53,8 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { secrets := map[string]string{} - if task.Job.Run.IsForkPullRequest && task.Job.Run.Event != webhook_module.HookEventPullRequestTarget { + if task.Job.Run.IsForkPullRequest { + // TODO: PullRequestTarget // ignore secrets for fork pull request return secrets } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 3d387239e46b..4d81379b947c 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -152,13 +152,33 @@ func notify(ctx context.Context, input *notifyInput) error { return fmt.Errorf("gitRepo.GetCommit: %w", err) } - workflows, err := actions_module.DetectWorkflows(commit, input.Event, input.Payload) + workflows, err := actions_module.DetectWorkflows(commit, ref, input.Event, input.Payload, false) if err != nil { return fmt.Errorf("DetectWorkflows: %w", err) } - if len(workflows) == 0 { log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID) + } + + if input.PullRequest != nil { + // detect pull_request_target workflows + baseRef := git.BranchPrefix + input.PullRequest.BaseBranch + baseCommit, err := gitRepo.GetCommit(baseRef) + if err != nil { + return fmt.Errorf("gitRepo.GetCommit: %w", err) + } + baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, baseRef, input.Event, input.Payload, true) + if err != nil { + return fmt.Errorf("DetectWorkflows: %w", err) + } + if len(baseWorkflows) == 0 { + log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RepoPath(), baseCommit.ID) + } else { + workflows = append(workflows, baseWorkflows...) + } + } + + if len(workflows) == 0 { return nil } @@ -182,15 +202,15 @@ func notify(ctx context.Context, input *notifyInput) error { } } - for id, content := range workflows { + for _, dwf := range workflows { run := &actions_model.ActionRun{ Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], RepoID: input.Repo.ID, OwnerID: input.Repo.OwnerID, - WorkflowID: id, + WorkflowID: dwf.EntryName, TriggerUserID: input.Doer.ID, - Ref: ref, - CommitSHA: commit.ID.String(), + Ref: dwf.Ref, + CommitSHA: dwf.Commit.ID.String(), IsForkPullRequest: isForkPullRequest, Event: input.Event, EventPayload: string(p), @@ -203,7 +223,7 @@ func notify(ctx context.Context, input *notifyInput) error { run.NeedApproval = need } - jobs, err := jobparser.Parse(content) + jobs, err := jobparser.Parse(dwf.Content) if err != nil { log.Error("jobparser.Parse: %v", err) continue From 35de43e59af81a3a560c87242500ebad3b1c6e03 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 19 Jun 2023 09:08:47 +0800 Subject: [PATCH 09/19] remove commented code --- modules/actions/workflows.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index bd2b3dd5535d..257bf3e2693d 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -128,7 +128,6 @@ func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module Content: content, } workflows = append(workflows, dwf) - // workflows[entry.Name()] = content } } } From dbf8b71ccfa5c419644ae6486058d8e8ffbfe1a3 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 19 Jun 2023 17:38:55 +0800 Subject: [PATCH 10/19] add TriggerEvent --- models/actions/run.go | 1 + models/migrations/migrations.go | 2 ++ models/migrations/v1_21/v261.go | 16 ++++++++++++++++ modules/actions/workflows.go | 20 ++++++++++---------- routers/api/actions/runner/utils.go | 6 +++--- services/actions/notifier.go | 12 ++++++------ services/actions/notifier_helper.go | 13 ++----------- 7 files changed, 40 insertions(+), 30 deletions(-) create mode 100644 models/migrations/v1_21/v261.go diff --git a/models/actions/run.go b/models/actions/run.go index 0654809900c6..fa551978283d 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -41,6 +41,7 @@ type ActionRun struct { ApprovedBy int64 `xorm:"index"` // who approved Event webhook_module.HookEventType EventPayload string `xorm:"LONGTEXT"` + TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow Status Status `xorm:"index"` Started timeutil.TimeStamp Stopped timeutil.TimeStamp diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 4eb512ab49f5..84f89a853310 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -503,6 +503,8 @@ var migrations = []Migration{ // v260 -> v261 NewMigration("Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner), + // v261 -> v262 + NewMigration("Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_21/v261.go b/models/migrations/v1_21/v261.go new file mode 100644 index 000000000000..23e900572a22 --- /dev/null +++ b/models/migrations/v1_21/v261.go @@ -0,0 +1,16 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_21 //nolint + +import ( + "xorm.io/xorm" +) + +func AddTriggerEventToActionRun(x *xorm.Engine) error { + type ActionRun struct { + TriggerEvent string + } + + return x.Sync(new(ActionRun)) +} diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 257bf3e2693d..6d56c932e942 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -21,11 +21,11 @@ import ( ) type DetectedWorkflow struct { - EntryName string - Event *jobparser.Event - Commit *git.Commit - Ref string - Content []byte + EntryName string + TriggerEvent string + Commit *git.Commit + Ref string + Content []byte } func init() { @@ -121,11 +121,11 @@ func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { dwf := &DetectedWorkflow{ - EntryName: entry.Name(), - Event: evt, - Commit: commit, - Ref: ref, - Content: content, + EntryName: entry.Name(), + TriggerEvent: evt.Name, + Commit: commit, + Ref: ref, + Content: content, } workflows = append(workflows, dwf) } diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index 103819d5680b..5df12a3d0ec8 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -9,6 +9,7 @@ import ( actions_model "code.gitea.io/gitea/models/actions" secret_model "code.gitea.io/gitea/models/secret" + actions_module "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -53,8 +54,7 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { secrets := map[string]string{} - if task.Job.Run.IsForkPullRequest { - // TODO: PullRequestTarget + if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { // ignore secrets for fork pull request return secrets } @@ -114,7 +114,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { "base_ref": baseRef, // string, The base_ref or target branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target. "env": "", // string, Path on the runner to the file that sets environment variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions." "event": event, // object, The full event webhook payload. You can access individual properties of the event using this context. This object is identical to the webhook payload of the event that triggered the workflow run, and is different for each event. The webhooks for each GitHub Actions event is linked in "Events that trigger workflows." For example, for a workflow run triggered by the push event, this object contains the contents of the push webhook payload. - "event_name": t.Job.Run.Event.Event(), // string, The name of the event that triggered the workflow run. + "event_name": t.Job.Run.TriggerEvent, // string, The name of the event that triggered the workflow run. "event_path": "", // string, The path to the file on the runner that contains the full event webhook payload. "graphql_url": "", // string, The URL of the GitHub GraphQL API. "head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target. diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 9ff0224834b6..da870bb84c8f 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -82,7 +82,7 @@ func (n *actionsNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *use WithDoer(doer). WithPayload(apiPullRequest). WithPullRequest(issue.PullRequest). - NotifyPullRequest(ctx) + Notify(ctx) return } apiIssue := &api.IssuePayload{ @@ -138,7 +138,7 @@ func (n *actionsNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *use Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(issue.PullRequest). - NotifyPullRequest(ctx) + Notify(ctx) return } newNotifyInputFromIssue(issue, webhook_module.HookEventIssueLabel). @@ -220,7 +220,7 @@ func (n *actionsNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues Sender: convert.ToUser(ctx, pull.Issue.Poster, nil), }). WithPullRequest(pull). - NotifyPullRequest(ctx) + Notify(ctx) } func (n *actionsNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { @@ -344,7 +344,7 @@ func (*actionsNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_m WithRef(pr.MergedCommitID). WithPayload(apiPullRequest). WithPullRequest(pr). - NotifyPullRequest(ctx) + Notify(ctx) } func (n *actionsNotifier) NotifyPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { @@ -498,7 +498,7 @@ func (n *actionsNotifier) NotifyPullRequestSynchronized(ctx context.Context, doe Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(pr). - NotifyPullRequest(ctx) + Notify(ctx) } func (n *actionsNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { @@ -529,7 +529,7 @@ func (n *actionsNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Contex Sender: convert.ToUser(ctx, doer, nil), }). WithPullRequest(pr). - NotifyPullRequest(ctx) + Notify(ctx) } func (n *actionsNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 4d81379b947c..53bcc354beca 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -95,16 +95,6 @@ func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyI return input } -func (input *notifyInput) NotifyPullRequest(ctx context.Context) { - // notify with the original `pull_request` related events - input.Notify(ctx) - - // notify with the `pull_request_target` event - // input.Event = webhook_module.HookEventPullRequestTarget - input.Ref = git.BranchPrefix + input.PullRequest.BaseBranch - input.Notify(ctx) -} - func (input *notifyInput) Notify(ctx context.Context) { log.Trace("execute %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name) @@ -214,6 +204,7 @@ func notify(ctx context.Context, input *notifyInput) error { IsForkPullRequest: isForkPullRequest, Event: input.Event, EventPayload: string(p), + TriggerEvent: dwf.TriggerEvent, Status: actions_model.StatusWaiting, } if need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer); err != nil { @@ -292,7 +283,7 @@ func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *rep // 1. don't need approval if it's not a fork PR // 2. don't need approval if the event is `pull_request_target` since the workflow will run in the context of base branch // see https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks - if !run.IsForkPullRequest { + if !run.IsForkPullRequest || run.TriggerEvent == actions_module.GithubEventPullRequestTarget { return false, nil } From 505a0762c39756d64931ad771c8bbe640eb16378 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 19 Jun 2023 18:33:06 +0800 Subject: [PATCH 11/19] fix DetectWorkflows --- modules/actions/workflows.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 6d56c932e942..71465638067c 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -115,7 +115,8 @@ func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module continue } for _, evt := range events { - if isPullRequestTarget && evt.Name != GithubEventPullRequestTarget { + if isPullRequestTarget && evt.Name != GithubEventPullRequestTarget || + !isPullRequestTarget && evt.Name == GithubEventPullRequestTarget { continue } log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) @@ -128,6 +129,7 @@ func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module Content: content, } workflows = append(workflows, dwf) + break } } } From db642aaae3ccb31ed7f8ff498cc72c104d65ea25 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 20 Jun 2023 17:43:51 +0800 Subject: [PATCH 12/19] fix review --- models/actions/run.go | 14 +++++++------- routers/api/actions/runner/utils.go | 12 +++++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/models/actions/run.go b/models/actions/run.go index fa551978283d..7b62ff884f4c 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -36,13 +36,13 @@ type ActionRun struct { TriggerUser *user_model.User `xorm:"-"` Ref string CommitSHA string - IsForkPullRequest bool // If this is triggered by a PR from a forked repository or an untrusted user, we need to check if it is approved and limit permissions when running the workflow. - NeedApproval bool // may need approval if it's a fork pull request - ApprovedBy int64 `xorm:"index"` // who approved - Event webhook_module.HookEventType - EventPayload string `xorm:"LONGTEXT"` - TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow - Status Status `xorm:"index"` + IsForkPullRequest bool // If this is triggered by a PR from a forked repository or an untrusted user, we need to check if it is approved and limit permissions when running the workflow. + NeedApproval bool // may need approval if it's a fork pull request + ApprovedBy int64 `xorm:"index"` // who approved + Event webhook_module.HookEventType // the webhook event that causes the workflow to run + EventPayload string `xorm:"LONGTEXT"` + TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow + Status Status `xorm:"index"` Started timeutil.TimeStamp Stopped timeutil.TimeStamp Created timeutil.TimeStamp `xorm:"created"` diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index c67276408f6e..49d94563eb7e 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -56,6 +56,8 @@ func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[s secrets := map[string]string{} if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { // ignore secrets for fork pull request + // for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch + // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target return secrets } @@ -93,6 +95,14 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { event := map[string]interface{}{} _ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event) + // TriggerEvent is added in https://github.com/go-gitea/gitea/pull/25229 + // This fallback is for the old ActionRun that doesn't have the TriggerEvent field + // and should be removed in 1.22 + eventName := t.Job.Run.TriggerEvent + if eventName == "" { + eventName = t.Job.Run.Event.Event() + } + baseRef := "" headRef := "" if pullPayload, err := t.Job.Run.GetPullRequestEventPayload(); err == nil && pullPayload.PullRequest != nil && pullPayload.PullRequest.Base != nil && pullPayload.PullRequest.Head != nil { @@ -114,7 +124,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { "base_ref": baseRef, // string, The base_ref or target branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target. "env": "", // string, Path on the runner to the file that sets environment variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions." "event": event, // object, The full event webhook payload. You can access individual properties of the event using this context. This object is identical to the webhook payload of the event that triggered the workflow run, and is different for each event. The webhooks for each GitHub Actions event is linked in "Events that trigger workflows." For example, for a workflow run triggered by the push event, this object contains the contents of the push webhook payload. - "event_name": t.Job.Run.TriggerEvent, // string, The name of the event that triggered the workflow run. + "event_name": eventName, // string, The name of the event that triggered the workflow run. "event_path": "", // string, The path to the file on the runner that contains the full event webhook payload. "graphql_url": "", // string, The URL of the GitHub GraphQL API. "head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target. From bf9646885775707af2cda1995effe7f019fd6ab3 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 20 Jun 2023 18:15:39 +0800 Subject: [PATCH 13/19] improve DetectWorkflows --- modules/actions/workflows.go | 8 +------- services/actions/notifier_helper.go | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 71465638067c..3786f2a274ce 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -97,7 +97,7 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { return events, nil } -func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module.HookEventType, payload api.Payloader, isPullRequestTarget bool) ([]*DetectedWorkflow, error) { +func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { entries, err := ListWorkflows(commit) if err != nil { return nil, err @@ -115,21 +115,15 @@ func DetectWorkflows(commit *git.Commit, ref string, triggedEvent webhook_module continue } for _, evt := range events { - if isPullRequestTarget && evt.Name != GithubEventPullRequestTarget || - !isPullRequestTarget && evt.Name == GithubEventPullRequestTarget { - continue - } log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) if detectMatched(commit, triggedEvent, payload, evt) { dwf := &DetectedWorkflow{ EntryName: entry.Name(), TriggerEvent: evt.Name, Commit: commit, - Ref: ref, Content: content, } workflows = append(workflows, dwf) - break } } } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 53bcc354beca..4dc1b7537a43 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -142,12 +142,20 @@ func notify(ctx context.Context, input *notifyInput) error { return fmt.Errorf("gitRepo.GetCommit: %w", err) } - workflows, err := actions_module.DetectWorkflows(commit, ref, input.Event, input.Payload, false) + var detectedWorkflows []*actions_module.DetectedWorkflow + workflows, err := actions_module.DetectWorkflows(commit, input.Event, input.Payload) if err != nil { return fmt.Errorf("DetectWorkflows: %w", err) } if len(workflows) == 0 { log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID) + } else { + for _, wf := range workflows { + if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget { + wf.Ref = ref + detectedWorkflows = append(detectedWorkflows, wf) + } + } } if input.PullRequest != nil { @@ -157,18 +165,23 @@ func notify(ctx context.Context, input *notifyInput) error { if err != nil { return fmt.Errorf("gitRepo.GetCommit: %w", err) } - baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, baseRef, input.Event, input.Payload, true) + baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, input.Event, input.Payload) if err != nil { return fmt.Errorf("DetectWorkflows: %w", err) } if len(baseWorkflows) == 0 { log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RepoPath(), baseCommit.ID) } else { - workflows = append(workflows, baseWorkflows...) + for _, wf := range baseWorkflows { + if wf.TriggerEvent == actions_module.GithubEventPullRequestTarget { + wf.Ref = baseRef + detectedWorkflows = append(detectedWorkflows, wf) + } + } } } - if len(workflows) == 0 { + if len(detectedWorkflows) == 0 { return nil } @@ -192,7 +205,7 @@ func notify(ctx context.Context, input *notifyInput) error { } } - for _, dwf := range workflows { + for _, dwf := range detectedWorkflows { run := &actions_model.ActionRun{ Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], RepoID: input.Repo.ID, From 96c5acb074778eadcc1703c0d4ad6e0639f92beb Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 25 Jun 2023 18:31:08 +0800 Subject: [PATCH 14/19] add TestPullRequestTargetEvent --- tests/integration/actions_trigger_test.go | 144 ++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 tests/integration/actions_trigger_test.go diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go new file mode 100644 index 000000000000..bbf7ad302e08 --- /dev/null +++ b/tests/integration/actions_trigger_test.go @@ -0,0 +1,144 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/url" + "testing" + "time" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + unit_model "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + actions_module "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/git" + repo_module "code.gitea.io/gitea/modules/repository" + pull_service "code.gitea.io/gitea/services/pull" + repo_service "code.gitea.io/gitea/services/repository" + files_service "code.gitea.io/gitea/services/repository/files" + + "github.com/stretchr/testify/assert" +) + +func TestPullRequestTargetEvent(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo + + // create the base repo + baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ + Name: "repo-pull-request-target", + Description: "test pull-request-target event", + AutoInit: true, + Gitignores: "Go", + License: "MIT", + Readme: "Default", + DefaultBranch: "main", + IsPrivate: false, + }) + assert.NoError(t, err) + assert.NotEmpty(t, baseRepo) + + // enable actions + err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ + RepoID: baseRepo.ID, + Type: unit_model.TypeActions, + }}, nil) + assert.NoError(t, err) + + // create the forked repo + forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ + BaseRepo: baseRepo, + Name: "forked-repo-pull-request-target", + Description: "test pull-request-target event", + }) + assert.NoError(t, err) + assert.NotEmpty(t, forkedRepo) + + // add workflow file to the base repo + addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: ".gitea/workflows/pr.yml", + Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", + }, + }, + Message: "add workflow", + OldBranch: "main", + NewBranch: "main", + Author: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addWorkflowToBaseResp) + + // add a new file to the forked repo + addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "file_1.txt", + Content: "file1", + }, + }, + Message: "add file1", + OldBranch: "main", + NewBranch: "fork-branch-1", + Author: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addFileToForkedResp) + + // create Pull + pullIssue := &issues_model.Issue{ + RepoID: baseRepo.ID, + Title: "Test pull-request-target-event", + PosterID: user3.ID, + Poster: user3, + IsPull: true, + } + pullRequest := &issues_model.PullRequest{ + HeadRepoID: forkedRepo.ID, + BaseRepoID: baseRepo.ID, + HeadBranch: "fork-branch-1", + BaseBranch: "main", + HeadRepo: forkedRepo, + BaseRepo: baseRepo, + Type: issues_model.PullRequestGitea, + } + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) + assert.NoError(t, err) + + // load and compare ActionRun + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) + assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) + assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) + }) +} From bb15a67519cd439b58b331daedef8d233dcd9089 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 25 Jun 2023 21:55:06 +0800 Subject: [PATCH 15/19] put TestPullRequestTargetEvent in unit tests --- modules/actions/actions_trigger_test.go | 143 +++++++++++++++++++++ tests/integration/actions_trigger_test.go | 144 ---------------------- 2 files changed, 143 insertions(+), 144 deletions(-) create mode 100644 modules/actions/actions_trigger_test.go delete mode 100644 tests/integration/actions_trigger_test.go diff --git a/modules/actions/actions_trigger_test.go b/modules/actions/actions_trigger_test.go new file mode 100644 index 000000000000..210fcc709253 --- /dev/null +++ b/modules/actions/actions_trigger_test.go @@ -0,0 +1,143 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions_test + +import ( + "testing" + "time" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + unit_model "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + actions_module "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/git" + repo_module "code.gitea.io/gitea/modules/repository" + pull_service "code.gitea.io/gitea/services/pull" + repo_service "code.gitea.io/gitea/services/repository" + files_service "code.gitea.io/gitea/services/repository/files" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestPullRequestTargetEvent(t *testing.T) { + defer tests.PrepareTestEnv(t)() + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo + + // create the base repo + baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ + Name: "repo-pull-request-target", + Description: "test pull-request-target event", + AutoInit: true, + Gitignores: "Go", + License: "MIT", + Readme: "Default", + DefaultBranch: "main", + IsPrivate: false, + }) + assert.NoError(t, err) + assert.NotEmpty(t, baseRepo) + + // enable actions + err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ + RepoID: baseRepo.ID, + Type: unit_model.TypeActions, + }}, nil) + assert.NoError(t, err) + + // create the forked repo + forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ + BaseRepo: baseRepo, + Name: "forked-repo-pull-request-target", + Description: "test pull-request-target event", + }) + assert.NoError(t, err) + assert.NotEmpty(t, forkedRepo) + + // add workflow file to the base repo + addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: ".gitea/workflows/pr.yml", + Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", + }, + }, + Message: "add workflow", + OldBranch: "main", + NewBranch: "main", + Author: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addWorkflowToBaseResp) + + // add a new file to the forked repo + addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "file_1.txt", + Content: "file1", + }, + }, + Message: "add file1", + OldBranch: "main", + NewBranch: "fork-branch-1", + Author: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addFileToForkedResp) + + // create Pull + pullIssue := &issues_model.Issue{ + RepoID: baseRepo.ID, + Title: "Test pull-request-target-event", + PosterID: user3.ID, + Poster: user3, + IsPull: true, + } + pullRequest := &issues_model.PullRequest{ + HeadRepoID: forkedRepo.ID, + BaseRepoID: baseRepo.ID, + HeadBranch: "fork-branch-1", + BaseBranch: "main", + HeadRepo: forkedRepo, + BaseRepo: baseRepo, + Type: issues_model.PullRequestGitea, + } + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) + assert.NoError(t, err) + + // load and compare ActionRun + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) + assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) + assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) +} diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go deleted file mode 100644 index bbf7ad302e08..000000000000 --- a/tests/integration/actions_trigger_test.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package integration - -import ( - "net/url" - "testing" - "time" - - actions_model "code.gitea.io/gitea/models/actions" - "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" - repo_model "code.gitea.io/gitea/models/repo" - unit_model "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - actions_module "code.gitea.io/gitea/modules/actions" - "code.gitea.io/gitea/modules/git" - repo_module "code.gitea.io/gitea/modules/repository" - pull_service "code.gitea.io/gitea/services/pull" - repo_service "code.gitea.io/gitea/services/repository" - files_service "code.gitea.io/gitea/services/repository/files" - - "github.com/stretchr/testify/assert" -) - -func TestPullRequestTargetEvent(t *testing.T) { - onGiteaRun(t, func(t *testing.T, u *url.URL) { - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo - - // create the base repo - baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ - Name: "repo-pull-request-target", - Description: "test pull-request-target event", - AutoInit: true, - Gitignores: "Go", - License: "MIT", - Readme: "Default", - DefaultBranch: "main", - IsPrivate: false, - }) - assert.NoError(t, err) - assert.NotEmpty(t, baseRepo) - - // enable actions - err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ - RepoID: baseRepo.ID, - Type: unit_model.TypeActions, - }}, nil) - assert.NoError(t, err) - - // create the forked repo - forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ - BaseRepo: baseRepo, - Name: "forked-repo-pull-request-target", - Description: "test pull-request-target event", - }) - assert.NoError(t, err) - assert.NotEmpty(t, forkedRepo) - - // add workflow file to the base repo - addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ - Files: []*files_service.ChangeRepoFile{ - { - Operation: "create", - TreePath: ".gitea/workflows/pr.yml", - Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", - }, - }, - Message: "add workflow", - OldBranch: "main", - NewBranch: "main", - Author: &files_service.IdentityOptions{ - Name: user2.Name, - Email: user2.Email, - }, - Committer: &files_service.IdentityOptions{ - Name: user2.Name, - Email: user2.Email, - }, - Dates: &files_service.CommitDateOptions{ - Author: time.Now(), - Committer: time.Now(), - }, - }) - assert.NoError(t, err) - assert.NotEmpty(t, addWorkflowToBaseResp) - - // add a new file to the forked repo - addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ - Files: []*files_service.ChangeRepoFile{ - { - Operation: "create", - TreePath: "file_1.txt", - Content: "file1", - }, - }, - Message: "add file1", - OldBranch: "main", - NewBranch: "fork-branch-1", - Author: &files_service.IdentityOptions{ - Name: user3.Name, - Email: user3.Email, - }, - Committer: &files_service.IdentityOptions{ - Name: user3.Name, - Email: user3.Email, - }, - Dates: &files_service.CommitDateOptions{ - Author: time.Now(), - Committer: time.Now(), - }, - }) - assert.NoError(t, err) - assert.NotEmpty(t, addFileToForkedResp) - - // create Pull - pullIssue := &issues_model.Issue{ - RepoID: baseRepo.ID, - Title: "Test pull-request-target-event", - PosterID: user3.ID, - Poster: user3, - IsPull: true, - } - pullRequest := &issues_model.PullRequest{ - HeadRepoID: forkedRepo.ID, - BaseRepoID: baseRepo.ID, - HeadBranch: "fork-branch-1", - BaseBranch: "main", - HeadRepo: forkedRepo, - BaseRepo: baseRepo, - Type: issues_model.PullRequestGitea, - } - err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) - assert.NoError(t, err) - - // load and compare ActionRun - actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) - assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) - assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) - }) -} From bf8912404fabf084e1572cb9a83ef7d6fff3320a Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 25 Jun 2023 22:15:56 +0800 Subject: [PATCH 16/19] add main --- modules/actions/actions_trigger_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/actions/actions_trigger_test.go b/modules/actions/actions_trigger_test.go index 210fcc709253..cdabefa3f9a7 100644 --- a/modules/actions/actions_trigger_test.go +++ b/modules/actions/actions_trigger_test.go @@ -4,6 +4,7 @@ package actions_test import ( + "path/filepath" "testing" "time" @@ -25,6 +26,12 @@ import ( "github.com/stretchr/testify/assert" ) +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: filepath.Join("..", "..", ".."), + }) +} + func TestPullRequestTargetEvent(t *testing.T) { defer tests.PrepareTestEnv(t)() user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo From 083a25b366be436ce3e46f46382dda3ec1436778 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 25 Jun 2023 22:35:01 +0800 Subject: [PATCH 17/19] fix path --- modules/actions/actions_trigger_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/actions/actions_trigger_test.go b/modules/actions/actions_trigger_test.go index cdabefa3f9a7..1b06b8d2a62d 100644 --- a/modules/actions/actions_trigger_test.go +++ b/modules/actions/actions_trigger_test.go @@ -28,7 +28,7 @@ import ( func TestMain(m *testing.M) { unittest.MainTest(m, &unittest.TestOptions{ - GiteaRootPath: filepath.Join("..", "..", ".."), + GiteaRootPath: filepath.Join("..", ".."), }) } From 396ed46d4c2c01cf3b0c36efd87966d344b06b2f Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sun, 25 Jun 2023 23:23:24 +0800 Subject: [PATCH 18/19] fix test --- modules/actions/actions_trigger_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/actions/actions_trigger_test.go b/modules/actions/actions_trigger_test.go index 1b06b8d2a62d..858dcc1090ae 100644 --- a/modules/actions/actions_trigger_test.go +++ b/modules/actions/actions_trigger_test.go @@ -21,7 +21,6 @@ import ( pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" files_service "code.gitea.io/gitea/services/repository/files" - "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" ) @@ -33,7 +32,8 @@ func TestMain(m *testing.M) { } func TestPullRequestTargetEvent(t *testing.T) { - defer tests.PrepareTestEnv(t)() + assert.NoError(t, unittest.PrepareTestDatabase()) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo From c272a775f8ff2c58e3c538e0bedb5ee5fa3a16f4 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Mon, 26 Jun 2023 12:28:26 +0800 Subject: [PATCH 19/19] move TestPullRequestTargetEvent to integration tests --- modules/actions/actions_trigger_test.go | 150 ---------------------- tests/integration/actions_trigger_test.go | 144 +++++++++++++++++++++ 2 files changed, 144 insertions(+), 150 deletions(-) delete mode 100644 modules/actions/actions_trigger_test.go create mode 100644 tests/integration/actions_trigger_test.go diff --git a/modules/actions/actions_trigger_test.go b/modules/actions/actions_trigger_test.go deleted file mode 100644 index 858dcc1090ae..000000000000 --- a/modules/actions/actions_trigger_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2023 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package actions_test - -import ( - "path/filepath" - "testing" - "time" - - actions_model "code.gitea.io/gitea/models/actions" - "code.gitea.io/gitea/models/db" - issues_model "code.gitea.io/gitea/models/issues" - repo_model "code.gitea.io/gitea/models/repo" - unit_model "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" - actions_module "code.gitea.io/gitea/modules/actions" - "code.gitea.io/gitea/modules/git" - repo_module "code.gitea.io/gitea/modules/repository" - pull_service "code.gitea.io/gitea/services/pull" - repo_service "code.gitea.io/gitea/services/repository" - files_service "code.gitea.io/gitea/services/repository/files" - - "github.com/stretchr/testify/assert" -) - -func TestMain(m *testing.M) { - unittest.MainTest(m, &unittest.TestOptions{ - GiteaRootPath: filepath.Join("..", ".."), - }) -} - -func TestPullRequestTargetEvent(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo - user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo - - // create the base repo - baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ - Name: "repo-pull-request-target", - Description: "test pull-request-target event", - AutoInit: true, - Gitignores: "Go", - License: "MIT", - Readme: "Default", - DefaultBranch: "main", - IsPrivate: false, - }) - assert.NoError(t, err) - assert.NotEmpty(t, baseRepo) - - // enable actions - err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ - RepoID: baseRepo.ID, - Type: unit_model.TypeActions, - }}, nil) - assert.NoError(t, err) - - // create the forked repo - forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ - BaseRepo: baseRepo, - Name: "forked-repo-pull-request-target", - Description: "test pull-request-target event", - }) - assert.NoError(t, err) - assert.NotEmpty(t, forkedRepo) - - // add workflow file to the base repo - addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ - Files: []*files_service.ChangeRepoFile{ - { - Operation: "create", - TreePath: ".gitea/workflows/pr.yml", - Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", - }, - }, - Message: "add workflow", - OldBranch: "main", - NewBranch: "main", - Author: &files_service.IdentityOptions{ - Name: user2.Name, - Email: user2.Email, - }, - Committer: &files_service.IdentityOptions{ - Name: user2.Name, - Email: user2.Email, - }, - Dates: &files_service.CommitDateOptions{ - Author: time.Now(), - Committer: time.Now(), - }, - }) - assert.NoError(t, err) - assert.NotEmpty(t, addWorkflowToBaseResp) - - // add a new file to the forked repo - addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ - Files: []*files_service.ChangeRepoFile{ - { - Operation: "create", - TreePath: "file_1.txt", - Content: "file1", - }, - }, - Message: "add file1", - OldBranch: "main", - NewBranch: "fork-branch-1", - Author: &files_service.IdentityOptions{ - Name: user3.Name, - Email: user3.Email, - }, - Committer: &files_service.IdentityOptions{ - Name: user3.Name, - Email: user3.Email, - }, - Dates: &files_service.CommitDateOptions{ - Author: time.Now(), - Committer: time.Now(), - }, - }) - assert.NoError(t, err) - assert.NotEmpty(t, addFileToForkedResp) - - // create Pull - pullIssue := &issues_model.Issue{ - RepoID: baseRepo.ID, - Title: "Test pull-request-target-event", - PosterID: user3.ID, - Poster: user3, - IsPull: true, - } - pullRequest := &issues_model.PullRequest{ - HeadRepoID: forkedRepo.ID, - BaseRepoID: baseRepo.ID, - HeadBranch: "fork-branch-1", - BaseBranch: "main", - HeadRepo: forkedRepo, - BaseRepo: baseRepo, - Type: issues_model.PullRequestGitea, - } - err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) - assert.NoError(t, err) - - // load and compare ActionRun - actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) - assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) - assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) -} diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go new file mode 100644 index 000000000000..bbf7ad302e08 --- /dev/null +++ b/tests/integration/actions_trigger_test.go @@ -0,0 +1,144 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/url" + "testing" + "time" + + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + unit_model "code.gitea.io/gitea/models/unit" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + actions_module "code.gitea.io/gitea/modules/actions" + "code.gitea.io/gitea/modules/git" + repo_module "code.gitea.io/gitea/modules/repository" + pull_service "code.gitea.io/gitea/services/pull" + repo_service "code.gitea.io/gitea/services/repository" + files_service "code.gitea.io/gitea/services/repository/files" + + "github.com/stretchr/testify/assert" +) + +func TestPullRequestTargetEvent(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo + + // create the base repo + baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ + Name: "repo-pull-request-target", + Description: "test pull-request-target event", + AutoInit: true, + Gitignores: "Go", + License: "MIT", + Readme: "Default", + DefaultBranch: "main", + IsPrivate: false, + }) + assert.NoError(t, err) + assert.NotEmpty(t, baseRepo) + + // enable actions + err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ + RepoID: baseRepo.ID, + Type: unit_model.TypeActions, + }}, nil) + assert.NoError(t, err) + + // create the forked repo + forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ + BaseRepo: baseRepo, + Name: "forked-repo-pull-request-target", + Description: "test pull-request-target event", + }) + assert.NoError(t, err) + assert.NotEmpty(t, forkedRepo) + + // add workflow file to the base repo + addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: ".gitea/workflows/pr.yml", + Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", + }, + }, + Message: "add workflow", + OldBranch: "main", + NewBranch: "main", + Author: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user2.Name, + Email: user2.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addWorkflowToBaseResp) + + // add a new file to the forked repo + addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "file_1.txt", + Content: "file1", + }, + }, + Message: "add file1", + OldBranch: "main", + NewBranch: "fork-branch-1", + Author: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addFileToForkedResp) + + // create Pull + pullIssue := &issues_model.Issue{ + RepoID: baseRepo.ID, + Title: "Test pull-request-target-event", + PosterID: user3.ID, + Poster: user3, + IsPull: true, + } + pullRequest := &issues_model.PullRequest{ + HeadRepoID: forkedRepo.ID, + BaseRepoID: baseRepo.ID, + HeadBranch: "fork-branch-1", + BaseBranch: "main", + HeadRepo: forkedRepo, + BaseRepo: baseRepo, + Type: issues_model.PullRequestGitea, + } + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) + assert.NoError(t, err) + + // load and compare ActionRun + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) + assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) + assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) + }) +}