Granular webhook events (#9626)
* Initial work Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add PR reviews and API coverage Signed-off-by: jolheiser <john.olheiser@gmail.com> * Split up events Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add migration and locale Signed-off-by: jolheiser <john.olheiser@gmail.com> * Format Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert IsPull Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix comments Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix PR reviews Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix issue_comment Signed-off-by: jolheiser <john.olheiser@gmail.com> * Make fmt Signed-off-by: jolheiser <john.olheiser@gmail.com> * Migrations Signed-off-by: jolheiser <john.olheiser@gmail.com> * Backwards compatible API Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix feishu Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move session commit Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
parent
80db44267c
commit
3f1c0841cb
18 changed files with 624 additions and 173 deletions
|
@ -192,6 +192,8 @@ var migrations = []Migration{
|
|||
NewMigration("fix merge base for pull requests", fixMergeBase),
|
||||
// v129 -> v130
|
||||
NewMigration("remove dependencies from deleted repositories", purgeUnusedDependencies),
|
||||
// v130 -> v131
|
||||
NewMigration("Expand webhooks for more granularity", expandWebhooks),
|
||||
}
|
||||
|
||||
// Migrate database to current version
|
||||
|
|
101
models/migrations/v130.go
Normal file
101
models/migrations/v130.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func expandWebhooks(x *xorm.Engine) error {
|
||||
|
||||
type ChooseEvents struct {
|
||||
Issues bool `json:"issues"`
|
||||
IssueAssign bool `json:"issue_assign"`
|
||||
IssueLabel bool `json:"issue_label"`
|
||||
IssueMilestone bool `json:"issue_milestone"`
|
||||
IssueComment bool `json:"issue_comment"`
|
||||
PullRequest bool `json:"pull_request"`
|
||||
PullRequestAssign bool `json:"pull_request_assign"`
|
||||
PullRequestLabel bool `json:"pull_request_label"`
|
||||
PullRequestMilestone bool `json:"pull_request_milestone"`
|
||||
PullRequestComment bool `json:"pull_request_comment"`
|
||||
PullRequestReview bool `json:"pull_request_review"`
|
||||
PullRequestSync bool `json:"pull_request_sync"`
|
||||
}
|
||||
|
||||
type Events struct {
|
||||
PushOnly bool `json:"push_only"`
|
||||
SendEverything bool `json:"send_everything"`
|
||||
ChooseEvents bool `json:"choose_events"`
|
||||
BranchFilter string `json:"branch_filter"`
|
||||
Events ChooseEvents `json:"events"`
|
||||
}
|
||||
|
||||
type Webhook struct {
|
||||
ID int64
|
||||
Events string
|
||||
}
|
||||
|
||||
var events Events
|
||||
var bytes []byte
|
||||
var last int
|
||||
const batchSize = 50
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
for {
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
var results = make([]Webhook, 0, batchSize)
|
||||
err := x.OrderBy("id").
|
||||
Limit(batchSize, last).
|
||||
Find(&results)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(results) == 0 {
|
||||
break
|
||||
}
|
||||
last += len(results)
|
||||
|
||||
for _, res := range results {
|
||||
if err = json.Unmarshal([]byte(res.Events), &events); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if events.Events.Issues {
|
||||
events.Events.IssueAssign = true
|
||||
events.Events.IssueLabel = true
|
||||
events.Events.IssueMilestone = true
|
||||
events.Events.IssueComment = true
|
||||
}
|
||||
|
||||
if events.Events.PullRequest {
|
||||
events.Events.PullRequestAssign = true
|
||||
events.Events.PullRequestLabel = true
|
||||
events.Events.PullRequestMilestone = true
|
||||
events.Events.PullRequestComment = true
|
||||
events.Events.PullRequestReview = true
|
||||
events.Events.PullRequestSync = true
|
||||
}
|
||||
|
||||
if bytes, err = json.Marshal(&events); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sess.Exec("UPDATE webhook SET events = ? WHERE id = ?", string(bytes), res.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -57,15 +57,24 @@ func IsValidHookContentType(name string) bool {
|
|||
|
||||
// HookEvents is a set of web hook events
|
||||
type HookEvents struct {
|
||||
Create bool `json:"create"`
|
||||
Delete bool `json:"delete"`
|
||||
Fork bool `json:"fork"`
|
||||
Issues bool `json:"issues"`
|
||||
IssueComment bool `json:"issue_comment"`
|
||||
Push bool `json:"push"`
|
||||
PullRequest bool `json:"pull_request"`
|
||||
Repository bool `json:"repository"`
|
||||
Release bool `json:"release"`
|
||||
Create bool `json:"create"`
|
||||
Delete bool `json:"delete"`
|
||||
Fork bool `json:"fork"`
|
||||
Issues bool `json:"issues"`
|
||||
IssueAssign bool `json:"issue_assign"`
|
||||
IssueLabel bool `json:"issue_label"`
|
||||
IssueMilestone bool `json:"issue_milestone"`
|
||||
IssueComment bool `json:"issue_comment"`
|
||||
Push bool `json:"push"`
|
||||
PullRequest bool `json:"pull_request"`
|
||||
PullRequestAssign bool `json:"pull_request_assign"`
|
||||
PullRequestLabel bool `json:"pull_request_label"`
|
||||
PullRequestMilestone bool `json:"pull_request_milestone"`
|
||||
PullRequestComment bool `json:"pull_request_comment"`
|
||||
PullRequestReview bool `json:"pull_request_review"`
|
||||
PullRequestSync bool `json:"pull_request_sync"`
|
||||
Repository bool `json:"repository"`
|
||||
Release bool `json:"release"`
|
||||
}
|
||||
|
||||
// HookEvent represents events that will delivery hook.
|
||||
|
@ -154,6 +163,24 @@ func (w *Webhook) HasIssuesEvent() bool {
|
|||
(w.ChooseEvents && w.HookEvents.Issues)
|
||||
}
|
||||
|
||||
// HasIssuesAssignEvent returns true if hook enabled issues assign event.
|
||||
func (w *Webhook) HasIssuesAssignEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.IssueAssign)
|
||||
}
|
||||
|
||||
// HasIssuesLabelEvent returns true if hook enabled issues label event.
|
||||
func (w *Webhook) HasIssuesLabelEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.IssueLabel)
|
||||
}
|
||||
|
||||
// HasIssuesMilestoneEvent returns true if hook enabled issues milestone event.
|
||||
func (w *Webhook) HasIssuesMilestoneEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.IssueMilestone)
|
||||
}
|
||||
|
||||
// HasIssueCommentEvent returns true if hook enabled issue_comment event.
|
||||
func (w *Webhook) HasIssueCommentEvent() bool {
|
||||
return w.SendEverything ||
|
||||
|
@ -172,6 +199,54 @@ func (w *Webhook) HasPullRequestEvent() bool {
|
|||
(w.ChooseEvents && w.HookEvents.PullRequest)
|
||||
}
|
||||
|
||||
// HasPullRequestAssignEvent returns true if hook enabled pull request assign event.
|
||||
func (w *Webhook) HasPullRequestAssignEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestAssign)
|
||||
}
|
||||
|
||||
// HasPullRequestLabelEvent returns true if hook enabled pull request label event.
|
||||
func (w *Webhook) HasPullRequestLabelEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestLabel)
|
||||
}
|
||||
|
||||
// HasPullRequestMilestoneEvent returns true if hook enabled pull request milestone event.
|
||||
func (w *Webhook) HasPullRequestMilestoneEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestMilestone)
|
||||
}
|
||||
|
||||
// HasPullRequestCommentEvent returns true if hook enabled pull_request_comment event.
|
||||
func (w *Webhook) HasPullRequestCommentEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestComment)
|
||||
}
|
||||
|
||||
// HasPullRequestApprovedEvent returns true if hook enabled pull request review event.
|
||||
func (w *Webhook) HasPullRequestApprovedEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestReview)
|
||||
}
|
||||
|
||||
// HasPullRequestRejectedEvent returns true if hook enabled pull request review event.
|
||||
func (w *Webhook) HasPullRequestRejectedEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestReview)
|
||||
}
|
||||
|
||||
// HasPullRequestReviewCommentEvent returns true if hook enabled pull request review event.
|
||||
func (w *Webhook) HasPullRequestReviewCommentEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestReview)
|
||||
}
|
||||
|
||||
// HasPullRequestSyncEvent returns true if hook enabled pull request sync event.
|
||||
func (w *Webhook) HasPullRequestSyncEvent() bool {
|
||||
return w.SendEverything ||
|
||||
(w.ChooseEvents && w.HookEvents.PullRequestSync)
|
||||
}
|
||||
|
||||
// HasReleaseEvent returns if hook enabled release event.
|
||||
func (w *Webhook) HasReleaseEvent() bool {
|
||||
return w.SendEverything ||
|
||||
|
@ -198,8 +273,19 @@ func (w *Webhook) EventCheckers() []struct {
|
|||
{w.HasForkEvent, HookEventFork},
|
||||
{w.HasPushEvent, HookEventPush},
|
||||
{w.HasIssuesEvent, HookEventIssues},
|
||||
{w.HasIssuesAssignEvent, HookEventIssueAssign},
|
||||
{w.HasIssuesLabelEvent, HookEventIssueLabel},
|
||||
{w.HasIssuesMilestoneEvent, HookEventIssueMilestone},
|
||||
{w.HasIssueCommentEvent, HookEventIssueComment},
|
||||
{w.HasPullRequestEvent, HookEventPullRequest},
|
||||
{w.HasPullRequestAssignEvent, HookEventPullRequestAssign},
|
||||
{w.HasPullRequestLabelEvent, HookEventPullRequestLabel},
|
||||
{w.HasPullRequestMilestoneEvent, HookEventPullRequestMilestone},
|
||||
{w.HasPullRequestCommentEvent, HookEventPullRequestComment},
|
||||
{w.HasPullRequestApprovedEvent, HookEventPullRequestReviewApproved},
|
||||
{w.HasPullRequestRejectedEvent, HookEventPullRequestReviewRejected},
|
||||
{w.HasPullRequestCommentEvent, HookEventPullRequestReviewComment},
|
||||
{w.HasPullRequestSyncEvent, HookEventPullRequestSync},
|
||||
{w.HasRepositoryEvent, HookEventRepository},
|
||||
{w.HasReleaseEvent, HookEventRelease},
|
||||
}
|
||||
|
@ -498,20 +584,60 @@ 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"
|
||||
HookEventPullRequestApproved HookEventType = "pull_request_approved"
|
||||
HookEventPullRequestRejected HookEventType = "pull_request_rejected"
|
||||
HookEventPullRequestComment HookEventType = "pull_request_comment"
|
||||
HookEventCreate HookEventType = "create"
|
||||
HookEventDelete HookEventType = "delete"
|
||||
HookEventFork HookEventType = "fork"
|
||||
HookEventPush HookEventType = "push"
|
||||
HookEventIssues HookEventType = "issues"
|
||||
HookEventIssueAssign HookEventType = "issue_assign"
|
||||
HookEventIssueLabel HookEventType = "issue_label"
|
||||
HookEventIssueMilestone HookEventType = "issue_milestone"
|
||||
HookEventIssueComment HookEventType = "issue_comment"
|
||||
HookEventPullRequest HookEventType = "pull_request"
|
||||
HookEventPullRequestAssign HookEventType = "pull_request_assign"
|
||||
HookEventPullRequestLabel HookEventType = "pull_request_label"
|
||||
HookEventPullRequestMilestone HookEventType = "pull_request_milestone"
|
||||
HookEventPullRequestComment HookEventType = "pull_request_comment"
|
||||
HookEventPullRequestReviewApproved HookEventType = "pull_request_review_approved"
|
||||
HookEventPullRequestReviewRejected HookEventType = "pull_request_review_rejected"
|
||||
HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment"
|
||||
HookEventPullRequestSync HookEventType = "pull_request_sync"
|
||||
HookEventRepository HookEventType = "repository"
|
||||
HookEventRelease HookEventType = "release"
|
||||
)
|
||||
|
||||
// Event returns the HookEventType as an event string
|
||||
func (h HookEventType) Event() string {
|
||||
switch h {
|
||||
case HookEventCreate:
|
||||
return "create"
|
||||
case HookEventDelete:
|
||||
return "delete"
|
||||
case HookEventFork:
|
||||
return "fork"
|
||||
case HookEventPush:
|
||||
return "push"
|
||||
case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone:
|
||||
return "issues"
|
||||
case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone,
|
||||
HookEventPullRequestSync:
|
||||
return "pull_request"
|
||||
case HookEventIssueComment, HookEventPullRequestComment:
|
||||
return "issue_comment"
|
||||
case HookEventPullRequestReviewApproved:
|
||||
return "pull_request_approved"
|
||||
case HookEventPullRequestReviewRejected:
|
||||
return "pull_request_rejected"
|
||||
case HookEventPullRequestReviewComment:
|
||||
return "pull_request_comment"
|
||||
case HookEventRepository:
|
||||
return "repository"
|
||||
case HookEventRelease:
|
||||
return "release"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// HookRequest represents hook task request information.
|
||||
type HookRequest struct {
|
||||
Headers map[string]string `json:"headers"`
|
||||
|
|
|
@ -61,7 +61,11 @@ func TestWebhook_UpdateEvent(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWebhook_EventsArray(t *testing.T) {
|
||||
assert.Equal(t, []string{"create", "delete", "fork", "push", "issues", "issue_comment", "pull_request", "repository", "release"},
|
||||
assert.Equal(t, []string{"create", "delete", "fork", "push",
|
||||
"issues", "issue_assign", "issue_label", "issue_milestone", "issue_comment",
|
||||
"pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone",
|
||||
"pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected",
|
||||
"pull_request_review_comment", "pull_request_sync", "repository", "release"},
|
||||
(&Webhook{
|
||||
HookEvent: &HookEvent{SendEverything: true},
|
||||
}).EventsArray(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue