Fix #242
This commit is contained in:
parent
a0318db2f9
commit
302c863cda
14 changed files with 432 additions and 375 deletions
|
@ -15,7 +15,6 @@ import (
|
|||
qlog "github.com/qiniu/log"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/hooks"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
@ -131,35 +130,35 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
|
|||
}
|
||||
|
||||
repoLink := fmt.Sprintf("%s%s/%s", setting.AppUrl, repoUserName, repoName)
|
||||
commits := make([]*hooks.PayloadCommit, len(commit.Commits))
|
||||
commits := make([]*PayloadCommit, len(commit.Commits))
|
||||
for i, cmt := range commit.Commits {
|
||||
commits[i] = &hooks.PayloadCommit{
|
||||
commits[i] = &PayloadCommit{
|
||||
Id: cmt.Sha1,
|
||||
Message: cmt.Message,
|
||||
Url: fmt.Sprintf("%s/commit/%s", repoLink, cmt.Sha1),
|
||||
Author: &hooks.PayloadAuthor{
|
||||
Author: &PayloadAuthor{
|
||||
Name: cmt.AuthorName,
|
||||
Email: cmt.AuthorEmail,
|
||||
},
|
||||
}
|
||||
}
|
||||
p := &hooks.Payload{
|
||||
p := &Payload{
|
||||
Ref: refFullName,
|
||||
Commits: commits,
|
||||
Repo: &hooks.PayloadRepo{
|
||||
Repo: &PayloadRepo{
|
||||
Id: repo.Id,
|
||||
Name: repo.LowerName,
|
||||
Url: repoLink,
|
||||
Description: repo.Description,
|
||||
Website: repo.Website,
|
||||
Watchers: repo.NumWatches,
|
||||
Owner: &hooks.PayloadAuthor{
|
||||
Owner: &PayloadAuthor{
|
||||
Name: repoUserName,
|
||||
Email: actEmail,
|
||||
},
|
||||
Private: repo.IsPrivate,
|
||||
},
|
||||
Pusher: &hooks.PayloadAuthor{
|
||||
Pusher: &PayloadAuthor{
|
||||
Name: repo.Owner.LowerName,
|
||||
Email: repo.Owner.Email,
|
||||
},
|
||||
|
@ -172,7 +171,13 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
|
|||
}
|
||||
|
||||
p.Secret = w.Secret
|
||||
hooks.AddHookTask(&hooks.HookTask{hooks.HTT_WEBHOOK, w.Url, p, w.ContentType, w.IsSsl})
|
||||
CreateHookTask(&HookTask{
|
||||
Type: WEBHOOK,
|
||||
Url: w.Url,
|
||||
Payload: p,
|
||||
ContentType: w.ContentType,
|
||||
IsSsl: w.IsSsl,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func init() {
|
|||
tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
|
||||
new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
|
||||
new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
|
||||
new(Milestone), new(Label))
|
||||
new(Milestone), new(Label), new(HookTask))
|
||||
}
|
||||
|
||||
func LoadModelsConfig() {
|
||||
|
|
|
@ -7,29 +7,35 @@ package models
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/gogits/gogs/modules/httplib"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrWebhookNotExist = errors.New("Webhook does not exist")
|
||||
)
|
||||
|
||||
// Content types.
|
||||
type HookContentType int
|
||||
|
||||
const (
|
||||
CT_JSON = iota + 1
|
||||
CT_FORM
|
||||
JSON HookContentType = iota + 1
|
||||
FORM
|
||||
)
|
||||
|
||||
// HookEvent represents events that will delivery hook.
|
||||
type HookEvent struct {
|
||||
PushOnly bool `json:"push_only"`
|
||||
}
|
||||
|
||||
// Webhook represents a web hook object.
|
||||
type Webhook struct {
|
||||
Id int64
|
||||
RepoId int64
|
||||
Url string `xorm:"TEXT"`
|
||||
ContentType int
|
||||
ContentType HookContentType
|
||||
Secret string `xorm:"TEXT"`
|
||||
Events string `xorm:"TEXT"`
|
||||
*HookEvent `xorm:"-"`
|
||||
|
@ -44,7 +50,7 @@ func (w *Webhook) GetEvent() {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *Webhook) SaveEvent() error {
|
||||
func (w *Webhook) UpdateEvent() error {
|
||||
data, err := json.Marshal(w.HookEvent)
|
||||
w.Events = string(data)
|
||||
return err
|
||||
|
@ -57,18 +63,12 @@ func (w *Webhook) HasPushEvent() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// CreateWebhook creates new webhook.
|
||||
// CreateWebhook creates a new web hook.
|
||||
func CreateWebhook(w *Webhook) error {
|
||||
_, err := orm.Insert(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateWebhook updates information of webhook.
|
||||
func UpdateWebhook(w *Webhook) error {
|
||||
_, err := orm.AllCols().Update(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetWebhookById returns webhook by given ID.
|
||||
func GetWebhookById(hookId int64) (*Webhook, error) {
|
||||
w := &Webhook{Id: hookId}
|
||||
|
@ -93,8 +93,114 @@ func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) {
|
|||
return ws, err
|
||||
}
|
||||
|
||||
// UpdateWebhook updates information of webhook.
|
||||
func UpdateWebhook(w *Webhook) error {
|
||||
_, err := orm.AllCols().Update(w)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteWebhook deletes webhook of repository.
|
||||
func DeleteWebhook(hookId int64) error {
|
||||
_, err := orm.Delete(&Webhook{Id: hookId})
|
||||
return err
|
||||
}
|
||||
|
||||
// ___ ___ __ ___________ __
|
||||
// / | \ ____ ____ | | _\__ ___/____ _____| | __
|
||||
// / ~ \/ _ \ / _ \| |/ / | | \__ \ / ___/ |/ /
|
||||
// \ Y ( <_> | <_> ) < | | / __ \_\___ \| <
|
||||
// \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
type HookTaskType int
|
||||
|
||||
const (
|
||||
WEBHOOK = iota + 1
|
||||
SERVICE
|
||||
)
|
||||
|
||||
type PayloadAuthor struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type PayloadCommit struct {
|
||||
Id string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Url string `json:"url"`
|
||||
Author *PayloadAuthor `json:"author"`
|
||||
}
|
||||
|
||||
type PayloadRepo struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Description string `json:"description"`
|
||||
Website string `json:"website"`
|
||||
Watchers int `json:"watchers"`
|
||||
Owner *PayloadAuthor `json:"author"`
|
||||
Private bool `json:"private"`
|
||||
}
|
||||
|
||||
// Payload represents payload information of hook.
|
||||
type Payload struct {
|
||||
Secret string `json:"secret"`
|
||||
Ref string `json:"ref"`
|
||||
Commits []*PayloadCommit `json:"commits"`
|
||||
Repo *PayloadRepo `json:"repository"`
|
||||
Pusher *PayloadAuthor `json:"pusher"`
|
||||
}
|
||||
|
||||
// HookTask represents hook task.
|
||||
type HookTask struct {
|
||||
Id int64
|
||||
Type int
|
||||
Url string
|
||||
*Payload `xorm:"-"`
|
||||
PayloadContent string `xorm:"TEXT"`
|
||||
ContentType HookContentType
|
||||
IsSsl bool
|
||||
IsDeliveried bool
|
||||
}
|
||||
|
||||
// CreateHookTask creates a new hook task,
|
||||
// it handles conversion from Payload to PayloadContent.
|
||||
func CreateHookTask(t *HookTask) error {
|
||||
data, err := json.Marshal(t.Payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.PayloadContent = string(data)
|
||||
_, err = orm.Insert(t)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateHookTask updates information of hook task.
|
||||
func UpdateHookTask(t *HookTask) error {
|
||||
_, err := orm.AllCols().Update(t)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeliverHooks checks and delivers undelivered hooks.
|
||||
func DeliverHooks() {
|
||||
timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second
|
||||
orm.Where("is_deliveried=?", false).Iterate(new(HookTask),
|
||||
func(idx int, bean interface{}) error {
|
||||
t := bean.(*HookTask)
|
||||
// Only support JSON now.
|
||||
if _, err := httplib.Post(t.Url).SetTimeout(timeout, timeout).
|
||||
Body([]byte(t.PayloadContent)).Response(); err != nil {
|
||||
log.Error("webhook.DeliverHooks(Delivery): %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
t.IsDeliveried = true
|
||||
if err := UpdateHookTask(t); err != nil {
|
||||
log.Error("webhook.DeliverHooks(UpdateHookTask): %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Trace("Hook delivered: %s", t.PayloadContent)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue