aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorJohn Olheiser <john.olheiser@gmail.com>2020-03-05 23:10:48 -0600
committerGitHub <noreply@github.com>2020-03-06 07:10:48 +0200
commit3f1c0841cb9fc61136b85c6b39613679d2851707 (patch)
treed0b15f3b809891d83f41fed5ab7378765330525a /models
parent80db44267ccb688c596e8375523af5cd92864d87 (diff)
downloadgitea-3f1c0841cb9fc61136b85c6b39613679d2851707.tar.gz
gitea-3f1c0841cb9fc61136b85c6b39613679d2851707.zip
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>
Diffstat (limited to 'models')
-rw-r--r--models/migrations/migrations.go2
-rw-r--r--models/migrations/v130.go101
-rw-r--r--models/webhook.go168
-rw-r--r--models/webhook_test.go6
4 files changed, 255 insertions, 22 deletions
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index bb72b7f5d3..ba411dd8c2 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -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
diff --git a/models/migrations/v130.go b/models/migrations/v130.go
new file mode 100644
index 0000000000..3a7efedf86
--- /dev/null
+++ b/models/migrations/v130.go
@@ -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
+}
diff --git a/models/webhook.go b/models/webhook.go
index 626489b342..82aedf7e81 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -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"`
diff --git a/models/webhook_test.go b/models/webhook_test.go
index f8e4234299..5ee7f9159b 100644
--- a/models/webhook_test.go
+++ b/models/webhook_test.go
@@ -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(),