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:
Lunny Xiao 2020-12-10 01:20:13 +08:00 committed by GitHub
parent 18e4477ad4
commit 6edfa6bc88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 98 additions and 37 deletions

View file

@ -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
View 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()
}

View file

@ -124,7 +124,7 @@ func GenerateWebhooks(ctx DBContext, templateRepo, generateRepo *Repository) err
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,

View file

@ -112,7 +112,7 @@ type Webhook struct {
*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

View file

@ -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,

View file

@ -133,9 +133,9 @@ 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,

View file

@ -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:

View file

@ -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,