loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Support `pull_request_target` event (#25229)

Fix #25088

This PR adds the support for
[`pull_request_target`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target)
workflow trigger. `pull_request_target` is similar to `pull_request`,
but the workflow triggered by the `pull_request_target` event runs in
the context of the base branch of the pull request rather than the head
branch. Since the workflow from the base is considered trusted, it can
access the secrets and doesn't need approvals to run.

authored by

Zettat123 and committed by
GitHub
48e5a74f e409e14b

+286 -63
+7 -6
models/actions/run.go
··· 36 36 TriggerUser *user_model.User `xorm:"-"` 37 37 Ref string 38 38 CommitSHA string 39 - 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. 40 - NeedApproval bool // may need approval if it's a fork pull request 41 - ApprovedBy int64 `xorm:"index"` // who approved 42 - Event webhook_module.HookEventType 43 - EventPayload string `xorm:"LONGTEXT"` 44 - Status Status `xorm:"index"` 39 + 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. 40 + NeedApproval bool // may need approval if it's a fork pull request 41 + ApprovedBy int64 `xorm:"index"` // who approved 42 + Event webhook_module.HookEventType // the webhook event that causes the workflow to run 43 + EventPayload string `xorm:"LONGTEXT"` 44 + TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow 45 + Status Status `xorm:"index"` 45 46 Started timeutil.TimeStamp 46 47 Stopped timeutil.TimeStamp 47 48 Created timeutil.TimeStamp `xorm:"created"`
+2 -1
models/migrations/migrations.go
··· 503 503 504 504 // v260 -> v261 505 505 NewMigration("Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner), 506 - 507 506 // v261 -> v262 508 507 NewMigration("Add variable table", v1_21.CreateVariableTable), 508 + // v262 -> v263 509 + NewMigration("Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun), 509 510 } 510 511 511 512 // GetCurrentDBVersion returns the current db version
+16
models/migrations/v1_21/v262.go
··· 1 + // Copyright 2023 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package v1_21 //nolint 5 + 6 + import ( 7 + "xorm.io/xorm" 8 + ) 9 + 10 + func AddTriggerEventToActionRun(x *xorm.Engine) error { 11 + type ActionRun struct { 12 + TriggerEvent string 13 + } 14 + 15 + return x.Sync(new(ActionRun)) 16 + }
+19 -19
modules/actions/github.go
··· 8 8 ) 9 9 10 10 const ( 11 - githubEventPullRequest = "pull_request" 12 - githubEventPullRequestTarget = "pull_request_target" 13 - githubEventPullRequestReviewComment = "pull_request_review_comment" 14 - githubEventPullRequestReview = "pull_request_review" 15 - githubEventRegistryPackage = "registry_package" 16 - githubEventCreate = "create" 17 - githubEventDelete = "delete" 18 - githubEventFork = "fork" 19 - githubEventPush = "push" 20 - githubEventIssues = "issues" 21 - githubEventIssueComment = "issue_comment" 22 - githubEventRelease = "release" 23 - githubEventPullRequestComment = "pull_request_comment" 24 - githubEventGollum = "gollum" 11 + GithubEventPullRequest = "pull_request" 12 + GithubEventPullRequestTarget = "pull_request_target" 13 + GithubEventPullRequestReviewComment = "pull_request_review_comment" 14 + GithubEventPullRequestReview = "pull_request_review" 15 + GithubEventRegistryPackage = "registry_package" 16 + GithubEventCreate = "create" 17 + GithubEventDelete = "delete" 18 + GithubEventFork = "fork" 19 + GithubEventPush = "push" 20 + GithubEventIssues = "issues" 21 + GithubEventIssueComment = "issue_comment" 22 + GithubEventRelease = "release" 23 + GithubEventPullRequestComment = "pull_request_comment" 24 + GithubEventGollum = "gollum" 25 25 ) 26 26 27 27 // canGithubEventMatch check if the input Github event can match any Gitea event. 28 28 func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEventType) bool { 29 29 switch eventName { 30 - case githubEventRegistryPackage: 30 + case GithubEventRegistryPackage: 31 31 return triggedEvent == webhook_module.HookEventPackage 32 32 33 33 // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum 34 - case githubEventGollum: 34 + case GithubEventGollum: 35 35 return triggedEvent == webhook_module.HookEventWiki 36 36 37 - case githubEventIssues: 37 + case GithubEventIssues: 38 38 switch triggedEvent { 39 39 case webhook_module.HookEventIssues, 40 40 webhook_module.HookEventIssueAssign, ··· 46 46 return false 47 47 } 48 48 49 - case githubEventPullRequest, githubEventPullRequestTarget: 49 + case GithubEventPullRequest, GithubEventPullRequestTarget: 50 50 switch triggedEvent { 51 51 case webhook_module.HookEventPullRequest, 52 52 webhook_module.HookEventPullRequestSync, ··· 58 58 return false 59 59 } 60 60 61 - case githubEventPullRequestReview: 61 + case GithubEventPullRequestReview: 62 62 switch triggedEvent { 63 63 case webhook_module.HookEventPullRequestReviewApproved, 64 64 webhook_module.HookEventPullRequestReviewComment,
+13 -13
modules/actions/github_test.go
··· 21 21 // registry_package event 22 22 { 23 23 "registry_package matches", 24 - githubEventRegistryPackage, 24 + GithubEventRegistryPackage, 25 25 webhook_module.HookEventPackage, 26 26 true, 27 27 }, 28 28 { 29 29 "registry_package cannot match", 30 - githubEventRegistryPackage, 30 + GithubEventRegistryPackage, 31 31 webhook_module.HookEventPush, 32 32 false, 33 33 }, 34 34 // issues event 35 35 { 36 36 "issue matches", 37 - githubEventIssues, 37 + GithubEventIssues, 38 38 webhook_module.HookEventIssueLabel, 39 39 true, 40 40 }, 41 41 { 42 42 "issue cannot match", 43 - githubEventIssues, 43 + GithubEventIssues, 44 44 webhook_module.HookEventIssueComment, 45 45 false, 46 46 }, 47 47 // issue_comment event 48 48 { 49 49 "issue_comment matches", 50 - githubEventIssueComment, 50 + GithubEventIssueComment, 51 51 webhook_module.HookEventIssueComment, 52 52 true, 53 53 }, 54 54 { 55 55 "issue_comment cannot match", 56 - githubEventIssueComment, 56 + GithubEventIssueComment, 57 57 webhook_module.HookEventIssues, 58 58 false, 59 59 }, 60 60 // pull_request event 61 61 { 62 62 "pull_request matches", 63 - githubEventPullRequest, 63 + GithubEventPullRequest, 64 64 webhook_module.HookEventPullRequestSync, 65 65 true, 66 66 }, 67 67 { 68 68 "pull_request cannot match", 69 - githubEventPullRequest, 69 + GithubEventPullRequest, 70 70 webhook_module.HookEventPullRequestComment, 71 71 false, 72 72 }, 73 73 // pull_request_target event 74 74 { 75 75 "pull_request_target matches", 76 - githubEventPullRequest, 76 + GithubEventPullRequest, 77 77 webhook_module.HookEventPullRequest, 78 78 true, 79 79 }, 80 80 { 81 81 "pull_request_target cannot match", 82 - githubEventPullRequest, 82 + GithubEventPullRequest, 83 83 webhook_module.HookEventPullRequestComment, 84 84 false, 85 85 }, 86 86 // pull_request_review event 87 87 { 88 88 "pull_request_review matches", 89 - githubEventPullRequestReview, 89 + GithubEventPullRequestReview, 90 90 webhook_module.HookEventPullRequestReviewComment, 91 91 true, 92 92 }, 93 93 { 94 94 "pull_request_review cannot match", 95 - githubEventPullRequestReview, 95 + GithubEventPullRequestReview, 96 96 webhook_module.HookEventPullRequestComment, 97 97 false, 98 98 }, 99 99 // other events 100 100 { 101 101 "create event", 102 - githubEventCreate, 102 + GithubEventCreate, 103 103 webhook_module.HookEventCreate, 104 104 true, 105 105 },
+17 -3
modules/actions/workflows.go
··· 20 20 "gopkg.in/yaml.v3" 21 21 ) 22 22 23 + type DetectedWorkflow struct { 24 + EntryName string 25 + TriggerEvent string 26 + Commit *git.Commit 27 + Ref string 28 + Content []byte 29 + } 30 + 23 31 func init() { 24 32 model.OnDecodeNodeError = func(node yaml.Node, out interface{}, err error) { 25 33 // Log the error instead of panic or fatal. ··· 89 97 return events, nil 90 98 } 91 99 92 - func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) (map[string][]byte, error) { 100 + func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { 93 101 entries, err := ListWorkflows(commit) 94 102 if err != nil { 95 103 return nil, err 96 104 } 97 105 98 - workflows := make(map[string][]byte, len(entries)) 106 + workflows := make([]*DetectedWorkflow, 0, len(entries)) 99 107 for _, entry := range entries { 100 108 content, err := GetContentFromEntry(entry) 101 109 if err != nil { ··· 109 117 for _, evt := range events { 110 118 log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) 111 119 if detectMatched(commit, triggedEvent, payload, evt) { 112 - workflows[entry.Name()] = content 120 + dwf := &DetectedWorkflow{ 121 + EntryName: entry.Name(), 122 + TriggerEvent: evt.Name, 123 + Commit: commit, 124 + Content: content, 125 + } 126 + workflows = append(workflows, dwf) 113 127 } 114 128 } 115 129 }
+11 -11
modules/actions/workflows_test.go
··· 23 23 expected bool 24 24 }{ 25 25 { 26 - desc: "HookEventCreate(create) matches githubEventCreate(create)", 26 + desc: "HookEventCreate(create) matches GithubEventCreate(create)", 27 27 triggedEvent: webhook_module.HookEventCreate, 28 28 payload: nil, 29 29 yamlOn: "on: create", 30 30 expected: true, 31 31 }, 32 32 { 33 - desc: "HookEventIssues(issues) `opened` action matches githubEventIssues(issues)", 33 + desc: "HookEventIssues(issues) `opened` action matches GithubEventIssues(issues)", 34 34 triggedEvent: webhook_module.HookEventIssues, 35 35 payload: &api.IssuePayload{Action: api.HookIssueOpened}, 36 36 yamlOn: "on: issues", 37 37 expected: true, 38 38 }, 39 39 { 40 - desc: "HookEventIssues(issues) `milestoned` action matches githubEventIssues(issues)", 40 + desc: "HookEventIssues(issues) `milestoned` action matches GithubEventIssues(issues)", 41 41 triggedEvent: webhook_module.HookEventIssues, 42 42 payload: &api.IssuePayload{Action: api.HookIssueMilestoned}, 43 43 yamlOn: "on: issues", 44 44 expected: true, 45 45 }, 46 46 { 47 - desc: "HookEventPullRequestSync(pull_request_sync) matches githubEventPullRequest(pull_request)", 47 + desc: "HookEventPullRequestSync(pull_request_sync) matches GithubEventPullRequest(pull_request)", 48 48 triggedEvent: webhook_module.HookEventPullRequestSync, 49 49 payload: &api.PullRequestPayload{Action: api.HookIssueSynchronized}, 50 50 yamlOn: "on: pull_request", 51 51 expected: true, 52 52 }, 53 53 { 54 - desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match githubEventPullRequest(pull_request) with no activity type", 54 + desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match GithubEventPullRequest(pull_request) with no activity type", 55 55 triggedEvent: webhook_module.HookEventPullRequest, 56 56 payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated}, 57 57 yamlOn: "on: pull_request", 58 58 expected: false, 59 59 }, 60 60 { 61 - desc: "HookEventPullRequest(pull_request) `label_updated` action matches githubEventPullRequest(pull_request) with `label` activity type", 61 + desc: "HookEventPullRequest(pull_request) `label_updated` action matches GithubEventPullRequest(pull_request) with `label` activity type", 62 62 triggedEvent: webhook_module.HookEventPullRequest, 63 63 payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated}, 64 64 yamlOn: "on:\n pull_request:\n types: [labeled]", 65 65 expected: true, 66 66 }, 67 67 { 68 - desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches githubEventPullRequestReviewComment(pull_request_review_comment)", 68 + desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches GithubEventPullRequestReviewComment(pull_request_review_comment)", 69 69 triggedEvent: webhook_module.HookEventPullRequestReviewComment, 70 70 payload: &api.PullRequestPayload{Action: api.HookIssueReviewed}, 71 71 yamlOn: "on:\n pull_request_review_comment:\n types: [created]", 72 72 expected: true, 73 73 }, 74 74 { 75 - desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match githubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)", 75 + desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match GithubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)", 76 76 triggedEvent: webhook_module.HookEventPullRequestReviewRejected, 77 77 payload: &api.PullRequestPayload{Action: api.HookIssueReviewed}, 78 78 yamlOn: "on:\n pull_request_review:\n types: [dismissed]", 79 79 expected: false, 80 80 }, 81 81 { 82 - desc: "HookEventRelease(release) `published` action matches githubEventRelease(release) with `published` activity type", 82 + desc: "HookEventRelease(release) `published` action matches GithubEventRelease(release) with `published` activity type", 83 83 triggedEvent: webhook_module.HookEventRelease, 84 84 payload: &api.ReleasePayload{Action: api.HookReleasePublished}, 85 85 yamlOn: "on:\n release:\n types: [published]", 86 86 expected: true, 87 87 }, 88 88 { 89 - desc: "HookEventPackage(package) `created` action doesn't match githubEventRegistryPackage(registry_package) with `updated` activity type", 89 + desc: "HookEventPackage(package) `created` action doesn't match GithubEventRegistryPackage(registry_package) with `updated` activity type", 90 90 triggedEvent: webhook_module.HookEventPackage, 91 91 payload: &api.PackagePayload{Action: api.HookPackageCreated}, 92 92 yamlOn: "on:\n registry_package:\n types: [updated]", 93 93 expected: false, 94 94 }, 95 95 { 96 - desc: "HookEventWiki(wiki) matches githubEventGollum(gollum)", 96 + desc: "HookEventWiki(wiki) matches GithubEventGollum(gollum)", 97 97 triggedEvent: webhook_module.HookEventWiki, 98 98 payload: nil, 99 99 yamlOn: "on: gollum",
+13 -2
routers/api/actions/runner/utils.go
··· 9 9 10 10 actions_model "code.gitea.io/gitea/models/actions" 11 11 secret_model "code.gitea.io/gitea/models/secret" 12 + actions_module "code.gitea.io/gitea/modules/actions" 12 13 "code.gitea.io/gitea/modules/git" 13 14 "code.gitea.io/gitea/modules/json" 14 15 "code.gitea.io/gitea/modules/log" ··· 54 55 55 56 func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { 56 57 secrets := map[string]string{} 57 - if task.Job.Run.IsForkPullRequest { 58 + if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { 58 59 // ignore secrets for fork pull request 60 + // 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 61 + // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target 59 62 return secrets 60 63 } 61 64 ··· 116 119 event := map[string]interface{}{} 117 120 _ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event) 118 121 122 + // TriggerEvent is added in https://github.com/go-gitea/gitea/pull/25229 123 + // This fallback is for the old ActionRun that doesn't have the TriggerEvent field 124 + // and should be removed in 1.22 125 + eventName := t.Job.Run.TriggerEvent 126 + if eventName == "" { 127 + eventName = t.Job.Run.Event.Event() 128 + } 129 + 119 130 baseRef := "" 120 131 headRef := "" 121 132 if pullPayload, err := t.Job.Run.GetPullRequestEventPayload(); err == nil && pullPayload.PullRequest != nil && pullPayload.PullRequest.Base != nil && pullPayload.PullRequest.Head != nil { ··· 137 148 "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. 138 149 "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." 139 150 "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. 140 - "event_name": t.Job.Run.Event.Event(), // string, The name of the event that triggered the workflow run. 151 + "event_name": eventName, // string, The name of the event that triggered the workflow run. 141 152 "event_path": "", // string, The path to the file on the runner that contains the full event webhook payload. 142 153 "graphql_url": "", // string, The URL of the GitHub GraphQL API. 143 154 "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.
+44 -8
services/actions/notifier_helper.go
··· 142 142 return fmt.Errorf("gitRepo.GetCommit: %w", err) 143 143 } 144 144 145 + var detectedWorkflows []*actions_module.DetectedWorkflow 145 146 workflows, err := actions_module.DetectWorkflows(commit, input.Event, input.Payload) 146 147 if err != nil { 147 148 return fmt.Errorf("DetectWorkflows: %w", err) 148 149 } 149 - 150 150 if len(workflows) == 0 { 151 151 log.Trace("repo %s with commit %s couldn't find workflows", input.Repo.RepoPath(), commit.ID) 152 + } else { 153 + for _, wf := range workflows { 154 + if wf.TriggerEvent != actions_module.GithubEventPullRequestTarget { 155 + wf.Ref = ref 156 + detectedWorkflows = append(detectedWorkflows, wf) 157 + } 158 + } 159 + } 160 + 161 + if input.PullRequest != nil { 162 + // detect pull_request_target workflows 163 + baseRef := git.BranchPrefix + input.PullRequest.BaseBranch 164 + baseCommit, err := gitRepo.GetCommit(baseRef) 165 + if err != nil { 166 + return fmt.Errorf("gitRepo.GetCommit: %w", err) 167 + } 168 + baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, input.Event, input.Payload) 169 + if err != nil { 170 + return fmt.Errorf("DetectWorkflows: %w", err) 171 + } 172 + if len(baseWorkflows) == 0 { 173 + log.Trace("repo %s with commit %s couldn't find pull_request_target workflows", input.Repo.RepoPath(), baseCommit.ID) 174 + } else { 175 + for _, wf := range baseWorkflows { 176 + if wf.TriggerEvent == actions_module.GithubEventPullRequestTarget { 177 + wf.Ref = baseRef 178 + detectedWorkflows = append(detectedWorkflows, wf) 179 + } 180 + } 181 + } 182 + } 183 + 184 + if len(detectedWorkflows) == 0 { 152 185 return nil 153 186 } 154 187 ··· 172 205 } 173 206 } 174 207 175 - for id, content := range workflows { 208 + for _, dwf := range detectedWorkflows { 176 209 run := &actions_model.ActionRun{ 177 210 Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0], 178 211 RepoID: input.Repo.ID, 179 212 OwnerID: input.Repo.OwnerID, 180 - WorkflowID: id, 213 + WorkflowID: dwf.EntryName, 181 214 TriggerUserID: input.Doer.ID, 182 - Ref: ref, 183 - CommitSHA: commit.ID.String(), 215 + Ref: dwf.Ref, 216 + CommitSHA: dwf.Commit.ID.String(), 184 217 IsForkPullRequest: isForkPullRequest, 185 218 Event: input.Event, 186 219 EventPayload: string(p), 220 + TriggerEvent: dwf.TriggerEvent, 187 221 Status: actions_model.StatusWaiting, 188 222 } 189 223 if need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer); err != nil { ··· 193 227 run.NeedApproval = need 194 228 } 195 229 196 - jobs, err := jobparser.Parse(content) 230 + jobs, err := jobparser.Parse(dwf.Content) 197 231 if err != nil { 198 232 log.Error("jobparser.Parse: %v", err) 199 233 continue ··· 259 293 } 260 294 261 295 func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *repo_model.Repository, user *user_model.User) (bool, error) { 262 - // don't need approval if it's not a fork PR 263 - if !run.IsForkPullRequest { 296 + // 1. don't need approval if it's not a fork PR 297 + // 2. don't need approval if the event is `pull_request_target` since the workflow will run in the context of base branch 298 + // see https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks 299 + if !run.IsForkPullRequest || run.TriggerEvent == actions_module.GithubEventPullRequestTarget { 264 300 return false, nil 265 301 } 266 302
+144
tests/integration/actions_trigger_test.go
··· 1 + // Copyright 2023 The Gitea Authors. All rights reserved. 2 + // SPDX-License-Identifier: MIT 3 + 4 + package integration 5 + 6 + import ( 7 + "net/url" 8 + "testing" 9 + "time" 10 + 11 + actions_model "code.gitea.io/gitea/models/actions" 12 + "code.gitea.io/gitea/models/db" 13 + issues_model "code.gitea.io/gitea/models/issues" 14 + repo_model "code.gitea.io/gitea/models/repo" 15 + unit_model "code.gitea.io/gitea/models/unit" 16 + "code.gitea.io/gitea/models/unittest" 17 + user_model "code.gitea.io/gitea/models/user" 18 + actions_module "code.gitea.io/gitea/modules/actions" 19 + "code.gitea.io/gitea/modules/git" 20 + repo_module "code.gitea.io/gitea/modules/repository" 21 + pull_service "code.gitea.io/gitea/services/pull" 22 + repo_service "code.gitea.io/gitea/services/repository" 23 + files_service "code.gitea.io/gitea/services/repository/files" 24 + 25 + "github.com/stretchr/testify/assert" 26 + ) 27 + 28 + func TestPullRequestTargetEvent(t *testing.T) { 29 + onGiteaRun(t, func(t *testing.T, u *url.URL) { 30 + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the base repo 31 + user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the forked repo 32 + 33 + // create the base repo 34 + baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_module.CreateRepoOptions{ 35 + Name: "repo-pull-request-target", 36 + Description: "test pull-request-target event", 37 + AutoInit: true, 38 + Gitignores: "Go", 39 + License: "MIT", 40 + Readme: "Default", 41 + DefaultBranch: "main", 42 + IsPrivate: false, 43 + }) 44 + assert.NoError(t, err) 45 + assert.NotEmpty(t, baseRepo) 46 + 47 + // enable actions 48 + err = repo_model.UpdateRepositoryUnits(baseRepo, []repo_model.RepoUnit{{ 49 + RepoID: baseRepo.ID, 50 + Type: unit_model.TypeActions, 51 + }}, nil) 52 + assert.NoError(t, err) 53 + 54 + // create the forked repo 55 + forkedRepo, err := repo_service.ForkRepository(git.DefaultContext, user2, user3, repo_service.ForkRepoOptions{ 56 + BaseRepo: baseRepo, 57 + Name: "forked-repo-pull-request-target", 58 + Description: "test pull-request-target event", 59 + }) 60 + assert.NoError(t, err) 61 + assert.NotEmpty(t, forkedRepo) 62 + 63 + // add workflow file to the base repo 64 + addWorkflowToBaseResp, err := files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, user2, &files_service.ChangeRepoFilesOptions{ 65 + Files: []*files_service.ChangeRepoFile{ 66 + { 67 + Operation: "create", 68 + TreePath: ".gitea/workflows/pr.yml", 69 + Content: "name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n", 70 + }, 71 + }, 72 + Message: "add workflow", 73 + OldBranch: "main", 74 + NewBranch: "main", 75 + Author: &files_service.IdentityOptions{ 76 + Name: user2.Name, 77 + Email: user2.Email, 78 + }, 79 + Committer: &files_service.IdentityOptions{ 80 + Name: user2.Name, 81 + Email: user2.Email, 82 + }, 83 + Dates: &files_service.CommitDateOptions{ 84 + Author: time.Now(), 85 + Committer: time.Now(), 86 + }, 87 + }) 88 + assert.NoError(t, err) 89 + assert.NotEmpty(t, addWorkflowToBaseResp) 90 + 91 + // add a new file to the forked repo 92 + addFileToForkedResp, err := files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ 93 + Files: []*files_service.ChangeRepoFile{ 94 + { 95 + Operation: "create", 96 + TreePath: "file_1.txt", 97 + Content: "file1", 98 + }, 99 + }, 100 + Message: "add file1", 101 + OldBranch: "main", 102 + NewBranch: "fork-branch-1", 103 + Author: &files_service.IdentityOptions{ 104 + Name: user3.Name, 105 + Email: user3.Email, 106 + }, 107 + Committer: &files_service.IdentityOptions{ 108 + Name: user3.Name, 109 + Email: user3.Email, 110 + }, 111 + Dates: &files_service.CommitDateOptions{ 112 + Author: time.Now(), 113 + Committer: time.Now(), 114 + }, 115 + }) 116 + assert.NoError(t, err) 117 + assert.NotEmpty(t, addFileToForkedResp) 118 + 119 + // create Pull 120 + pullIssue := &issues_model.Issue{ 121 + RepoID: baseRepo.ID, 122 + Title: "Test pull-request-target-event", 123 + PosterID: user3.ID, 124 + Poster: user3, 125 + IsPull: true, 126 + } 127 + pullRequest := &issues_model.PullRequest{ 128 + HeadRepoID: forkedRepo.ID, 129 + BaseRepoID: baseRepo.ID, 130 + HeadBranch: "fork-branch-1", 131 + BaseBranch: "main", 132 + HeadRepo: forkedRepo, 133 + BaseRepo: baseRepo, 134 + Type: issues_model.PullRequestGitea, 135 + } 136 + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) 137 + assert.NoError(t, err) 138 + 139 + // load and compare ActionRun 140 + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) 141 + assert.Equal(t, addWorkflowToBaseResp.Commit.SHA, actionRun.CommitSHA) 142 + assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) 143 + }) 144 + }