diff --git a/services/actions/notifier.go b/services/actions/notifier.go index a5bac730be..33ac675fcc 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -343,7 +343,7 @@ func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, commen newNotifyInputFromIssue(comment.Issue, event). WithDoer(doer). WithPayload(payload). - WithPullRequest(comment.Issue.PullRequest). + WithPullRequestData(comment.Issue.PullRequest). Notify(ctx) return } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index c94223bc3b..7dd449eda5 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -102,6 +102,12 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput { return input } +// for cases like issue comments on PRs, which have the PR data, but don't run on its ref +func (input *notifyInput) WithPullRequestData(pr *issues_model.PullRequest) *notifyInput { + input.PullRequest = pr + return input +} + func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput { input.PullRequest = pr if input.Ref == "" { @@ -219,7 +225,7 @@ func notify(ctx context.Context, input *notifyInput) error { } } - if input.PullRequest != nil { + if input.PullRequest != nil && !actions_module.IsDefaultBranchWorkflow(input.Event) { // detect pull_request_target workflows baseRef := git.BranchPrefix + input.PullRequest.BaseBranch baseCommit, err := gitRepo.GetCommit(baseRef) @@ -315,7 +321,7 @@ func handleWorkflows( } isForkPullRequest := false - if pr := input.PullRequest; pr != nil { + if pr := input.PullRequest; pr != nil && !actions_module.IsDefaultBranchWorkflow(input.Event) { switch pr.Flow { case issues_model.PullRequestFlowGithub: isForkPullRequest = pr.IsFromFork() diff --git a/services/actions/notifier_helper_test.go b/services/actions/notifier_helper_test.go index 9166dc3b95..fabc783bd0 100644 --- a/services/actions/notifier_helper_test.go +++ b/services/actions/notifier_helper_test.go @@ -8,9 +8,16 @@ import ( actions_model "forgejo.org/models/actions" "forgejo.org/models/db" + issues_model "forgejo.org/models/issues" + repo_model "forgejo.org/models/repo" "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" + actions_module "forgejo.org/modules/actions" + "forgejo.org/modules/git" + api "forgejo.org/modules/structs" webhook_module "forgejo.org/modules/webhook" + "github.com/nektos/act/pkg/jobparser" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -49,3 +56,91 @@ func Test_SkipPullRequestEvent(t *testing.T) { unittest.AssertSuccessfulInsert(t, run) assert.True(t, SkipPullRequestEvent(db.DefaultContext, webhook_module.HookEventPullRequestSync, repoID, commitSHA)) } + +func Test_IssueCommentOnForkPullRequestEvent(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3}) + require.NoError(t, pr.LoadIssue(db.DefaultContext)) + + require.True(t, pr.IsFromFork()) + + commit := &git.Commit{ + ID: git.MustIDFromString("0000000000000000000000000000000000000000"), + CommitMessage: "test", + } + detectedWorkflows := []*actions_module.DetectedWorkflow{ + { + TriggerEvent: &jobparser.Event{ + Name: "issue_comment", + }, + }, + } + input := ¬ifyInput{ + Repo: repo, + Doer: doer, + Event: webhook_module.HookEventIssueComment, + PullRequest: pr, + Payload: &api.IssueCommentPayload{}, + } + + unittest.AssertSuccessfulDelete(t, &actions_model.ActionRun{RepoID: repo.ID}) + + err := handleWorkflows(db.DefaultContext, detectedWorkflows, commit, input, "") + require.NoError(t, err) + + runs, err := db.Find[actions_model.ActionRun](db.DefaultContext, actions_model.FindRunOptions{ + RepoID: repo.ID, + }) + require.NoError(t, err) + require.Len(t, runs, 1) + + assert.Equal(t, webhook_module.HookEventIssueComment, runs[0].Event) + assert.False(t, runs[0].IsForkPullRequest) +} + +func Test_OpenForkPullRequestEvent(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 3}) + require.NoError(t, pr.LoadIssue(db.DefaultContext)) + + require.True(t, pr.IsFromFork()) + + commit := &git.Commit{ + ID: git.MustIDFromString("0000000000000000000000000000000000000000"), + CommitMessage: "test", + } + detectedWorkflows := []*actions_module.DetectedWorkflow{ + { + TriggerEvent: &jobparser.Event{ + Name: "pull_request", + }, + }, + } + input := ¬ifyInput{ + Repo: repo, + Doer: doer, + Event: webhook_module.HookEventPullRequest, + PullRequest: pr, + Payload: &api.PullRequestPayload{}, + } + + unittest.AssertSuccessfulDelete(t, &actions_model.ActionRun{RepoID: repo.ID}) + + err := handleWorkflows(db.DefaultContext, detectedWorkflows, commit, input, "") + require.NoError(t, err) + + runs, err := db.Find[actions_model.ActionRun](db.DefaultContext, actions_model.FindRunOptions{ + RepoID: repo.ID, + }) + require.NoError(t, err) + require.Len(t, runs, 1) + + assert.Equal(t, webhook_module.HookEventPullRequest, runs[0].Event) + assert.True(t, runs[0].IsForkPullRequest) +}