webhook APIs
This commit is contained in:
parent
2f08e9f048
commit
55ddf225bb
|
@ -13,7 +13,7 @@ github.com/go-sql-driver/mysql = commit:a197e5d405
|
||||||
github.com/go-xorm/core = commit:4813c0110d
|
github.com/go-xorm/core = commit:4813c0110d
|
||||||
github.com/go-xorm/xorm = commit:97e7703766
|
github.com/go-xorm/xorm = commit:97e7703766
|
||||||
github.com/gogits/chardet = commit:2404f77725
|
github.com/gogits/chardet = commit:2404f77725
|
||||||
github.com/gogits/go-gogs-client = commit:92e76d616a
|
github.com/gogits/go-gogs-client =
|
||||||
github.com/lib/pq = commit:0dad96c0b9
|
github.com/lib/pq = commit:0dad96c0b9
|
||||||
github.com/macaron-contrib/binding = commit:de6ed78668
|
github.com/macaron-contrib/binding = commit:de6ed78668
|
||||||
github.com/macaron-contrib/cache = commit:cd824f6f2d
|
github.com/macaron-contrib/cache = commit:cd824f6f2d
|
||||||
|
|
|
@ -529,7 +529,10 @@ settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the UR
|
||||||
settings.payload_url = Payload URL
|
settings.payload_url = Payload URL
|
||||||
settings.content_type = Content Type
|
settings.content_type = Content Type
|
||||||
settings.secret = Secret
|
settings.secret = Secret
|
||||||
settings.event_desc = Upon which events should this webhook be triggered?
|
settings.slack_username = Username
|
||||||
|
settings.slack_icon_url = Icon URL
|
||||||
|
settings.slack_color = Color
|
||||||
|
settings.event_desc = When should this webhook be triggered?
|
||||||
settings.event_push_only = Just the <code>push</code> event.
|
settings.event_push_only = Just the <code>push</code> event.
|
||||||
settings.event_send_everything = I need <strong>everything</strong>.
|
settings.event_send_everything = I need <strong>everything</strong>.
|
||||||
settings.event_choose = Let me choose what I need.
|
settings.event_choose = Let me choose what I need.
|
||||||
|
|
|
@ -325,7 +325,9 @@ repo_lang=仓库语言
|
||||||
repo_lang_helper=请选择 .gitignore 文件
|
repo_lang_helper=请选择 .gitignore 文件
|
||||||
license=授权许可
|
license=授权许可
|
||||||
license_helper=请选择授权许可文件
|
license_helper=请选择授权许可文件
|
||||||
init_readme=使用 README.md 文件初始化仓库
|
readme=自述文档
|
||||||
|
readme_helper=请选择自述文档模板
|
||||||
|
auto_init=使用选定的文件和模板初始化仓库
|
||||||
create_repo=创建仓库
|
create_repo=创建仓库
|
||||||
default_branch=默认分支
|
default_branch=默认分支
|
||||||
mirror_interval=镜像同步周期(小时)
|
mirror_interval=镜像同步周期(小时)
|
||||||
|
@ -527,8 +529,17 @@ settings.add_webhook_desc=我们会通过 <code>POST</code> 请求将订阅事
|
||||||
settings.payload_url=推送地址
|
settings.payload_url=推送地址
|
||||||
settings.content_type=数据格式
|
settings.content_type=数据格式
|
||||||
settings.secret=密钥文本
|
settings.secret=密钥文本
|
||||||
|
settings.slack_username=服务名称
|
||||||
|
settings.slack_icon_url=图标 URL
|
||||||
|
settings.slack_color=颜色代码
|
||||||
settings.event_desc=请设置您希望触发 Web 钩子的事件:
|
settings.event_desc=请设置您希望触发 Web 钩子的事件:
|
||||||
settings.event_push_only=只推送 <code>push</code> 事件。
|
settings.event_push_only=只推送 <code>push</code> 事件。
|
||||||
|
settings.event_send_everything=请把 <strong>一切</strong> 都给我
|
||||||
|
settings.event_choose=我的命运自己主宰
|
||||||
|
settings.event_create=创建
|
||||||
|
settings.event_create_desc=创建分支或标签
|
||||||
|
settings.event_push=推送
|
||||||
|
settings.event_push_desc=Git 仓库推送
|
||||||
settings.active=是否激活
|
settings.active=是否激活
|
||||||
settings.active_helper=当指定事件发生时我们将会触发此 Web 钩子。
|
settings.active_helper=当指定事件发生时我们将会触发此 Web 钩子。
|
||||||
settings.add_hook_success=Web 钩子添加成功!
|
settings.add_hook_success=Web 钩子添加成功!
|
||||||
|
|
|
@ -97,11 +97,16 @@ type Webhook struct {
|
||||||
Updated time.Time `xorm:"UPDATED"`
|
Updated time.Time `xorm:"UPDATED"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEvent handles conversion from Events to HookEvent.
|
func (w *Webhook) AfterSet(colName string, _ xorm.Cell) {
|
||||||
func (w *Webhook) GetEvent() {
|
var err error
|
||||||
w.HookEvent = &HookEvent{}
|
switch colName {
|
||||||
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
|
case "events":
|
||||||
log.Error(4, "webhook.GetEvent(%d): %v", w.ID, err)
|
w.HookEvent = &HookEvent{}
|
||||||
|
if err = json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
|
||||||
|
log.Error(3, "Unmarshal[%d]: %v", w.ID, err)
|
||||||
|
}
|
||||||
|
case "created":
|
||||||
|
w.Created = regulateTimeZone(w.Created)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +142,17 @@ func (w *Webhook) HasPushEvent() bool {
|
||||||
(w.ChooseEvents && w.HookEvents.Push)
|
(w.ChooseEvents && w.HookEvents.Push)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Webhook) EventsArray() []string {
|
||||||
|
events := make([]string, 0, 2)
|
||||||
|
if w.HasCreateEvent() {
|
||||||
|
events = append(events, "create")
|
||||||
|
}
|
||||||
|
if w.HasPushEvent() {
|
||||||
|
events = append(events, "push")
|
||||||
|
}
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
// CreateWebhook creates a new web hook.
|
// CreateWebhook creates a new web hook.
|
||||||
func CreateWebhook(w *Webhook) error {
|
func CreateWebhook(w *Webhook) error {
|
||||||
_, err := x.Insert(w)
|
_, err := x.Insert(w)
|
||||||
|
@ -382,8 +398,6 @@ func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, w := range ws {
|
for _, w := range ws {
|
||||||
w.GetEvent()
|
|
||||||
|
|
||||||
switch event {
|
switch event {
|
||||||
case HOOK_EVENT_CREATE:
|
case HOOK_EVENT_CREATE:
|
||||||
if !w.HasCreateEvent() {
|
if !w.HasCreateEvent() {
|
||||||
|
|
|
@ -13,22 +13,20 @@ import (
|
||||||
api "github.com/gogits/go-gogs-client"
|
api "github.com/gogits/go-gogs-client"
|
||||||
|
|
||||||
"github.com/gogits/gogs/modules/git"
|
"github.com/gogits/gogs/modules/git"
|
||||||
"github.com/gogits/gogs/modules/setting"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
SLACK_COLOR string = "#dd4b39"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SlackMeta struct {
|
type SlackMeta struct {
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
IconURL string `json:"icon_url"`
|
||||||
|
Color string `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SlackPayload struct {
|
type SlackPayload struct {
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
IconUrl string `json:"icon_url"`
|
IconURL string `json:"icon_url"`
|
||||||
UnfurlLinks int `json:"unfurl_links"`
|
UnfurlLinks int `json:"unfurl_links"`
|
||||||
LinkNames int `json:"link_names"`
|
LinkNames int `json:"link_names"`
|
||||||
Attachments []SlackAttachment `json:"attachments"`
|
Attachments []SlackAttachment `json:"attachments"`
|
||||||
|
@ -75,8 +73,8 @@ func getSlackCreatePayload(p *api.CreatePayload, slack *SlackMeta) (*SlackPayloa
|
||||||
return &SlackPayload{
|
return &SlackPayload{
|
||||||
Channel: slack.Channel,
|
Channel: slack.Channel,
|
||||||
Text: text,
|
Text: text,
|
||||||
Username: setting.AppName,
|
Username: slack.Username,
|
||||||
IconUrl: setting.AppUrl + "/img/favicon.png",
|
IconURL: slack.IconURL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,13 +111,13 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slackAttachments := []SlackAttachment{{Color: SLACK_COLOR, Text: attachmentText}}
|
slackAttachments := []SlackAttachment{{Color: slack.Color, Text: attachmentText}}
|
||||||
|
|
||||||
return &SlackPayload{
|
return &SlackPayload{
|
||||||
Channel: slack.Channel,
|
Channel: slack.Channel,
|
||||||
Text: text,
|
Text: text,
|
||||||
Username: setting.AppName,
|
Username: slack.Username,
|
||||||
IconUrl: setting.AppUrl + "/img/favicon.png",
|
IconURL: slack.IconURL,
|
||||||
Attachments: slackAttachments,
|
Attachments: slackAttachments,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,9 @@ func (f *NewWebhookForm) Validate(ctx *macaron.Context, errs binding.Errors) bin
|
||||||
type NewSlackHookForm struct {
|
type NewSlackHookForm struct {
|
||||||
PayloadURL string `binding:"Required`
|
PayloadURL string `binding:"Required`
|
||||||
Channel string `binding:"Required"`
|
Channel string `binding:"Required"`
|
||||||
|
Username string
|
||||||
|
IconURL string
|
||||||
|
Color string
|
||||||
WebhookForm
|
WebhookForm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
package base
|
package base
|
||||||
|
|
||||||
const DOC_URL = "http://gogs.io/docs"
|
const DOC_URL = "https://github.com/gogits/go-gogs-client/wiki"
|
||||||
|
|
||||||
type (
|
type (
|
||||||
TplName string
|
TplName string
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,9 @@ package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Unknwon/com"
|
||||||
|
|
||||||
api "github.com/gogits/go-gogs-client"
|
api "github.com/gogits/go-gogs-client"
|
||||||
|
|
||||||
|
@ -14,8 +17,33 @@ import (
|
||||||
"github.com/gogits/gogs/modules/middleware"
|
"github.com/gogits/gogs/modules/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GET /repos/:username/:reponame/hooks
|
// ToApiHook converts webhook to API format.
|
||||||
// https://developer.github.com/v3/repos/hooks/#list-hooks
|
func ToApiHook(repoLink string, w *models.Webhook) *api.Hook {
|
||||||
|
config := map[string]string{
|
||||||
|
"url": w.URL,
|
||||||
|
"content_type": w.ContentType.Name(),
|
||||||
|
}
|
||||||
|
if w.HookTaskType == models.SLACK {
|
||||||
|
s := w.GetSlackHook()
|
||||||
|
config["channel"] = s.Channel
|
||||||
|
config["username"] = s.Username
|
||||||
|
config["icon_url"] = s.IconURL
|
||||||
|
config["color"] = s.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.Hook{
|
||||||
|
ID: w.ID,
|
||||||
|
Type: w.HookTaskType.Name(),
|
||||||
|
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
|
||||||
|
Active: w.IsActive,
|
||||||
|
Config: config,
|
||||||
|
Events: w.EventsArray(),
|
||||||
|
Updated: w.Updated,
|
||||||
|
Created: w.Created,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Repositories#list-hooks
|
||||||
func ListRepoHooks(ctx *middleware.Context) {
|
func ListRepoHooks(ctx *middleware.Context) {
|
||||||
hooks, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
|
hooks, err := models.GetWebhooksByRepoId(ctx.Repo.Repository.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -25,31 +53,13 @@ func ListRepoHooks(ctx *middleware.Context) {
|
||||||
|
|
||||||
apiHooks := make([]*api.Hook, len(hooks))
|
apiHooks := make([]*api.Hook, len(hooks))
|
||||||
for i := range hooks {
|
for i := range hooks {
|
||||||
h := &api.Hook{
|
apiHooks[i] = ToApiHook(ctx.Repo.RepoLink, hooks[i])
|
||||||
ID: hooks[i].ID,
|
|
||||||
Type: hooks[i].HookTaskType.Name(),
|
|
||||||
Active: hooks[i].IsActive,
|
|
||||||
Config: make(map[string]string),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Currently, onle have push event.
|
|
||||||
h.Events = []string{"push"}
|
|
||||||
|
|
||||||
h.Config["url"] = hooks[i].URL
|
|
||||||
h.Config["content_type"] = hooks[i].ContentType.Name()
|
|
||||||
if hooks[i].HookTaskType == models.SLACK {
|
|
||||||
s := hooks[i].GetSlackHook()
|
|
||||||
h.Config["channel"] = s.Channel
|
|
||||||
}
|
|
||||||
|
|
||||||
apiHooks[i] = h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, &apiHooks)
|
ctx.JSON(200, &apiHooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST /repos/:username/:reponame/hooks
|
// https://github.com/gogits/go-gogs-client/wiki/Repositories#create-a-hook
|
||||||
// https://developer.github.com/v3/repos/hooks/#create-a-hook
|
|
||||||
func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
||||||
if !models.IsValidHookTaskType(form.Type) {
|
if !models.IsValidHookTaskType(form.Type) {
|
||||||
ctx.JSON(422, &base.ApiJsonErr{"invalid hook type", base.DOC_URL})
|
ctx.JSON(422, &base.ApiJsonErr{"invalid hook type", base.DOC_URL})
|
||||||
|
@ -72,7 +82,11 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
||||||
ContentType: models.ToHookContentType(form.Config["content_type"]),
|
ContentType: models.ToHookContentType(form.Config["content_type"]),
|
||||||
Secret: form.Config["secret"],
|
Secret: form.Config["secret"],
|
||||||
HookEvent: &models.HookEvent{
|
HookEvent: &models.HookEvent{
|
||||||
PushOnly: true, // Only support it now.
|
ChooseEvents: true,
|
||||||
|
HookEvents: models.HookEvents{
|
||||||
|
Create: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_CREATE)),
|
||||||
|
Push: com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PUSH)),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
IsActive: form.Active,
|
IsActive: form.Active,
|
||||||
HookTaskType: models.ToHookTaskType(form.Type),
|
HookTaskType: models.ToHookTaskType(form.Type),
|
||||||
|
@ -84,7 +98,10 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
meta, err := json.Marshal(&models.SlackMeta{
|
meta, err := json.Marshal(&models.SlackMeta{
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
|
Username: form.Config["username"],
|
||||||
|
IconURL: form.Config["icon_url"],
|
||||||
|
Color: form.Config["color"],
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(500, &base.ApiJsonErr{"slack: JSON marshal failed: " + err.Error(), base.DOC_URL})
|
ctx.JSON(500, &base.ApiJsonErr{"slack: JSON marshal failed: " + err.Error(), base.DOC_URL})
|
||||||
|
@ -101,25 +118,10 @@ func CreateRepoHook(ctx *middleware.Context, form api.CreateHookOption) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiHook := &api.Hook{
|
ctx.JSON(201, ToApiHook(ctx.Repo.RepoLink, w))
|
||||||
ID: w.ID,
|
|
||||||
Type: w.HookTaskType.Name(),
|
|
||||||
Events: []string{"push"},
|
|
||||||
Active: w.IsActive,
|
|
||||||
Config: map[string]string{
|
|
||||||
"url": w.URL,
|
|
||||||
"content_type": w.ContentType.Name(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if w.HookTaskType == models.SLACK {
|
|
||||||
s := w.GetSlackHook()
|
|
||||||
apiHook.Config["channel"] = s.Channel
|
|
||||||
}
|
|
||||||
ctx.JSON(201, apiHook)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PATCH /repos/:username/:reponame/hooks/:id
|
// https://github.com/gogits/go-gogs-client/wiki/Repositories#edit-a-hook
|
||||||
// https://developer.github.com/v3/repos/hooks/#edit-a-hook
|
|
||||||
func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
|
func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
|
||||||
w, err := models.GetWebhookByID(ctx.ParamsInt64(":id"))
|
w, err := models.GetWebhookByID(ctx.ParamsInt64(":id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -142,7 +144,10 @@ func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
|
||||||
if w.HookTaskType == models.SLACK {
|
if w.HookTaskType == models.SLACK {
|
||||||
if channel, ok := form.Config["channel"]; ok {
|
if channel, ok := form.Config["channel"]; ok {
|
||||||
meta, err := json.Marshal(&models.SlackMeta{
|
meta, err := json.Marshal(&models.SlackMeta{
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
|
Username: form.Config["username"],
|
||||||
|
IconURL: form.Config["icon_url"],
|
||||||
|
Color: form.Config["color"],
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(500, &base.ApiJsonErr{"slack: JSON marshal failed: " + err.Error(), base.DOC_URL})
|
ctx.JSON(500, &base.ApiJsonErr{"slack: JSON marshal failed: " + err.Error(), base.DOC_URL})
|
||||||
|
@ -153,17 +158,25 @@ func EditRepoHook(ctx *middleware.Context, form api.EditHookOption) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update events
|
||||||
|
w.PushOnly = false
|
||||||
|
w.SendEverything = false
|
||||||
|
w.ChooseEvents = true
|
||||||
|
w.Create = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_CREATE))
|
||||||
|
w.Push = com.IsSliceContainsStr(form.Events, string(models.HOOK_EVENT_PUSH))
|
||||||
|
if err = w.UpdateEvent(); err != nil {
|
||||||
|
ctx.JSON(500, &base.ApiJsonErr{"UpdateEvent: " + err.Error(), base.DOC_URL})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if form.Active != nil {
|
if form.Active != nil {
|
||||||
w.IsActive = *form.Active
|
w.IsActive = *form.Active
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: edit events
|
|
||||||
if err := models.UpdateWebhook(w); err != nil {
|
if err := models.UpdateWebhook(w); err != nil {
|
||||||
ctx.JSON(500, &base.ApiJsonErr{"UpdateWebhook: " + err.Error(), base.DOC_URL})
|
ctx.JSON(500, &base.ApiJsonErr{"UpdateWebhook: " + err.Error(), base.DOC_URL})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, map[string]interface{}{
|
ctx.JSON(200, ToApiHook(ctx.Repo.RepoLink, w))
|
||||||
"ok": true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,7 +396,10 @@ func SlackHooksNewPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := json.Marshal(&models.SlackMeta{
|
meta, err := json.Marshal(&models.SlackMeta{
|
||||||
Channel: form.Channel,
|
Channel: form.Channel,
|
||||||
|
Username: form.Username,
|
||||||
|
IconURL: form.IconURL,
|
||||||
|
Color: form.Color,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "Marshal", err)
|
ctx.Handle(500, "Marshal", err)
|
||||||
|
@ -452,7 +455,6 @@ func checkWebhook(ctx *middleware.Context) (*OrgRepoCtx, *models.Webhook) {
|
||||||
default:
|
default:
|
||||||
ctx.Data["HookType"] = "gogs"
|
ctx.Data["HookType"] = "gogs"
|
||||||
}
|
}
|
||||||
w.GetEvent()
|
|
||||||
|
|
||||||
ctx.Data["History"], err = w.History(1)
|
ctx.Data["History"], err = w.History(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -530,7 +532,10 @@ func SlackHooksEditPost(ctx *middleware.Context, form auth.NewSlackHookForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := json.Marshal(&models.SlackMeta{
|
meta, err := json.Marshal(&models.SlackMeta{
|
||||||
Channel: form.Channel,
|
Channel: form.Channel,
|
||||||
|
Username: form.Username,
|
||||||
|
IconURL: form.IconURL,
|
||||||
|
Color: form.Color,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "Marshal", err)
|
ctx.Handle(500, "Marshal", err)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
|
<div class="inline required field {{if .Err_RepoName}}error{{end}}">
|
||||||
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
<label for="repo_name">{{.i18n.Tr "repo.repo_name"}}</label>
|
||||||
<input id="repo_name" name="repo_name" value="{{.repo_name}}" autofocus required>
|
<input id="repo_name" name="repo_name" value="{{.repo_name}}" autofocus required>
|
||||||
<span class="help">{{.i18n.Tr "repo.repo_name_helper"}}</span>
|
<span class="help">{{.i18n.Tr "repo.repo_name_helper" | Safe}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
|
|
|
@ -8,7 +8,20 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="required field {{if .Err_Channel}}error{{end}}">
|
<div class="required field {{if .Err_Channel}}error{{end}}">
|
||||||
<label for="channel">{{.i18n.Tr "repo.settings.slack_channel"}}</label>
|
<label for="channel">{{.i18n.Tr "repo.settings.slack_channel"}}</label>
|
||||||
<input id="channel" name="channel" value="{{.SlackHook.Channel}}" placeholder="#general" required>
|
<input id="channel" name="channel" value="{{.SlackHook.Channel}}" placeholder="e.g. #general" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label for="username">{{.i18n.Tr "repo.settings.slack_username"}}</label>
|
||||||
|
<input id="username" name="username" value="{{.SlackHook.Username}}" placeholder="e.g. Gogs">
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="icon_url">{{.i18n.Tr "repo.settings.slack_icon_url"}}</label>
|
||||||
|
<input id="icon_url" name="icon_url" value="{{.SlackHook.IconURL}}" placeholder="e.g. https://example.com/img/favicon.png">
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="color">{{.i18n.Tr "repo.settings.slack_color"}}</label>
|
||||||
|
<input id="color" name="color" value="{{.SlackHook.Color}}" placeholder="e.g. #dd4b39, good, warning, danger">
|
||||||
</div>
|
</div>
|
||||||
{{template "repo/settings/hook_settings" .}}
|
{{template "repo/settings/hook_settings" .}}
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in New Issue