From 17f9a8776ce32bcf913dff21de5d026edd43df89 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 15:25:35 +0100 Subject: [PATCH 01/17] started work on allowing pr approval/rejection... Untested though --- models/review.go | 29 ++++++++++++++++++++++++++ models/webhook.go | 20 ++++++++++-------- options/locale/locale_en-US.ini | 2 +- vendor/code.gitea.io/sdk/gitea/hook.go | 6 ++++++ 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/models/review.go b/models/review.go index 3326ea0549d2..e4f2eb901ffd 100644 --- a/models/review.go +++ b/models/review.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" + api "code.gitea.io/sdk/gitea" "github.com/go-xorm/xorm" "github.com/go-xorm/builder" @@ -216,6 +217,34 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { if _, err := e.Insert(review); err != nil { return nil, err } + + var reviewHookType HookEventType + var action api.HookIssueAction + + if opts.Type == ReviewTypeApprove { + reviewHookType = HookEventPullRequestApproved + action = api.HookPullRequestApproved + } else if opts.Type == ReviewTypeReject { + reviewHookType = HookEventPullRequestRejected + action = api.HookPullRequestRejected + } else { + // Webhook for a review comment does not exists + return review, nil + } + + mode, _ := AccessLevel(opts.Issue.Poster.ID, opts.Issue.Repo) + if err := PrepareWebhooks(opts.Issue.Repo, reviewHookType, &api.PullRequestPayload{ + Action: action, + Index: opts.Issue.Index, + PullRequest: opts.Issue.PullRequest.APIFormat(), + Repository: opts.Issue.Repo.APIFormat(mode), + Sender: opts.Reviewer.APIFormat(), + }); err != nil { + return nil, err + } else { + go HookQueue.Add(opts.Issue.Repo.RepoID) + } + return review, nil } diff --git a/models/webhook.go b/models/webhook.go index 77662f52757a..e20e8ce95dce 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -425,15 +425,17 @@ type HookEventType string // Types of hook events const ( - HookEventCreate HookEventType = "create" - HookEventDelete HookEventType = "delete" - HookEventFork HookEventType = "fork" - HookEventPush HookEventType = "push" - HookEventIssues HookEventType = "issues" - HookEventIssueComment HookEventType = "issue_comment" - HookEventPullRequest HookEventType = "pull_request" - HookEventRepository HookEventType = "repository" - HookEventRelease HookEventType = "release" + HookEventCreate HookEventType = "create" + HookEventDelete HookEventType = "delete" + HookEventFork HookEventType = "fork" + HookEventPush HookEventType = "push" + HookEventIssues HookEventType = "issues" + HookEventIssueComment HookEventType = "issue_comment" + HookEventPullRequest HookEventType = "pull_request" + HookEventRepository HookEventType = "repository" + HookEventRelease HookEventType = "release" + HookEventPullRequestApproved HookEventType = "pr_approved" + HookEventPullRequestRejected HookEventType = "pr_rejected" ) // HookRequest represents hook task request information. diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b7884b0199df..eb888a05ad8f 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1089,7 +1089,7 @@ settings.event_issue_comment_desc = Issue comment created, edited, or deleted. settings.event_release = Release settings.event_release_desc = Release published, updated or deleted in a repository. settings.event_pull_request = Pull Request -settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared or synchronized. +settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, approved, rejected, assigned, unassigned, label updated, label cleared or synchronized. settings.event_push = Push settings.event_push_desc = Git push to a repository. settings.event_repository = Repository diff --git a/vendor/code.gitea.io/sdk/gitea/hook.go b/vendor/code.gitea.io/sdk/gitea/hook.go index f34638167984..ad58d80ef427 100644 --- a/vendor/code.gitea.io/sdk/gitea/hook.go +++ b/vendor/code.gitea.io/sdk/gitea/hook.go @@ -432,6 +432,12 @@ const ( HookIssueMilestoned HookIssueAction = "milestoned" // HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue. HookIssueDemilestoned HookIssueAction = "demilestoned" + // HookPullRequestApproved is an issue action for when a pull request is + // approved + HookPullRequestApproved HookIssueAction = "pr_approved" + // HookPullRequestRejected is an issue action for when a pull request is + // rejected + HookPullRequestRejected HookIssueAction = "pr_rejected" ) // IssuePayload represents the payload information that is sent along with an issue event. From 1d478c933ce43b2ceef1be21e0b578b37a3a3b2b Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 15:59:44 +0100 Subject: [PATCH 02/17] whoops --- models/review.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/models/review.go b/models/review.go index e4f2eb901ffd..75a6e523a0de 100644 --- a/models/review.go +++ b/models/review.go @@ -234,15 +234,14 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { mode, _ := AccessLevel(opts.Issue.Poster.ID, opts.Issue.Repo) if err := PrepareWebhooks(opts.Issue.Repo, reviewHookType, &api.PullRequestPayload{ - Action: action, - Index: opts.Issue.Index, - PullRequest: opts.Issue.PullRequest.APIFormat(), - Repository: opts.Issue.Repo.APIFormat(mode), - Sender: opts.Reviewer.APIFormat(), + Action: action, + Index: opts.Issue.Index, + Repository: opts.Issue.Repo.APIFormat(mode), + Sender: opts.Reviewer.APIFormat(), }); err != nil { return nil, err } else { - go HookQueue.Add(opts.Issue.Repo.RepoID) + go HookQueue.Add(opts.Issue.Repo.ID) } return review, nil From b5564d62aa94cdd9099b32c55efb5f204183e5a4 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 16:08:44 +0100 Subject: [PATCH 03/17] fix pr#Issue being nil --- models/pull.go | 1 + models/review.go | 19 ++++++++++++------- vendor/code.gitea.io/sdk/gitea/hook.go | 6 ------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/models/pull.go b/models/pull.go index 79f6d7005d56..c74703e3fca2 100644 --- a/models/pull.go +++ b/models/pull.go @@ -148,6 +148,7 @@ func (pr *PullRequest) APIFormat() *api.PullRequest { headCommit *git.Commit err error ) + apiIssue := pr.Issue.APIFormat() if pr.BaseRepo == nil { pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID) diff --git a/models/review.go b/models/review.go index 75a6e523a0de..976496e398c5 100644 --- a/models/review.go +++ b/models/review.go @@ -219,25 +219,30 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { } var reviewHookType HookEventType - var action api.HookIssueAction if opts.Type == ReviewTypeApprove { reviewHookType = HookEventPullRequestApproved - action = api.HookPullRequestApproved } else if opts.Type == ReviewTypeReject { reviewHookType = HookEventPullRequestRejected - action = api.HookPullRequestRejected } else { // Webhook for a review comment does not exists return review, nil } + pr := opts.Issue.PullRequest + + // For some weird reason, pr#Issues is nil + if err := pr.LoadIssue(); err != nil { + return nil, err + } + mode, _ := AccessLevel(opts.Issue.Poster.ID, opts.Issue.Repo) if err := PrepareWebhooks(opts.Issue.Repo, reviewHookType, &api.PullRequestPayload{ - Action: action, - Index: opts.Issue.Index, - Repository: opts.Issue.Repo.APIFormat(mode), - Sender: opts.Reviewer.APIFormat(), + Action: api.HookIssueSynchronized, + Index: opts.Issue.Index, + PullRequest: pr.APIFormat(), + Repository: opts.Issue.Repo.APIFormat(mode), + Sender: opts.Reviewer.APIFormat(), }); err != nil { return nil, err } else { diff --git a/vendor/code.gitea.io/sdk/gitea/hook.go b/vendor/code.gitea.io/sdk/gitea/hook.go index ad58d80ef427..f34638167984 100644 --- a/vendor/code.gitea.io/sdk/gitea/hook.go +++ b/vendor/code.gitea.io/sdk/gitea/hook.go @@ -432,12 +432,6 @@ const ( HookIssueMilestoned HookIssueAction = "milestoned" // HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue. HookIssueDemilestoned HookIssueAction = "demilestoned" - // HookPullRequestApproved is an issue action for when a pull request is - // approved - HookPullRequestApproved HookIssueAction = "pr_approved" - // HookPullRequestRejected is an issue action for when a pull request is - // rejected - HookPullRequestRejected HookIssueAction = "pr_rejected" ) // IssuePayload represents the payload information that is sent along with an issue event. From e92bef5ae5ecdb2a2ae358537eda8fdbb7094887 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 16:09:32 +0100 Subject: [PATCH 04/17] updated hook name --- models/webhook.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/webhook.go b/models/webhook.go index e20e8ce95dce..2ea8bd20916d 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -434,8 +434,8 @@ const ( HookEventPullRequest HookEventType = "pull_request" HookEventRepository HookEventType = "repository" HookEventRelease HookEventType = "release" - HookEventPullRequestApproved HookEventType = "pr_approved" - HookEventPullRequestRejected HookEventType = "pr_rejected" + HookEventPullRequestApproved HookEventType = "pull_request_approved" + HookEventPullRequestRejected HookEventType = "pull_request_rejected" ) // HookRequest represents hook task request information. From b549837ec40aac424274b379d0c3e652a9068825 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 16:49:52 +0100 Subject: [PATCH 05/17] properly format webhook for slack --- models/webhook_slack.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/models/webhook_slack.go b/models/webhook_slack.go index 23df17bf2c72..0761745df8dc 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -328,6 +328,38 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S }, nil } +func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event HookEventType) (*SlackPayload, error) { + senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) + titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index), + fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)) + var text, title, attachmentText string + switch p.Action { + case api.HookIssueSynchronized: + var action string + if event == HookEventPullRequestRejected { + action = "rejected" + } else if event == HookEventPullRequestApproved { + action = "approved" + } else { + return nil, errors.New("unkown event type") + } + + text = fmt.Sprintf("[%s] Review on pull request %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink) + } + + return &SlackPayload{ + Channel: slack.Channel, + Text: text, + Username: slack.Username, + IconURL: slack.IconURL, + Attachments: []SlackAttachment{{ + Color: slack.Color, + Title: title, + Text: attachmentText, + }}, + }, nil +} + func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*SlackPayload, error) { senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) var text, title, attachmentText string @@ -376,6 +408,8 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP return getSlackPushPayload(p.(*api.PushPayload), slack) case HookEventPullRequest: return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack) + case HookEventPullRequestRejected, HookEventPullRequestApproved: + return getSlackPullRequestApprovalPayload(p.(*api.PullRequestPayload), slack, event) case HookEventRepository: return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack) case HookEventRelease: From d2cfc93b4f3d19aa960dd06c750a8f58b819167b Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 16:52:00 +0100 Subject: [PATCH 06/17] remove redundant newline --- models/pull.go | 1 - 1 file changed, 1 deletion(-) diff --git a/models/pull.go b/models/pull.go index c74703e3fca2..79f6d7005d56 100644 --- a/models/pull.go +++ b/models/pull.go @@ -148,7 +148,6 @@ func (pr *PullRequest) APIFormat() *api.PullRequest { headCommit *git.Commit err error ) - apiIssue := pr.Issue.APIFormat() if pr.BaseRepo == nil { pr.BaseRepo, err = GetRepositoryByID(pr.BaseRepoID) From 8969baf072efb2a5b4fae15a8db6d47cc5738fad Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 16:58:08 +0100 Subject: [PATCH 07/17] remove redundant comment --- models/review.go | 1 - 1 file changed, 1 deletion(-) diff --git a/models/review.go b/models/review.go index 976496e398c5..cd4138449872 100644 --- a/models/review.go +++ b/models/review.go @@ -231,7 +231,6 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { pr := opts.Issue.PullRequest - // For some weird reason, pr#Issues is nil if err := pr.LoadIssue(); err != nil { return nil, err } From 5ed0dbcc20d14b6fbba055e309ddd3ec8eab054d Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 17:00:41 +0100 Subject: [PATCH 08/17] fix make lint --- models/review.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/models/review.go b/models/review.go index cd4138449872..b9c97a65a679 100644 --- a/models/review.go +++ b/models/review.go @@ -244,9 +244,8 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { Sender: opts.Reviewer.APIFormat(), }); err != nil { return nil, err - } else { - go HookQueue.Add(opts.Issue.Repo.ID) } + go HookQueue.Add(opts.Issue.Repo.ID) return review, nil } From 59f4f5ace032191ba5b5a53d111051e735be4a2b Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 17:10:10 +0100 Subject: [PATCH 09/17] fix build --- models/webhook_slack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/webhook_slack.go b/models/webhook_slack.go index 0761745df8dc..cc575d49d8b9 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -341,7 +341,7 @@ func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackM } else if event == HookEventPullRequestApproved { action = "approved" } else { - return nil, errors.New("unkown event type") + return nil, errors.New("unknown event type") } text = fmt.Sprintf("[%s] Review on pull request %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink) From 1923bd9093ecdc498b99a8e1b0bee4e23900088f Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 22:13:34 +0100 Subject: [PATCH 10/17] add webhook formatting for discord --- models/webhook_discord.go | 46 +++++++++++++++++++++++++++++++++++++++ models/webhook_slack.go | 10 +++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/models/webhook_discord.go b/models/webhook_discord.go index 77634fbe9a8f..ccd4bc6cb65b 100644 --- a/models/webhook_discord.go +++ b/models/webhook_discord.go @@ -400,6 +400,40 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta) }, nil } +func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *DiscordMeta, event HookEventType) (*DiscordPayload, error) { + var text, title string + var color int + switch p.Action { + case api.HookIssueSynchronized: + action, err := parseActionText(event) + if err != nil { + return nil, err + } + + title = fmt.Sprintf("[%s] Review on pull request %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + color = warnColor + } + + return &DiscordPayload{ + Username: meta.Username, + AvatarURL: meta.IconURL, + Embeds: []DiscordEmbed{ + { + Title: title, + Description: text, + URL: p.PullRequest.HTMLURL, + Color: color, + Author: DiscordEmbedAuthor{ + Name: p.Sender.UserName, + URL: setting.AppURL + p.Sender.UserName, + IconURL: p.Sender.AvatarURL, + }, + }, + }, + }, nil +} + func getDiscordRepositoryPayload(p *api.RepositoryPayload, meta *DiscordMeta) (*DiscordPayload, error) { var title, url string var color int @@ -492,6 +526,8 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc return getDiscordPushPayload(p.(*api.PushPayload), discord) case HookEventPullRequest: return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord) + case HookEventPullRequestRejected, HookEventPullRequestApproved: + return getDiscordPullRequestApprovalPayload(p.(*api.PullRequestPayload), discord, event) case HookEventRepository: return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord) case HookEventRelease: @@ -500,3 +536,13 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc return s, nil } + +func parseActionText(event HookEventType) (string, error) { + if event == HookEventPullRequestApproved { + return "approved", nil + } else if event == HookEventPullRequestRejected { + return "rejected", nil + } + + return "", errors.New("unknown event type") +} diff --git a/models/webhook_slack.go b/models/webhook_slack.go index cc575d49d8b9..78a02e7def5c 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -335,13 +335,9 @@ func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackM var text, title, attachmentText string switch p.Action { case api.HookIssueSynchronized: - var action string - if event == HookEventPullRequestRejected { - action = "rejected" - } else if event == HookEventPullRequestApproved { - action = "approved" - } else { - return nil, errors.New("unknown event type") + action, err := parseActionText(event) + if err != nil { + return nil, err } text = fmt.Sprintf("[%s] Review on pull request %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink) From 50f4846aba6005d94d59f5a9172774ecd564bd57 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 22:25:13 +0100 Subject: [PATCH 11/17] add webhook formatting for dingtalk --- models/webhook_dingtalk.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/models/webhook_dingtalk.go b/models/webhook_dingtalk.go index 06388a6ba22b..4f5e69933c93 100644 --- a/models/webhook_dingtalk.go +++ b/models/webhook_dingtalk.go @@ -271,6 +271,33 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) (*DingtalkPayload, }, nil } +func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event HookEventType) (*DingtalkPayload, error) { + var text, title string + switch p.Action { + case api.HookIssueSynchronized: + action, err := parseActionText(event) + if err != nil { + return nil, err + } + + title = fmt.Sprintf("[%s] Review on pull request %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) + text = p.PullRequest.Body + + } + + return &DingtalkPayload{ + MsgType: "actionCard", + ActionCard: dingtalk.ActionCard{ + Text: title + "\r\n\r\n" + text, + //Markdown: "# " + title + "\n" + text, + Title: title, + HideAvatar: "0", + SingleTitle: "view pull request", + SingleURL: p.PullRequest.HTMLURL, + }, + }, nil +} + func getDingtalkRepositoryPayload(p *api.RepositoryPayload) (*DingtalkPayload, error) { var title, url string switch p.Action { @@ -369,6 +396,8 @@ func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*Din return getDingtalkPushPayload(p.(*api.PushPayload)) case HookEventPullRequest: return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload)) + case HookEventPullRequestApproved, HookEventPullRequestRejected: + return getDingtalkPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) case HookEventRepository: return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload)) case HookEventRelease: From ce776464f0495e26b9cc654b5344f3359f6ac38d Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Sat, 6 Oct 2018 22:27:12 +0100 Subject: [PATCH 12/17] try to fix naming --- models/webhook_dingtalk.go | 2 +- models/webhook_discord.go | 4 ++-- models/webhook_slack.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/models/webhook_dingtalk.go b/models/webhook_dingtalk.go index 4f5e69933c93..719a376bcc34 100644 --- a/models/webhook_dingtalk.go +++ b/models/webhook_dingtalk.go @@ -275,7 +275,7 @@ func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event Hook var text, title string switch p.Action { case api.HookIssueSynchronized: - action, err := parseActionText(event) + action, err := parseHookPullRequestEventType(event) if err != nil { return nil, err } diff --git a/models/webhook_discord.go b/models/webhook_discord.go index ccd4bc6cb65b..8a6a9d1fcec8 100644 --- a/models/webhook_discord.go +++ b/models/webhook_discord.go @@ -405,7 +405,7 @@ func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *Disco var color int switch p.Action { case api.HookIssueSynchronized: - action, err := parseActionText(event) + action, err := parseHookPullRequestEventType(event) if err != nil { return nil, err } @@ -537,7 +537,7 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc return s, nil } -func parseActionText(event HookEventType) (string, error) { +func parseHookPullRequestEventType(event HookEventType) (string, error) { if event == HookEventPullRequestApproved { return "approved", nil } else if event == HookEventPullRequestRejected { diff --git a/models/webhook_slack.go b/models/webhook_slack.go index 78a02e7def5c..f7fe8cceeaf9 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -335,7 +335,7 @@ func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackM var text, title, attachmentText string switch p.Action { case api.HookIssueSynchronized: - action, err := parseActionText(event) + action, err := parseHookPullRequestEventType(event) if err != nil { return nil, err } From d1c234c24ab2b7f700a744292d237d8de9aa43fc Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Tue, 9 Oct 2018 15:32:42 +0100 Subject: [PATCH 13/17] add error handling --- models/review.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/models/review.go b/models/review.go index b9c97a65a679..992492935040 100644 --- a/models/review.go +++ b/models/review.go @@ -235,7 +235,11 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { return nil, err } - mode, _ := AccessLevel(opts.Issue.Poster.ID, opts.Issue.Repo) + mode, err := AccessLevel(opts.Issue.Poster.ID, opts.Issue.Repo) + if err != nil { + return nil, err + } + if err := PrepareWebhooks(opts.Issue.Repo, reviewHookType, &api.PullRequestPayload{ Action: api.HookIssueSynchronized, Index: opts.Issue.Index, From 67259f0db271d5a640d84a920023055a8fe356e7 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Tue, 9 Oct 2018 15:33:26 +0100 Subject: [PATCH 14/17] fix style guide --- models/review.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/review.go b/models/review.go index 992492935040..3798c974153b 100644 --- a/models/review.go +++ b/models/review.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" api "code.gitea.io/sdk/gitea" - "github.com/go-xorm/xorm" "github.com/go-xorm/builder" + "github.com/go-xorm/xorm" ) // ReviewType defines the sort of feedback a review gives From 0770f7714c5e21245b7d1cf2463884cac0554136 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Tue, 23 Oct 2018 22:49:49 +0100 Subject: [PATCH 15/17] add support for pull request comment webhooks --- models/review.go | 12 +++++++----- models/webhook.go | 2 +- models/webhook_dingtalk.go | 5 ++--- models/webhook_discord.go | 18 ++++++++++++------ models/webhook_slack.go | 7 +++---- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/models/review.go b/models/review.go index 3798c974153b..3421a11578d8 100644 --- a/models/review.go +++ b/models/review.go @@ -10,7 +10,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" api "code.gitea.io/sdk/gitea" - "github.com/go-xorm/builder" "github.com/go-xorm/xorm" ) @@ -220,12 +219,15 @@ func createReview(e Engine, opts CreateReviewOptions) (*Review, error) { var reviewHookType HookEventType - if opts.Type == ReviewTypeApprove { + switch opts.Type { + case ReviewTypeApprove: reviewHookType = HookEventPullRequestApproved - } else if opts.Type == ReviewTypeReject { + case ReviewTypeComment: + reviewHookType = HookEventPullRequestComment + case ReviewTypeReject: reviewHookType = HookEventPullRequestRejected - } else { - // Webhook for a review comment does not exists + default: + // unsupported review webhook type here return review, nil } diff --git a/models/webhook.go b/models/webhook.go index 2ea8bd20916d..4c0ed2747ea3 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -19,7 +19,6 @@ import ( "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" api "code.gitea.io/sdk/gitea" - "github.com/Unknwon/com" gouuid "github.com/satori/go.uuid" ) @@ -436,6 +435,7 @@ const ( HookEventRelease HookEventType = "release" HookEventPullRequestApproved HookEventType = "pull_request_approved" HookEventPullRequestRejected HookEventType = "pull_request_rejected" + HookEventPullRequestComment HookEventType = "pull_request_commented" ) // HookRequest represents hook task request information. diff --git a/models/webhook_dingtalk.go b/models/webhook_dingtalk.go index 719a376bcc34..98fe77f6aa62 100644 --- a/models/webhook_dingtalk.go +++ b/models/webhook_dingtalk.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/git" api "code.gitea.io/sdk/gitea" - dingtalk "github.com/lunny/dingtalk_webhook" ) @@ -280,7 +279,7 @@ func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event Hook return nil, err } - title = fmt.Sprintf("[%s] Review on pull request %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) + title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) text = p.PullRequest.Body } @@ -396,7 +395,7 @@ func GetDingtalkPayload(p api.Payloader, event HookEventType, meta string) (*Din return getDingtalkPushPayload(p.(*api.PushPayload)) case HookEventPullRequest: return getDingtalkPullRequestPayload(p.(*api.PullRequestPayload)) - case HookEventPullRequestApproved, HookEventPullRequestRejected: + case HookEventPullRequestApproved, HookEventPullRequestRejected, HookEventPullRequestComment: return getDingtalkPullRequestApprovalPayload(p.(*api.PullRequestPayload), event) case HookEventRepository: return getDingtalkRepositoryPayload(p.(*api.RepositoryPayload)) diff --git a/models/webhook_discord.go b/models/webhook_discord.go index 8a6a9d1fcec8..4011880ea903 100644 --- a/models/webhook_discord.go +++ b/models/webhook_discord.go @@ -410,7 +410,7 @@ func getDiscordPullRequestApprovalPayload(p *api.PullRequestPayload, meta *Disco return nil, err } - title = fmt.Sprintf("[%s] Review on pull request %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) + title = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title) text = p.PullRequest.Body color = warnColor } @@ -526,7 +526,7 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc return getDiscordPushPayload(p.(*api.PushPayload), discord) case HookEventPullRequest: return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord) - case HookEventPullRequestRejected, HookEventPullRequestApproved: + case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: return getDiscordPullRequestApprovalPayload(p.(*api.PullRequestPayload), discord, event) case HookEventRepository: return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord) @@ -538,11 +538,17 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc } func parseHookPullRequestEventType(event HookEventType) (string, error) { - if event == HookEventPullRequestApproved { + + switch event { + + case HookEventPullRequestApproved: return "approved", nil - } else if event == HookEventPullRequestRejected { + case HookEventPullRequestRejected: return "rejected", nil - } + case HookEventPullRequestComment: + return "comment", nil - return "", errors.New("unknown event type") + default: + return "", errors.New("unknown event type") + } } diff --git a/models/webhook_slack.go b/models/webhook_slack.go index f7fe8cceeaf9..3a21f9860111 100644 --- a/models/webhook_slack.go +++ b/models/webhook_slack.go @@ -11,9 +11,8 @@ import ( "strings" "code.gitea.io/git" - api "code.gitea.io/sdk/gitea" - "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/sdk/gitea" ) // SlackMeta contains the slack metadata @@ -340,7 +339,7 @@ func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackM return nil, err } - text = fmt.Sprintf("[%s] Review on pull request %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink) + text = fmt.Sprintf("[%s] Pull request review %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink) } return &SlackPayload{ @@ -404,7 +403,7 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP return getSlackPushPayload(p.(*api.PushPayload), slack) case HookEventPullRequest: return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack) - case HookEventPullRequestRejected, HookEventPullRequestApproved: + case HookEventPullRequestRejected, HookEventPullRequestApproved, HookEventPullRequestComment: return getSlackPullRequestApprovalPayload(p.(*api.PullRequestPayload), slack, event) case HookEventRepository: return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack) From 0f698bb5bf32e8e4e48bcc61f09592f2e9e48e83 Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Tue, 23 Oct 2018 22:53:08 +0100 Subject: [PATCH 16/17] fix naming --- models/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/webhook.go b/models/webhook.go index 4c0ed2747ea3..a764455f5f39 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -435,7 +435,7 @@ const ( HookEventRelease HookEventType = "release" HookEventPullRequestApproved HookEventType = "pull_request_approved" HookEventPullRequestRejected HookEventType = "pull_request_rejected" - HookEventPullRequestComment HookEventType = "pull_request_commented" + HookEventPullRequestComment HookEventType = "pull_request_comment" ) // HookRequest represents hook task request information. From d2577fc3c807a13171dc35687d63faffbb8ddcdc Mon Sep 17 00:00:00 2001 From: Lanre Adelowo Date: Wed, 24 Oct 2018 21:30:01 +0100 Subject: [PATCH 17/17] remove redundant comment and update translations --- models/webhook_dingtalk.go | 3 +-- options/locale/locale_en-US.ini | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/models/webhook_dingtalk.go b/models/webhook_dingtalk.go index 98fe77f6aa62..dbbbebcd9a05 100644 --- a/models/webhook_dingtalk.go +++ b/models/webhook_dingtalk.go @@ -287,8 +287,7 @@ func getDingtalkPullRequestApprovalPayload(p *api.PullRequestPayload, event Hook return &DingtalkPayload{ MsgType: "actionCard", ActionCard: dingtalk.ActionCard{ - Text: title + "\r\n\r\n" + text, - //Markdown: "# " + title + "\n" + text, + Text: title + "\r\n\r\n" + text, Title: title, HideAvatar: "0", SingleTitle: "view pull request", diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index d44f787a275e..b2c8ea164b24 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1090,7 +1090,7 @@ settings.event_issue_comment_desc = Issue comment created, edited, or deleted. settings.event_release = Release settings.event_release_desc = Release published, updated or deleted in a repository. settings.event_pull_request = Pull Request -settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, approved, rejected, assigned, unassigned, label updated, label cleared or synchronized. +settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, approved, rejected, review comment, assigned, unassigned, label updated, label cleared or synchronized. settings.event_push = Push settings.event_push_desc = Git push to a repository. settings.event_repository = Repository