Fix broken migration on webhook (#13911)
* Fix broken migration on webhook * Fix lint Co-authored-by: John Olheiser <john.olheiser@gmail.com>
This commit is contained in:
parent
18e4477ad4
commit
6edfa6bc88
8 changed files with 98 additions and 37 deletions
|
@ -267,6 +267,8 @@ var migrations = []Migration{
|
||||||
NewMigration("Add block on official review requests branch protection", addBlockOnOfficialReviewRequests),
|
NewMigration("Add block on official review requests branch protection", addBlockOnOfficialReviewRequests),
|
||||||
// v161 -> v162
|
// v161 -> v162
|
||||||
NewMigration("Convert task type from int to string", convertTaskTypeToString),
|
NewMigration("Convert task type from int to string", convertTaskTypeToString),
|
||||||
|
// v162 -> v163
|
||||||
|
NewMigration("Convert webhook task type from int to string", convertWebhookTaskTypeToString),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
|
59
models/migrations/v162.go
Normal file
59
models/migrations/v162.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// 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 (
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertWebhookTaskTypeToString(x *xorm.Engine) error {
|
||||||
|
const (
|
||||||
|
GOGS int = iota + 1
|
||||||
|
SLACK
|
||||||
|
GITEA
|
||||||
|
DISCORD
|
||||||
|
DINGTALK
|
||||||
|
TELEGRAM
|
||||||
|
MSTEAMS
|
||||||
|
FEISHU
|
||||||
|
MATRIX
|
||||||
|
)
|
||||||
|
|
||||||
|
var hookTaskTypes = map[int]string{
|
||||||
|
GITEA: "gitea",
|
||||||
|
GOGS: "gogs",
|
||||||
|
SLACK: "slack",
|
||||||
|
DISCORD: "discord",
|
||||||
|
DINGTALK: "dingtalk",
|
||||||
|
TELEGRAM: "telegram",
|
||||||
|
MSTEAMS: "msteams",
|
||||||
|
FEISHU: "feishu",
|
||||||
|
MATRIX: "matrix",
|
||||||
|
}
|
||||||
|
|
||||||
|
type Webhook struct {
|
||||||
|
Type string `xorm:"char(16) index"`
|
||||||
|
}
|
||||||
|
if err := x.Sync2(new(Webhook)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, s := range hookTaskTypes {
|
||||||
|
if _, err := x.Exec("UPDATE webhook set type = ? where hook_task_type=?", s, i); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := x.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
if err := sess.Begin(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := dropTableColumns(sess, "webhook", "hook_task_type"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess.Commit()
|
||||||
|
}
|
|
@ -117,17 +117,17 @@ func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) err
|
||||||
|
|
||||||
for _, templateWebhook := range templateWebhooks {
|
for _, templateWebhook := range templateWebhooks {
|
||||||
generateWebhook := &Webhook{
|
generateWebhook := &Webhook{
|
||||||
RepoID: generateRepo.ID,
|
RepoID: generateRepo.ID,
|
||||||
URL: templateWebhook.URL,
|
URL: templateWebhook.URL,
|
||||||
HTTPMethod: templateWebhook.HTTPMethod,
|
HTTPMethod: templateWebhook.HTTPMethod,
|
||||||
ContentType: templateWebhook.ContentType,
|
ContentType: templateWebhook.ContentType,
|
||||||
Secret: templateWebhook.Secret,
|
Secret: templateWebhook.Secret,
|
||||||
HookEvent: templateWebhook.HookEvent,
|
HookEvent: templateWebhook.HookEvent,
|
||||||
IsActive: templateWebhook.IsActive,
|
IsActive: templateWebhook.IsActive,
|
||||||
HookTaskType: templateWebhook.HookTaskType,
|
Type: templateWebhook.Type,
|
||||||
OrgID: templateWebhook.OrgID,
|
OrgID: templateWebhook.OrgID,
|
||||||
Events: templateWebhook.Events,
|
Events: templateWebhook.Events,
|
||||||
Meta: templateWebhook.Meta,
|
Meta: templateWebhook.Meta,
|
||||||
}
|
}
|
||||||
if err := createWebhook(ctx.e, generateWebhook); err != nil {
|
if err := createWebhook(ctx.e, generateWebhook); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -110,11 +110,11 @@ type Webhook struct {
|
||||||
Secret string `xorm:"TEXT"`
|
Secret string `xorm:"TEXT"`
|
||||||
Events string `xorm:"TEXT"`
|
Events string `xorm:"TEXT"`
|
||||||
*HookEvent `xorm:"-"`
|
*HookEvent `xorm:"-"`
|
||||||
IsSSL bool `xorm:"is_ssl"`
|
IsSSL bool `xorm:"is_ssl"`
|
||||||
IsActive bool `xorm:"INDEX"`
|
IsActive bool `xorm:"INDEX"`
|
||||||
HookTaskType HookTaskType
|
Type HookTaskType `xorm:"char(16) 'type'"`
|
||||||
Meta string `xorm:"TEXT"` // store hook-specific attributes
|
Meta string `xorm:"TEXT"` // store hook-specific attributes
|
||||||
LastStatus HookStatus // Last delivery status
|
LastStatus HookStatus // Last delivery status
|
||||||
|
|
||||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||||
|
|
|
@ -227,7 +227,7 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
|
||||||
"url": w.URL,
|
"url": w.URL,
|
||||||
"content_type": w.ContentType.Name(),
|
"content_type": w.ContentType.Name(),
|
||||||
}
|
}
|
||||||
if w.HookTaskType == models.SLACK {
|
if w.Type == models.SLACK {
|
||||||
s := webhook.GetSlackHook(w)
|
s := webhook.GetSlackHook(w)
|
||||||
config["channel"] = s.Channel
|
config["channel"] = s.Channel
|
||||||
config["username"] = s.Username
|
config["username"] = s.Username
|
||||||
|
@ -237,7 +237,7 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook {
|
||||||
|
|
||||||
return &api.Hook{
|
return &api.Hook{
|
||||||
ID: w.ID,
|
ID: w.ID,
|
||||||
Type: string(w.HookTaskType),
|
Type: string(w.Type),
|
||||||
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
|
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
|
||||||
Active: w.IsActive,
|
Active: w.IsActive,
|
||||||
Config: config,
|
Config: config,
|
||||||
|
|
|
@ -132,10 +132,10 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
|
||||||
},
|
},
|
||||||
BranchFilter: form.BranchFilter,
|
BranchFilter: form.BranchFilter,
|
||||||
},
|
},
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.HookTaskType(form.Type),
|
Type: models.HookTaskType(form.Type),
|
||||||
}
|
}
|
||||||
if w.HookTaskType == models.SLACK {
|
if w.Type == models.SLACK {
|
||||||
channel, ok := form.Config["channel"]
|
channel, ok := form.Config["channel"]
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: channel")
|
ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: channel")
|
||||||
|
@ -219,7 +219,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
|
||||||
w.ContentType = models.ToHookContentType(ct)
|
w.ContentType = models.ToHookContentType(ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.HookTaskType == models.SLACK {
|
if w.Type == models.SLACK {
|
||||||
if channel, ok := form.Config["channel"]; ok {
|
if channel, ok := form.Config["channel"]; ok {
|
||||||
meta, err := json.Marshal(&webhook.SlackMeta{
|
meta, err := json.Marshal(&webhook.SlackMeta{
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
|
|
|
@ -208,7 +208,7 @@ func GiteaHooksNewPost(ctx *context.Context, form auth.NewWebhookForm) {
|
||||||
Secret: form.Secret,
|
Secret: form.Secret,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.GITEA,
|
Type: models.GITEA,
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ func newGogsWebhookPost(ctx *context.Context, form auth.NewGogshookForm, kind mo
|
||||||
Secret: form.Secret,
|
Secret: form.Secret,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: kind,
|
Type: kind,
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ func DiscordHooksNewPost(ctx *context.Context, form auth.NewDiscordHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.DISCORD,
|
Type: models.DISCORD,
|
||||||
Meta: string(meta),
|
Meta: string(meta),
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -353,7 +353,7 @@ func DingtalkHooksNewPost(ctx *context.Context, form auth.NewDingtalkHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.DINGTALK,
|
Type: models.DINGTALK,
|
||||||
Meta: "",
|
Meta: "",
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -404,7 +404,7 @@ func TelegramHooksNewPost(ctx *context.Context, form auth.NewTelegramHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.TELEGRAM,
|
Type: models.TELEGRAM,
|
||||||
Meta: string(meta),
|
Meta: string(meta),
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -458,7 +458,7 @@ func MatrixHooksNewPost(ctx *context.Context, form auth.NewMatrixHookForm) {
|
||||||
HTTPMethod: "PUT",
|
HTTPMethod: "PUT",
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.MATRIX,
|
Type: models.MATRIX,
|
||||||
Meta: string(meta),
|
Meta: string(meta),
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -500,7 +500,7 @@ func MSTeamsHooksNewPost(ctx *context.Context, form auth.NewMSTeamsHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.MSTEAMS,
|
Type: models.MSTEAMS,
|
||||||
Meta: "",
|
Meta: "",
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -559,7 +559,7 @@ func SlackHooksNewPost(ctx *context.Context, form auth.NewSlackHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.SLACK,
|
Type: models.SLACK,
|
||||||
Meta: string(meta),
|
Meta: string(meta),
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -601,7 +601,7 @@ func FeishuHooksNewPost(ctx *context.Context, form auth.NewFeishuHookForm) {
|
||||||
ContentType: models.ContentTypeJSON,
|
ContentType: models.ContentTypeJSON,
|
||||||
HookEvent: ParseHookEvent(form.WebhookForm),
|
HookEvent: ParseHookEvent(form.WebhookForm),
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.FEISHU,
|
Type: models.FEISHU,
|
||||||
Meta: "",
|
Meta: "",
|
||||||
OrgID: orCtx.OrgID,
|
OrgID: orCtx.OrgID,
|
||||||
IsSystemWebhook: orCtx.IsSystemWebhook,
|
IsSystemWebhook: orCtx.IsSystemWebhook,
|
||||||
|
@ -647,8 +647,8 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *models.Webhook) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["HookType"] = w.HookTaskType
|
ctx.Data["HookType"] = w.Type
|
||||||
switch w.HookTaskType {
|
switch w.Type {
|
||||||
case models.SLACK:
|
case models.SLACK:
|
||||||
ctx.Data["SlackHook"] = webhook.GetSlackHook(w)
|
ctx.Data["SlackHook"] = webhook.GetSlackHook(w)
|
||||||
case models.DISCORD:
|
case models.DISCORD:
|
||||||
|
|
|
@ -128,7 +128,7 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo
|
||||||
// Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.).
|
// Avoid sending "0 new commits" to non-integration relevant webhooks (e.g. slack, discord, etc.).
|
||||||
// Integration webhooks (e.g. drone) still receive the required data.
|
// Integration webhooks (e.g. drone) still receive the required data.
|
||||||
if pushEvent, ok := p.(*api.PushPayload); ok &&
|
if pushEvent, ok := p.(*api.PushPayload); ok &&
|
||||||
w.HookTaskType != models.GITEA && w.HookTaskType != models.GOGS &&
|
w.Type != models.GITEA && w.Type != models.GOGS &&
|
||||||
len(pushEvent.Commits) == 0 {
|
len(pushEvent.Commits) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -144,11 +144,11 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo
|
||||||
|
|
||||||
var payloader api.Payloader
|
var payloader api.Payloader
|
||||||
var err error
|
var err error
|
||||||
webhook, ok := webhooks[w.HookTaskType]
|
webhook, ok := webhooks[w.Type]
|
||||||
if ok {
|
if ok {
|
||||||
payloader, err = webhook.payloadCreator(p, event, w.Meta)
|
payloader, err = webhook.payloadCreator(p, event, w.Meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("create payload for %s[%s]: %v", w.HookTaskType, event, err)
|
return fmt.Errorf("create payload for %s[%s]: %v", w.Type, event, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.SetSecret(w.Secret)
|
p.SetSecret(w.Secret)
|
||||||
|
@ -172,7 +172,7 @@ func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.Hoo
|
||||||
if err = models.CreateHookTask(&models.HookTask{
|
if err = models.CreateHookTask(&models.HookTask{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
HookID: w.ID,
|
HookID: w.ID,
|
||||||
Typ: w.HookTaskType,
|
Typ: w.Type,
|
||||||
URL: w.URL,
|
URL: w.URL,
|
||||||
Signature: signature,
|
Signature: signature,
|
||||||
Payloader: payloader,
|
Payloader: payloader,
|
||||||
|
|
Reference in a new issue