Fix the bug when getting files changed for pull_request_target
event (#26320)
Follow #25229 Copy from https://github.com/go-gitea/gitea/pull/26290#issuecomment-1663135186 The bug is that we cannot get changed files for the `pull_request_target` event. This event runs in the context of the base branch, so we won't get any changes if we call `GetFilesChangedSinceCommit` with `PullRequest.Base.Ref`.
This commit is contained in:
parent
5db4c8db93
commit
9a8af92577
4 changed files with 77 additions and 13 deletions
|
@ -95,7 +95,7 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) {
|
||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) {
|
func DetectWorkflows(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) {
|
||||||
entries, err := ListWorkflows(commit)
|
entries, err := ListWorkflows(commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -114,7 +114,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
|
||||||
}
|
}
|
||||||
for _, evt := range events {
|
for _, evt := range events {
|
||||||
log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
|
log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent)
|
||||||
if detectMatched(commit, triggedEvent, payload, evt) {
|
if detectMatched(gitRepo, commit, triggedEvent, payload, evt) {
|
||||||
dwf := &DetectedWorkflow{
|
dwf := &DetectedWorkflow{
|
||||||
EntryName: entry.Name(),
|
EntryName: entry.Name(),
|
||||||
TriggerEvent: evt.Name,
|
TriggerEvent: evt.Name,
|
||||||
|
@ -128,7 +128,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy
|
||||||
return workflows, nil
|
return workflows, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
|
func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool {
|
||||||
if !canGithubEventMatch(evt.Name, triggedEvent) {
|
if !canGithubEventMatch(evt.Name, triggedEvent) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType
|
||||||
webhook_module.HookEventPullRequestSync,
|
webhook_module.HookEventPullRequestSync,
|
||||||
webhook_module.HookEventPullRequestAssign,
|
webhook_module.HookEventPullRequestAssign,
|
||||||
webhook_module.HookEventPullRequestLabel:
|
webhook_module.HookEventPullRequestLabel:
|
||||||
return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt)
|
return matchPullRequestEvent(gitRepo, commit, payload.(*api.PullRequestPayload), evt)
|
||||||
|
|
||||||
case // pull_request_review
|
case // pull_request_review
|
||||||
webhook_module.HookEventPullRequestReviewApproved,
|
webhook_module.HookEventPullRequestReviewApproved,
|
||||||
|
@ -331,7 +331,7 @@ func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *j
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
||||||
acts := evt.Acts()
|
acts := evt.Acts()
|
||||||
activityTypeMatched := false
|
activityTypeMatched := false
|
||||||
matchTimes := 0
|
matchTimes := 0
|
||||||
|
@ -370,6 +370,18 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
headCommit = commit
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if evt.Name == GithubEventPullRequestTarget && (len(acts["paths"]) > 0 || len(acts["paths-ignore"]) > 0) {
|
||||||
|
headCommit, err = gitRepo.GetCommit(prPayload.PullRequest.Head.Sha)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetCommit [ref: %s]: %v", prPayload.PullRequest.Head.Sha, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// all acts conditions should be satisfied
|
// all acts conditions should be satisfied
|
||||||
for cond, vals := range acts {
|
for cond, vals := range acts {
|
||||||
switch cond {
|
switch cond {
|
||||||
|
@ -392,9 +404,9 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload
|
||||||
matchTimes++
|
matchTimes++
|
||||||
}
|
}
|
||||||
case "paths":
|
case "paths":
|
||||||
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
|
||||||
} else {
|
} else {
|
||||||
patterns, err := workflowpattern.CompilePatterns(vals...)
|
patterns, err := workflowpattern.CompilePatterns(vals...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -405,9 +417,9 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "paths-ignore":
|
case "paths-ignore":
|
||||||
filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
|
||||||
} else {
|
} else {
|
||||||
patterns, err := workflowpattern.CompilePatterns(vals...)
|
patterns, err := workflowpattern.CompilePatterns(vals...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -125,7 +125,7 @@ func TestDetectMatched(t *testing.T) {
|
||||||
evts, err := GetEventsFromContent([]byte(tc.yamlOn))
|
evts, err := GetEventsFromContent([]byte(tc.yamlOn))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, evts, 1)
|
assert.Len(t, evts, 1)
|
||||||
assert.Equal(t, tc.expected, detectMatched(tc.commit, tc.triggedEvent, tc.payload, evts[0]))
|
assert.Equal(t, tc.expected, detectMatched(nil, tc.commit, tc.triggedEvent, tc.payload, evts[0]))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var detectedWorkflows []*actions_module.DetectedWorkflow
|
var detectedWorkflows []*actions_module.DetectedWorkflow
|
||||||
workflows, err := actions_module.DetectWorkflows(commit, input.Event, input.Payload)
|
workflows, err := actions_module.DetectWorkflows(gitRepo, commit, input.Event, input.Payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("DetectWorkflows: %w", err)
|
return fmt.Errorf("DetectWorkflows: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("gitRepo.GetCommit: %w", err)
|
return fmt.Errorf("gitRepo.GetCommit: %w", err)
|
||||||
}
|
}
|
||||||
baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, input.Event, input.Payload)
|
baseWorkflows, err := actions_module.DetectWorkflows(gitRepo, baseCommit, input.Event, input.Payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("DetectWorkflows: %w", err)
|
return fmt.Errorf("DetectWorkflows: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ func TestPullRequestTargetEvent(t *testing.T) {
|
||||||
{
|
{
|
||||||
Operation: "create",
|
Operation: "create",
|
||||||
TreePath: ".gitea/workflows/pr.yml",
|
TreePath: ".gitea/workflows/pr.yml",
|
||||||
ContentReader: strings.NewReader("name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
|
ContentReader: strings.NewReader("name: test\non:\n pull_request_target:\n paths:\n - 'file_*.txt'\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Message: "add workflow",
|
Message: "add workflow",
|
||||||
|
@ -138,8 +138,60 @@ func TestPullRequestTargetEvent(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// load and compare ActionRun
|
// load and compare ActionRun
|
||||||
|
assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}))
|
||||||
actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID})
|
actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID})
|
||||||
assert.Equal(t, addFileToForkedResp.Commit.SHA, actionRun.CommitSHA)
|
assert.Equal(t, addFileToForkedResp.Commit.SHA, actionRun.CommitSHA)
|
||||||
assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent)
|
assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent)
|
||||||
|
|
||||||
|
// add another file whose name cannot match the specified path
|
||||||
|
addFileToForkedResp, err = files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{
|
||||||
|
Files: []*files_service.ChangeRepoFile{
|
||||||
|
{
|
||||||
|
Operation: "create",
|
||||||
|
TreePath: "foo.txt",
|
||||||
|
ContentReader: strings.NewReader("foo"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Message: "add foo.txt",
|
||||||
|
OldBranch: "main",
|
||||||
|
NewBranch: "fork-branch-2",
|
||||||
|
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: "A mismatched path cannot trigger pull-request-target-event",
|
||||||
|
PosterID: user3.ID,
|
||||||
|
Poster: user3,
|
||||||
|
IsPull: true,
|
||||||
|
}
|
||||||
|
pullRequest = &issues_model.PullRequest{
|
||||||
|
HeadRepoID: forkedRepo.ID,
|
||||||
|
BaseRepoID: baseRepo.ID,
|
||||||
|
HeadBranch: "fork-branch-2",
|
||||||
|
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)
|
||||||
|
|
||||||
|
// the new pull request cannot trigger actions, so there is still only 1 record
|
||||||
|
assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue