Files
Atay-Makhzan/models/webhook/webhook.go
T

599 lines
17 KiB
Go
Raw Normal View History

2014-05-05 20:52:25 -04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2017-05-29 09:17:15 +02:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2014-05-05 20:52:25 -04:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-11-10 13:13:16 +08:00
package webhook
2014-05-05 20:52:25 -04:00
import (
"context"
2015-08-27 23:06:14 +08:00
"fmt"
"strings"
2014-05-05 20:52:25 -04:00
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
2021-08-12 14:43:08 +02:00
"code.gitea.io/gitea/modules/util"
2021-08-12 14:43:08 +02:00
"xorm.io/builder"
2014-05-05 20:52:25 -04:00
)
2021-11-10 13:13:16 +08:00
// __ __ ___. .__ __
// / \ / \ ____\_ |__ | |__ ____ ____ | | __
// \ \/\/ // __ \| __ \| | \ / _ \ / _ \| |/ /
// \ /\ ___/| \_\ \ Y ( <_> | <_> ) <
// \__/\ / \___ >___ /___| /\____/ \____/|__|_ \
// \/ \/ \/ \/ \/
// ErrWebhookNotExist represents a "WebhookNotExist" kind of error.
type ErrWebhookNotExist struct {
ID int64
}
// IsErrWebhookNotExist checks if an error is a ErrWebhookNotExist.
func IsErrWebhookNotExist(err error) bool {
_, ok := err.(ErrWebhookNotExist)
return ok
}
func (err ErrWebhookNotExist) Error() string {
return fmt.Sprintf("webhook does not exist [id: %d]", err.ID)
}
2022-01-05 22:00:20 +01:00
// ErrHookTaskNotExist represents a "HookTaskNotExist" kind of error.
type ErrHookTaskNotExist struct {
HookID int64
UUID string
}
// IsErrWebhookNotExist checks if an error is a ErrWebhookNotExist.
func IsErrHookTaskNotExist(err error) bool {
_, ok := err.(ErrHookTaskNotExist)
return ok
}
func (err ErrHookTaskNotExist) Error() string {
return fmt.Sprintf("hook task does not exist [hook: %d, uuid: %s]", err.HookID, err.UUID)
}
// HookContentType is the content type of a web hook
2014-06-08 04:45:34 -04:00
type HookContentType int
2014-05-05 20:52:25 -04:00
const (
// ContentTypeJSON is a JSON payload for web hooks
2016-11-07 21:58:22 +01:00
ContentTypeJSON HookContentType = iota + 1
// ContentTypeForm is an url-encoded form payload for web hook
2016-11-07 17:53:22 +01:00
ContentTypeForm
2014-05-05 20:52:25 -04:00
)
2014-11-13 12:57:00 -05:00
var hookContentTypes = map[string]HookContentType{
2016-11-07 21:58:22 +01:00
"json": ContentTypeJSON,
2016-11-07 17:53:22 +01:00
"form": ContentTypeForm,
2014-11-13 12:57:00 -05:00
}
// ToHookContentType returns HookContentType by given name.
func ToHookContentType(name string) HookContentType {
return hookContentTypes[name]
}
// HookTaskCleanupType is the type of cleanup to perform on hook_task
type HookTaskCleanupType int
const (
// OlderThan hook_task rows will be cleaned up by the age of the row
OlderThan HookTaskCleanupType = iota
// PerWebhook hook_task rows will be cleaned up by leaving the most recent deliveries for each webhook
PerWebhook
)
var hookTaskCleanupTypes = map[string]HookTaskCleanupType{
"OlderThan": OlderThan,
"PerWebhook": PerWebhook,
}
// ToHookTaskCleanupType returns HookTaskCleanupType by given name.
func ToHookTaskCleanupType(name string) HookTaskCleanupType {
return hookTaskCleanupTypes[name]
}
// Name returns the name of a given web hook's content type
2014-11-13 02:32:18 -05:00
func (t HookContentType) Name() string {
switch t {
2016-11-07 21:58:22 +01:00
case ContentTypeJSON:
2014-11-13 02:32:18 -05:00
return "json"
2016-11-07 17:53:22 +01:00
case ContentTypeForm:
2014-11-13 02:32:18 -05:00
return "form"
}
return ""
}
2014-11-13 12:57:00 -05:00
// IsValidHookContentType returns true if given name is a valid hook content type.
func IsValidHookContentType(name string) bool {
_, ok := hookContentTypes[name]
return ok
}
// HookEvents is a set of web hook events
2015-08-28 23:36:13 +08:00
type HookEvents struct {
2020-03-05 23:10:48 -06:00
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"`
2015-08-28 23:36:13 +08:00
}
2014-06-08 04:45:34 -04:00
// HookEvent represents events that will delivery hook.
2014-05-05 20:52:25 -04:00
type HookEvent struct {
2019-09-09 08:48:21 +03:00
PushOnly bool `json:"push_only"`
SendEverything bool `json:"send_everything"`
ChooseEvents bool `json:"choose_events"`
BranchFilter string `json:"branch_filter"`
2015-08-28 23:36:13 +08:00
HookEvents `json:"events"`
2014-05-05 20:52:25 -04:00
}
// HookType is the type of a webhook
type HookType = string
// Types of webhooks
const (
GITEA HookType = "gitea"
GOGS HookType = "gogs"
SLACK HookType = "slack"
DISCORD HookType = "discord"
DINGTALK HookType = "dingtalk"
TELEGRAM HookType = "telegram"
MSTEAMS HookType = "msteams"
FEISHU HookType = "feishu"
MATRIX HookType = "matrix"
WECHATWORK HookType = "wechatwork"
)
// HookStatus is the status of a web hook
2015-08-26 21:45:51 +08:00
type HookStatus int
// Possible statuses of a web hook
2015-08-26 21:45:51 +08:00
const (
2016-11-07 17:08:21 +01:00
HookStatusNone = iota
2016-11-07 16:37:32 +01:00
HookStatusSucceed
HookStatusFail
2015-08-26 21:45:51 +08:00
)
2014-06-08 04:45:34 -04:00
// Webhook represents a web hook object.
2014-05-05 20:52:25 -04:00
type Webhook struct {
2020-03-08 22:08:05 +00:00
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"` // An ID of 0 indicates either a default or system webhook
OrgID int64 `xorm:"INDEX"`
IsSystemWebhook bool
URL string `xorm:"url TEXT"`
HTTPMethod string `xorm:"http_method"`
ContentType HookContentType
Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"`
IsActive bool `xorm:"INDEX"`
Type HookType `xorm:"VARCHAR(16) 'type'"`
Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
2014-05-05 20:52:25 -04:00
}
func init() {
db.RegisterModel(new(Webhook))
}
// AfterLoad updates the webhook object upon setting a column
func (w *Webhook) AfterLoad() {
w.HookEvent = &HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
2019-04-02 08:48:31 +01:00
log.Error("Unmarshal[%d]: %v", w.ID, err)
2014-05-05 20:52:25 -04:00
}
}
2015-08-27 23:06:14 +08:00
// History returns history of webhook by given conditions.
func (w *Webhook) History(page int) ([]*HookTask, error) {
return HookTasks(w.ID, page)
}
2014-06-08 04:54:52 -04:00
// UpdateEvent handles conversion from HookEvent to Events.
2014-06-08 04:45:34 -04:00
func (w *Webhook) UpdateEvent() error {
2014-05-05 21:36:08 -04:00
data, err := json.Marshal(w.HookEvent)
2014-05-05 20:52:25 -04:00
w.Events = string(data)
return err
}
2015-08-28 23:36:13 +08:00
// HasCreateEvent returns true if hook enabled create event.
func (w *Webhook) HasCreateEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Create)
}
// HasDeleteEvent returns true if hook enabled delete event.
func (w *Webhook) HasDeleteEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Delete)
}
// HasForkEvent returns true if hook enabled fork event.
func (w *Webhook) HasForkEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Fork)
}
// HasIssuesEvent returns true if hook enabled issues event.
func (w *Webhook) HasIssuesEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Issues)
}
2020-03-05 23:10:48 -06:00
// 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 ||
(w.ChooseEvents && w.HookEvents.IssueComment)
}
2014-12-06 20:22:48 -05:00
// HasPushEvent returns true if hook enabled push event.
2014-05-06 11:50:31 -04:00
func (w *Webhook) HasPushEvent() bool {
2015-08-28 23:36:13 +08:00
return w.PushOnly || w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Push)
2014-05-06 11:50:31 -04:00
}
// HasPullRequestEvent returns true if hook enabled pull request event.
func (w *Webhook) HasPullRequestEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.PullRequest)
}
2020-03-05 23:10:48 -06:00
// 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 ||
(w.ChooseEvents && w.HookEvents.Release)
}
2017-09-03 01:20:24 -07:00
// HasRepositoryEvent returns if hook enabled repository event.
func (w *Webhook) HasRepositoryEvent() bool {
return w.SendEverything ||
(w.ChooseEvents && w.HookEvents.Repository)
}
// EventCheckers returns event checkers
func (w *Webhook) EventCheckers() []struct {
Has func() bool
Type HookEventType
} {
return []struct {
Has func() bool
Type HookEventType
}{
{w.HasCreateEvent, HookEventCreate},
{w.HasDeleteEvent, HookEventDelete},
{w.HasForkEvent, HookEventFork},
{w.HasPushEvent, HookEventPush},
{w.HasIssuesEvent, HookEventIssues},
2020-03-05 23:10:48 -06:00
{w.HasIssuesAssignEvent, HookEventIssueAssign},
{w.HasIssuesLabelEvent, HookEventIssueLabel},
{w.HasIssuesMilestoneEvent, HookEventIssueMilestone},
{w.HasIssueCommentEvent, HookEventIssueComment},
{w.HasPullRequestEvent, HookEventPullRequest},
2020-03-05 23:10:48 -06:00
{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},
}
}
// EventsArray returns an array of hook events
2015-08-29 11:49:59 +08:00
func (w *Webhook) EventsArray() []string {
events := make([]string, 0, 7)
for _, c := range w.EventCheckers() {
if c.Has() {
events = append(events, string(c.Type))
}
}
2015-08-29 11:49:59 +08:00
return events
}
2014-06-08 04:45:34 -04:00
// CreateWebhook creates a new web hook.
2021-11-10 13:13:16 +08:00
func CreateWebhook(ctx context.Context, w *Webhook) error {
w.Type = strings.TrimSpace(w.Type)
2021-11-10 13:13:16 +08:00
return db.Insert(ctx, w)
2014-05-05 20:52:25 -04:00
}
// getWebhook uses argument bean as query condition,
// ID must be specified and do not assign unnecessary fields.
func getWebhook(bean *Webhook) (*Webhook, error) {
2021-09-23 16:45:36 +01:00
has, err := db.GetEngine(db.DefaultContext).Get(bean)
2014-05-05 21:36:08 -04:00
if err != nil {
return nil, err
} else if !has {
return nil, ErrWebhookNotExist{bean.ID}
2014-05-05 21:36:08 -04:00
}
return bean, nil
}
2017-08-30 13:36:52 +08:00
// GetWebhookByID returns webhook of repository by given ID.
func GetWebhookByID(id int64) (*Webhook, error) {
return getWebhook(&Webhook{
ID: id,
})
}
// GetWebhookByRepoID returns webhook of repository by given ID.
func GetWebhookByRepoID(repoID, id int64) (*Webhook, error) {
return getWebhook(&Webhook{
ID: id,
RepoID: repoID,
})
2014-05-05 21:36:08 -04:00
}
// GetWebhookByOrgID returns webhook of organization by given ID.
func GetWebhookByOrgID(orgID, id int64) (*Webhook, error) {
return getWebhook(&Webhook{
ID: id,
OrgID: orgID,
})
}
2021-08-12 14:43:08 +02:00
// ListWebhookOptions are options to filter webhooks on ListWebhooksByOpts
type ListWebhookOptions struct {
db.ListOptions
2021-08-12 14:43:08 +02:00
RepoID int64
OrgID int64
IsActive util.OptionalBool
2017-09-03 01:20:24 -07:00
}
2021-08-12 14:43:08 +02:00
func (opts *ListWebhookOptions) toCond() builder.Cond {
cond := builder.NewCond()
if opts.RepoID != 0 {
cond = cond.And(builder.Eq{"webhook.repo_id": opts.RepoID})
}
if opts.OrgID != 0 {
cond = cond.And(builder.Eq{"webhook.org_id": opts.OrgID})
}
if !opts.IsActive.IsNone() {
cond = cond.And(builder.Eq{"webhook.is_active": opts.IsActive.IsTrue()})
2020-01-24 19:00:29 +00:00
}
2021-08-12 14:43:08 +02:00
return cond
}
2020-01-24 19:00:29 +00:00
func listWebhooksByOpts(e db.Engine, opts *ListWebhookOptions) ([]*Webhook, error) {
2021-08-12 14:43:08 +02:00
sess := e.Where(opts.toCond())
2020-01-24 19:00:29 +00:00
2021-08-12 14:43:08 +02:00
if opts.Page != 0 {
sess = db.SetSessionPagination(sess, opts)
2021-08-12 14:43:08 +02:00
webhooks := make([]*Webhook, 0, opts.PageSize)
err := sess.Find(&webhooks)
return webhooks, err
}
2014-05-05 21:36:08 -04:00
2021-08-12 14:43:08 +02:00
webhooks := make([]*Webhook, 0, 10)
err := sess.Find(&webhooks)
return webhooks, err
2017-09-03 01:20:24 -07:00
}
2021-08-12 14:43:08 +02:00
// ListWebhooksByOpts return webhooks based on options
func ListWebhooksByOpts(opts *ListWebhookOptions) ([]*Webhook, error) {
2021-09-23 16:45:36 +01:00
return listWebhooksByOpts(db.GetEngine(db.DefaultContext), opts)
}
2021-08-12 14:43:08 +02:00
// CountWebhooksByOpts count webhooks based on options and ignore pagination
func CountWebhooksByOpts(opts *ListWebhookOptions) (int64, error) {
2021-09-23 16:45:36 +01:00
return db.GetEngine(db.DefaultContext).Where(opts.toCond()).Count(&Webhook{})
}
2019-03-18 22:33:20 -04:00
// GetDefaultWebhooks returns all admin-default webhooks.
func GetDefaultWebhooks() ([]*Webhook, error) {
2021-11-10 13:13:16 +08:00
return getDefaultWebhooks(db.DefaultContext)
2019-03-18 22:33:20 -04:00
}
2021-11-10 13:13:16 +08:00
func getDefaultWebhooks(ctx context.Context) ([]*Webhook, error) {
2019-03-18 22:33:20 -04:00
webhooks := make([]*Webhook, 0, 5)
2021-11-10 13:13:16 +08:00
return webhooks, db.GetEngine(ctx).
2020-03-08 22:08:05 +00:00
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, false).
Find(&webhooks)
}
// GetSystemOrDefaultWebhook returns admin system or default webhook by given ID.
func GetSystemOrDefaultWebhook(id int64) (*Webhook, error) {
2020-03-08 22:08:05 +00:00
webhook := &Webhook{ID: id}
2021-09-23 16:45:36 +01:00
has, err := db.GetEngine(db.DefaultContext).
Where("repo_id=? AND org_id=?", 0, 0).
2020-03-08 22:08:05 +00:00
Get(webhook)
if err != nil {
return nil, err
} else if !has {
return nil, ErrWebhookNotExist{id}
}
return webhook, nil
}
// GetSystemWebhooks returns all admin system webhooks.
func GetSystemWebhooks() ([]*Webhook, error) {
2021-09-23 16:45:36 +01:00
return getSystemWebhooks(db.GetEngine(db.DefaultContext))
2020-03-08 22:08:05 +00:00
}
func getSystemWebhooks(e db.Engine) ([]*Webhook, error) {
2020-03-08 22:08:05 +00:00
webhooks := make([]*Webhook, 0, 5)
return webhooks, e.
Where("repo_id=? AND org_id=? AND is_system_webhook=?", 0, 0, true).
2019-03-18 22:33:20 -04:00
Find(&webhooks)
}
2014-06-08 04:45:34 -04:00
// UpdateWebhook updates information of webhook.
func UpdateWebhook(w *Webhook) error {
2021-09-23 16:45:36 +01:00
_, err := db.GetEngine(db.DefaultContext).ID(w.ID).AllCols().Update(w)
2014-06-08 04:45:34 -04:00
return err
}
2017-08-30 13:36:52 +08:00
// UpdateWebhookLastStatus updates last status of webhook.
func UpdateWebhookLastStatus(w *Webhook) error {
2021-09-23 16:45:36 +01:00
_, err := db.GetEngine(db.DefaultContext).ID(w.ID).Cols("last_status").Update(w)
2017-08-30 13:36:52 +08:00
return err
}
// deleteWebhook uses argument bean as query condition,
// ID must be specified and do not assign unnecessary fields.
func deleteWebhook(bean *Webhook) (err error) {
ctx, committer, err := db.TxContext()
if err != nil {
2015-08-26 21:45:51 +08:00
return err
}
defer committer.Close()
2015-08-26 21:45:51 +08:00
if count, err := db.DeleteByBean(ctx, bean); err != nil {
2015-08-26 21:45:51 +08:00
return err
2017-01-13 21:14:48 -05:00
} else if count == 0 {
return ErrWebhookNotExist{ID: bean.ID}
} else if _, err = db.DeleteByBean(ctx, &HookTask{HookID: bean.ID}); err != nil {
2015-08-26 21:45:51 +08:00
return err
}
return committer.Commit()
2014-05-05 21:36:08 -04:00
}
2014-06-08 04:45:34 -04:00
// DeleteWebhookByRepoID deletes webhook of repository by given ID.
2016-07-23 20:24:44 +08:00
func DeleteWebhookByRepoID(repoID, id int64) error {
return deleteWebhook(&Webhook{
ID: id,
RepoID: repoID,
})
}
// DeleteWebhookByOrgID deletes webhook of organization by given ID.
2016-07-23 20:24:44 +08:00
func DeleteWebhookByOrgID(orgID, id int64) error {
return deleteWebhook(&Webhook{
ID: id,
OrgID: orgID,
})
}
2020-03-08 22:08:05 +00:00
// DeleteDefaultSystemWebhook deletes an admin-configured default or system webhook (where Org and Repo ID both 0)
func DeleteDefaultSystemWebhook(id int64) error {
ctx, committer, err := db.TxContext()
if err != nil {
2019-03-18 22:33:20 -04:00
return err
}
defer committer.Close()
2019-03-18 22:33:20 -04:00
count, err := db.GetEngine(ctx).
2019-03-18 22:33:20 -04:00
Where("repo_id=? AND org_id=?", 0, 0).
Delete(&Webhook{ID: id})
if err != nil {
return err
} else if count == 0 {
return ErrWebhookNotExist{ID: id}
}
if _, err := db.DeleteByBean(ctx, &HookTask{HookID: id}); err != nil {
2019-03-18 22:33:20 -04:00
return err
}
return committer.Commit()
2019-03-18 22:33:20 -04:00
}
2021-11-10 13:13:16 +08:00
// CopyDefaultWebhooksToRepo creates copies of the default webhooks in a new repo
func CopyDefaultWebhooksToRepo(ctx context.Context, repoID int64) error {
ws, err := getDefaultWebhooks(ctx)
2019-03-18 22:33:20 -04:00
if err != nil {
return fmt.Errorf("GetDefaultWebhooks: %v", err)
}
for _, w := range ws {
w.ID = 0
w.RepoID = repoID
2021-11-10 13:13:16 +08:00
if err := CreateWebhook(ctx, w); err != nil {
2019-03-18 22:33:20 -04:00
return fmt.Errorf("CreateWebhook: %v", err)
}
}
return nil
}