From a0b30ad6d399dd733eee9e316d6864ed08cfdbe2 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 20 Feb 2024 13:36:31 +0800 Subject: [PATCH 1/4] support issue_comment --- modules/actions/github.go | 44 ++++++++++++++ modules/actions/github_test.go | 6 ++ services/actions/notifier.go | 89 +++++++++++++++++++++++++++++ services/actions/notifier_helper.go | 11 ++-- 4 files changed, 146 insertions(+), 4 deletions(-) diff --git a/modules/actions/github.go b/modules/actions/github.go index 18917c5118d66..68116ec83a539 100644 --- a/modules/actions/github.go +++ b/modules/actions/github.go @@ -25,6 +25,45 @@ const ( GithubEventSchedule = "schedule" ) +// IsDefaultBranchWorkflow returns true if the event only triggers workflows on the default branch +func IsDefaultBranchWorkflow(triggedEvent webhook_module.HookEventType) bool { + switch triggedEvent { + case webhook_module.HookEventDelete: + // GitHub "delete" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#delete + return true + case webhook_module.HookEventFork: + // GitHub "fork" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#fork + return true + case webhook_module.HookEventIssueComment: + // GitHub "issue_comment" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment + return true + case webhook_module.HookEventPullRequestComment: + // GitHub "pull_request_comment" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment + return true + case webhook_module.HookEventWiki: + // GitHub "gollum" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#gollum + return true + case webhook_module.HookEventSchedule: + // GitHub "schedule" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule + return true + case webhook_module.HookEventIssues, + webhook_module.HookEventIssueAssign, + webhook_module.HookEventIssueLabel, + webhook_module.HookEventIssueMilestone: + // Github "issues" event + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues + return true + } + + return false +} + // canGithubEventMatch check if the input Github event can match any Gitea event. func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEventType) bool { switch eventName { @@ -75,6 +114,11 @@ func canGithubEventMatch(eventName string, triggedEvent webhook_module.HookEvent case GithubEventSchedule: return triggedEvent == webhook_module.HookEventSchedule + case GithubEventIssueComment: + // https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment + return triggedEvent == webhook_module.HookEventIssueComment || + triggedEvent == webhook_module.HookEventPullRequestComment + default: return eventName == string(triggedEvent) } diff --git a/modules/actions/github_test.go b/modules/actions/github_test.go index 4bf55ae03fccd..6652ff6eac22e 100644 --- a/modules/actions/github_test.go +++ b/modules/actions/github_test.go @@ -103,6 +103,12 @@ func TestCanGithubEventMatch(t *testing.T) { webhook_module.HookEventCreate, true, }, + { + "create pull request comment", + GithubEventIssueComment, + webhook_module.HookEventPullRequestComment, + true, + }, } for _, tc := range testCases { diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 77848a3f58978..0b104a24ce4ee 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -258,6 +258,95 @@ func (n *actionsNotifier) CreateIssueComment(ctx context.Context, doer *user_mod Notify(ctx) } +func (m *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { + ctx = withMethod(ctx, "UpdateComment") + + if err := c.LoadIssue(ctx); err != nil { + log.Error("LoadIssue: %v", err) + return + } + if err := c.Issue.LoadAttributes(ctx); err != nil { + log.Error("LoadAttributes: %v", err) + return + } + + permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer) + + payload := &api.IssueCommentPayload{ + Action: api.HookIssueCommentEdited, + Issue: convert.ToAPIIssue(ctx, c.Issue), + Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c), + Repository: convert.ToRepo(ctx, c.Issue.Repo, permission), + Changes: &api.ChangesPayload{ + Body: &api.ChangesFromPayload{ + From: oldContent, + }, + }, + Sender: convert.ToUser(ctx, doer, nil), + IsPull: c.Issue.IsPull, + } + + if c.Issue.IsPull { + if err := c.Issue.LoadPullRequest(ctx); err != nil { + log.Error("LoadPullRequest: %v", err) + return + } + newNotifyInputFromIssue(c.Issue, webhook_module.HookEventPullRequestComment). + WithDoer(doer). + WithPayload(payload). + WithPullRequest(c.Issue.PullRequest). + Notify(ctx) + return + } + + newNotifyInputFromIssue(c.Issue, webhook_module.HookEventIssueComment). + WithDoer(doer). + WithPayload(payload). + Notify(ctx) +} + +func (m *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { + ctx = withMethod(ctx, "DeleteComment") + + if err := comment.LoadIssue(ctx); err != nil { + log.Error("LoadIssue: %v", err) + return + } + if err := comment.Issue.LoadAttributes(ctx); err != nil { + log.Error("LoadAttributes: %v", err) + return + } + + permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) + + payload := &api.IssueCommentPayload{ + Action: api.HookIssueCommentDeleted, + Issue: convert.ToAPIIssue(ctx, comment.Issue), + Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment), + Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission), + Sender: convert.ToUser(ctx, doer, nil), + IsPull: comment.Issue.IsPull, + } + + if comment.Issue.IsPull { + if err := comment.Issue.LoadPullRequest(ctx); err != nil { + log.Error("LoadPullRequest: %v", err) + return + } + newNotifyInputFromIssue(comment.Issue, webhook_module.HookEventPullRequestComment). + WithDoer(doer). + WithPayload(payload). + WithPullRequest(comment.Issue.PullRequest). + Notify(ctx) + return + } + + newNotifyInputFromIssue(comment.Issue, webhook_module.HookEventIssueComment). + WithDoer(doer). + WithPayload(payload). + Notify(ctx) +} + func (n *actionsNotifier) NewPullRequest(ctx context.Context, pull *issues_model.PullRequest, _ []*user_model.User) { ctx = withMethod(ctx, "NewPullRequest") diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 8852f23c5f713..c20335af6f30d 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -136,12 +136,15 @@ func notify(ctx context.Context, input *notifyInput) error { defer gitRepo.Close() ref := input.Ref - if input.Event == webhook_module.HookEventDelete { - // The event is deleting a reference, so it will fail to get the commit for a deleted reference. - // Set ref to empty string to fall back to the default branch. - ref = "" + if ref != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) { + if ref != "" { + log.Warn("Event %q should only trigger workflows on the default branch, but its ref is %q. Will fall back to the default branch", + input.Event, ref) + } + ref = input.Repo.DefaultBranch } if ref == "" { + log.Warn("Ref of event %q is empty, will fall back to the default branch", input.Event) ref = input.Repo.DefaultBranch } From 17222428126c41cd97ce181c62c86db6f7ec3d4c Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 20 Feb 2024 14:04:52 +0800 Subject: [PATCH 2/4] lint --- services/actions/notifier.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 0b104a24ce4ee..2ac4254a85667 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -258,7 +258,7 @@ func (n *actionsNotifier) CreateIssueComment(ctx context.Context, doer *user_mod Notify(ctx) } -func (m *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { +func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { ctx = withMethod(ctx, "UpdateComment") if err := c.LoadIssue(ctx); err != nil { @@ -305,7 +305,7 @@ func (m *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.Us Notify(ctx) } -func (m *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { +func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { ctx = withMethod(ctx, "DeleteComment") if err := comment.LoadIssue(ctx); err != nil { From 6e33761437fd2e2483953b464c317be56ce00219 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 21 Feb 2024 15:39:51 +0800 Subject: [PATCH 3/4] remove the ref for delete event --- services/actions/notifier.go | 1 - 1 file changed, 1 deletion(-) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 2ac4254a85667..a2b4c7af64c5a 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -585,7 +585,6 @@ func (n *actionsNotifier) DeleteRef(ctx context.Context, pusher *user_model.User apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}) newNotifyInput(repo, pusher, webhook_module.HookEventDelete). - WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name WithPayload(&api.DeletePayload{ Ref: refFullName.ShortName(), RefType: refFullName.RefType(), From 9bc944c311e45d0ee70470cb181e5fd61a70bc6b Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Thu, 22 Feb 2024 16:02:17 +0800 Subject: [PATCH 4/4] introduce notifyIssueCommentChange --- services/actions/notifier.go | 92 +++++++++++------------------------- 1 file changed, 27 insertions(+), 65 deletions(-) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index a2b4c7af64c5a..e144484dabda2 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -224,38 +224,11 @@ func (n *actionsNotifier) CreateIssueComment(ctx context.Context, doer *user_mod ) { ctx = withMethod(ctx, "CreateIssueComment") - permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) - if issue.IsPull { - if err := issue.LoadPullRequest(ctx); err != nil { - log.Error("LoadPullRequest: %v", err) - return - } - newNotifyInputFromIssue(issue, webhook_module.HookEventPullRequestComment). - WithDoer(doer). - WithPayload(&api.IssueCommentPayload{ - Action: api.HookIssueCommentCreated, - Issue: convert.ToAPIIssue(ctx, issue), - Comment: convert.ToAPIComment(ctx, repo, comment), - Repository: convert.ToRepo(ctx, repo, permission), - Sender: convert.ToUser(ctx, doer, nil), - IsPull: true, - }). - WithPullRequest(issue.PullRequest). - Notify(ctx) + notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventPullRequestComment, api.HookIssueCommentCreated) return } - newNotifyInputFromIssue(issue, webhook_module.HookEventIssueComment). - WithDoer(doer). - WithPayload(&api.IssueCommentPayload{ - Action: api.HookIssueCommentCreated, - Issue: convert.ToAPIIssue(ctx, issue), - Comment: convert.ToAPIComment(ctx, repo, comment), - Repository: convert.ToRepo(ctx, repo, permission), - Sender: convert.ToUser(ctx, doer, nil), - IsPull: false, - }). - Notify(ctx) + notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventIssueComment, api.HookIssueCommentCreated) } func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { @@ -265,49 +238,30 @@ func (n *actionsNotifier) UpdateComment(ctx context.Context, doer *user_model.Us log.Error("LoadIssue: %v", err) return } - if err := c.Issue.LoadAttributes(ctx); err != nil { - log.Error("LoadAttributes: %v", err) + + if c.Issue.IsPull { + notifyIssueCommentChange(ctx, doer, c, oldContent, webhook_module.HookEventPullRequestComment, api.HookIssueCommentEdited) return } + notifyIssueCommentChange(ctx, doer, c, oldContent, webhook_module.HookEventIssueComment, api.HookIssueCommentEdited) +} - permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer) +func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { + ctx = withMethod(ctx, "DeleteComment") - payload := &api.IssueCommentPayload{ - Action: api.HookIssueCommentEdited, - Issue: convert.ToAPIIssue(ctx, c.Issue), - Comment: convert.ToAPIComment(ctx, c.Issue.Repo, c), - Repository: convert.ToRepo(ctx, c.Issue.Repo, permission), - Changes: &api.ChangesPayload{ - Body: &api.ChangesFromPayload{ - From: oldContent, - }, - }, - Sender: convert.ToUser(ctx, doer, nil), - IsPull: c.Issue.IsPull, + if err := comment.LoadIssue(ctx); err != nil { + log.Error("LoadIssue: %v", err) + return } - if c.Issue.IsPull { - if err := c.Issue.LoadPullRequest(ctx); err != nil { - log.Error("LoadPullRequest: %v", err) - return - } - newNotifyInputFromIssue(c.Issue, webhook_module.HookEventPullRequestComment). - WithDoer(doer). - WithPayload(payload). - WithPullRequest(c.Issue.PullRequest). - Notify(ctx) + if comment.Issue.IsPull { + notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventPullRequestComment, api.HookIssueCommentDeleted) return } - - newNotifyInputFromIssue(c.Issue, webhook_module.HookEventIssueComment). - WithDoer(doer). - WithPayload(payload). - Notify(ctx) + notifyIssueCommentChange(ctx, doer, comment, "", webhook_module.HookEventIssueComment, api.HookIssueCommentDeleted) } -func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) { - ctx = withMethod(ctx, "DeleteComment") - +func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, comment *issues_model.Comment, oldContent string, event webhook_module.HookEventType, action api.HookIssueCommentAction) { if err := comment.LoadIssue(ctx); err != nil { log.Error("LoadIssue: %v", err) return @@ -320,7 +274,7 @@ func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.Us permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) payload := &api.IssueCommentPayload{ - Action: api.HookIssueCommentDeleted, + Action: action, Issue: convert.ToAPIIssue(ctx, comment.Issue), Comment: convert.ToAPIComment(ctx, comment.Issue.Repo, comment), Repository: convert.ToRepo(ctx, comment.Issue.Repo, permission), @@ -328,12 +282,20 @@ func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.Us IsPull: comment.Issue.IsPull, } + if action == api.HookIssueCommentEdited { + payload.Changes = &api.ChangesPayload{ + Body: &api.ChangesFromPayload{ + From: oldContent, + }, + } + } + if comment.Issue.IsPull { if err := comment.Issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest: %v", err) return } - newNotifyInputFromIssue(comment.Issue, webhook_module.HookEventPullRequestComment). + newNotifyInputFromIssue(comment.Issue, event). WithDoer(doer). WithPayload(payload). WithPullRequest(comment.Issue.PullRequest). @@ -341,7 +303,7 @@ func (n *actionsNotifier) DeleteComment(ctx context.Context, doer *user_model.Us return } - newNotifyInputFromIssue(comment.Issue, webhook_module.HookEventIssueComment). + newNotifyInputFromIssue(comment.Issue, event). WithDoer(doer). WithPayload(payload). Notify(ctx)