mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-10-24 11:02:42 +00:00
[BRANDING] define the forgejo webhook type
templates/swagger/v1_json.tmpl updated with `make generate-swagger` (cherry picked from commit88899c492e) (cherry picked from commit7171bd9617) (cherry picked from commit1a742446c1) (cherry picked from commitd7c189d7b2) Conflicts: routers/web/web.go (cherry picked from commitcbdea868e4) (cherry picked from commit6cd150483b) (cherry picked from commit47246da8d3) (cherry picked from commitf2aa0e6b76) (cherry picked from commit5a4fc69a16) (cherry picked from commit48e444ca09) (cherry picked from commit888e537811) (cherry picked from commit5121f493c9) (cherry picked from commit9394e55fdf) (cherry picked from commit3a2ce51768) (cherry picked from commit719ead3a65) (cherry picked from commit83e6f82e2a) (cherry picked from commit494a429b21) (cherry picked from commit4d775db6b4) (cherry picked from commitb68f777dc2) (cherry picked from commit5b934023fa) (cherry picked from commit3b1ed8b16c) (cherry picked from commit6bc4a46c9f) (cherry picked from commit8064bb24a3) Conflicts: templates/admin/hook_new.tmpl templates/org/settings/hook_new.tmpl templates/repo/settings/webhook/base_list.tmpl templates/repo/settings/webhook/new.tmpl templates/user/settings/hook_new.tmpl https://codeberg.org/forgejo/forgejo/pulls/1181 (cherry picked from commit55f5588a91) (cherry picked from commita428bc06b3)
This commit is contained in:
parent
8f8c9fd9e3
commit
d2186eceb9
13 changed files with 115 additions and 5 deletions
|
|
@ -35,7 +35,7 @@ func loadWebhookFrom(rootCfg ConfigProvider) {
|
||||||
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
|
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
|
||||||
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
|
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
|
||||||
Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("")
|
Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("")
|
||||||
Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"}
|
Webhook.Types = []string{"forgejo", "gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"}
|
||||||
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
|
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
|
||||||
Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("")
|
Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("")
|
||||||
if Webhook.ProxyURL != "" {
|
if Webhook.ProxyURL != "" {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ type CreateHookOptionConfig map[string]string
|
||||||
// CreateHookOption options when create a hook
|
// CreateHookOption options when create a hook
|
||||||
type CreateHookOption struct {
|
type CreateHookOption struct {
|
||||||
// required: true
|
// required: true
|
||||||
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
|
// enum: forgejo,dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
|
||||||
Type string `json:"type" binding:"Required"`
|
Type string `json:"type" binding:"Required"`
|
||||||
// required: true
|
// required: true
|
||||||
Config CreateHookOptionConfig `json:"config" binding:"Required"`
|
Config CreateHookOptionConfig `json:"config" binding:"Required"`
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ type HookType = string
|
||||||
|
|
||||||
// Types of webhooks
|
// Types of webhooks
|
||||||
const (
|
const (
|
||||||
|
FORGEJO HookType = "forgejo"
|
||||||
GITEA HookType = "gitea"
|
GITEA HookType = "gitea"
|
||||||
GOGS HookType = "gogs"
|
GOGS HookType = "gogs"
|
||||||
SLACK HookType = "slack"
|
SLACK HookType = "slack"
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,34 @@ func editWebhook(ctx *context.Context, params webhookParams) {
|
||||||
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
|
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForgejoHooksNewPost response for creating Forgejo webhook
|
||||||
|
func ForgejoHooksNewPost(ctx *context.Context) {
|
||||||
|
createWebhook(ctx, forgejoHookParams(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForgejoHooksEditPost response for editing Forgejo webhook
|
||||||
|
func ForgejoHooksEditPost(ctx *context.Context) {
|
||||||
|
editWebhook(ctx, forgejoHookParams(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func forgejoHookParams(ctx *context.Context) webhookParams {
|
||||||
|
form := web.GetForm(ctx).(*forms.NewWebhookForm)
|
||||||
|
|
||||||
|
contentType := webhook.ContentTypeJSON
|
||||||
|
if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
|
||||||
|
contentType = webhook.ContentTypeForm
|
||||||
|
}
|
||||||
|
|
||||||
|
return webhookParams{
|
||||||
|
Type: webhook_module.FORGEJO,
|
||||||
|
URL: form.PayloadURL,
|
||||||
|
ContentType: contentType,
|
||||||
|
Secret: form.Secret,
|
||||||
|
HTTPMethod: form.HTTPMethod,
|
||||||
|
WebhookForm: form.WebhookForm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GiteaHooksNewPost response for creating Gitea webhook
|
// GiteaHooksNewPost response for creating Gitea webhook
|
||||||
func GiteaHooksNewPost(ctx *context.Context) {
|
func GiteaHooksNewPost(ctx *context.Context) {
|
||||||
createWebhook(ctx, giteaHookParams(ctx))
|
createWebhook(ctx, giteaHookParams(ctx))
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,7 @@ func registerRoutes(m *web.Route) {
|
||||||
|
|
||||||
addWebhookAddRoutes := func() {
|
addWebhookAddRoutes := func() {
|
||||||
m.Get("/{type}/new", repo_setting.WebhooksNew)
|
m.Get("/{type}/new", repo_setting.WebhooksNew)
|
||||||
|
m.Post("/forgejo/new", web.Bind(forms.NewWebhookForm{}), repo_setting.ForgejoHooksNewPost)
|
||||||
m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksNewPost)
|
m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksNewPost)
|
||||||
m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost)
|
m.Post("/gogs/new", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksNewPost)
|
||||||
m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksNewPost)
|
m.Post("/slack/new", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksNewPost)
|
||||||
|
|
@ -293,6 +294,7 @@ func registerRoutes(m *web.Route) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addWebhookEditRoutes := func() {
|
addWebhookEditRoutes := func() {
|
||||||
|
m.Post("/forgejo/{id}", web.Bind(forms.NewWebhookForm{}), repo_setting.ForgejoHooksEditPost)
|
||||||
m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksEditPost)
|
m.Post("/gitea/{id}", web.Bind(forms.NewWebhookForm{}), repo_setting.GiteaHooksEditPost)
|
||||||
m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost)
|
m.Post("/gogs/{id}", web.Bind(forms.NewGogshookForm{}), repo_setting.GogsHooksEditPost)
|
||||||
m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksEditPost)
|
m.Post("/slack/{id}", web.Bind(forms.NewSlackHookForm{}), repo_setting.SlackHooksEditPost)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ var webhooks = map[webhook_module.HookType]*webhook{
|
||||||
|
|
||||||
// IsValidHookTaskType returns true if a webhook registered
|
// IsValidHookTaskType returns true if a webhook registered
|
||||||
func IsValidHookTaskType(name string) bool {
|
func IsValidHookTaskType(name string) bool {
|
||||||
if name == webhook_module.GITEA || name == webhook_module.GOGS {
|
if name == webhook_module.FORGEJO || name == webhook_module.GITEA || name == webhook_module.GOGS {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
_, ok := webhooks[name]
|
_, ok := webhooks[name]
|
||||||
|
|
@ -177,7 +177,7 @@ func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook
|
||||||
// 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.Type != webhook_module.GITEA && w.Type != webhook_module.GOGS &&
|
w.Type != webhook_module.FORGEJO && w.Type != webhook_module.GITEA && w.Type != webhook_module.GOGS &&
|
||||||
len(pushEvent.Commits) == 0 {
|
len(pushEvent.Commits) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached segment">
|
<div class="ui attached segment">
|
||||||
|
{{template "repo/settings/webhook/forgejo" .}}
|
||||||
{{template "repo/settings/webhook/gitea" .}}
|
{{template "repo/settings/webhook/gitea" .}}
|
||||||
{{template "repo/settings/webhook/gogs" .}}
|
{{template "repo/settings/webhook/gogs" .}}
|
||||||
{{template "repo/settings/webhook/slack" .}}
|
{{template "repo/settings/webhook/slack" .}}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@
|
||||||
<div class="ui jump dropdown">
|
<div class="ui jump dropdown">
|
||||||
<div class="ui primary tiny button">{{.locale.Tr "repo.settings.add_webhook"}}</div>
|
<div class="ui primary tiny button">{{.locale.Tr "repo.settings.add_webhook"}}</div>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
|
<a class="item" href="{{.BaseLinkNew}}/forgejo/new">
|
||||||
|
{{template "shared/webhook/icon" (dict "HookType" "forgejo" "Size" 20)}}
|
||||||
|
{{.locale.Tr "repo.settings.web_hook_name_forgejo"}}
|
||||||
|
</a>
|
||||||
<a class="item" href="{{.BaseLinkNew}}/gitea/new">
|
<a class="item" href="{{.BaseLinkNew}}/gitea/new">
|
||||||
{{template "shared/webhook/icon" (dict "HookType" "gitea" "Size" 20)}}
|
{{template "shared/webhook/icon" (dict "HookType" "gitea" "Size" 20)}}
|
||||||
{{.locale.Tr "repo.settings.web_hook_name_gitea"}}
|
{{.locale.Tr "repo.settings.web_hook_name_gitea"}}
|
||||||
|
|
|
||||||
40
templates/repo/settings/webhook/forgejo.tmpl
Normal file
40
templates/repo/settings/webhook/forgejo.tmpl
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
{{if eq .HookType "forgejo"}}
|
||||||
|
<p>{{.locale.Tr "repo.settings.add_web_hook_desc" "https://docs.gitea.io/en-us/webhooks/" (.locale.Tr "repo.settings.web_hook_name_forgejo") | Str2html}}</p>
|
||||||
|
<form class="ui form" action="{{.BaseLink}}/forgejo/{{or .Webhook.ID "new"}}" method="post">
|
||||||
|
{{template "base/disable_form_autofill"}}
|
||||||
|
{{.CsrfTokenHtml}}
|
||||||
|
<div class="required field {{if .Err_PayloadURL}}error{{end}}">
|
||||||
|
<label for="payload_url">{{.locale.Tr "repo.settings.payload_url"}}</label>
|
||||||
|
<input id="payload_url" name="payload_url" type="url" value="{{.Webhook.URL}}" autofocus required>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>{{.locale.Tr "repo.settings.http_method"}}</label>
|
||||||
|
<div class="ui selection dropdown">
|
||||||
|
<input type="hidden" id="http_method" name="http_method" value="{{if .Webhook.HTTPMethod}}{{.Webhook.HTTPMethod}}{{else}}POST{{end}}">
|
||||||
|
<div class="default text"></div>
|
||||||
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
|
<div class="menu">
|
||||||
|
<div class="item" data-value="POST">POST</div>
|
||||||
|
<div class="item" data-value="GET">GET</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>{{.locale.Tr "repo.settings.content_type"}}</label>
|
||||||
|
<div class="ui selection dropdown">
|
||||||
|
<input type="hidden" id="content_type" name="content_type" value="{{if .Webhook.ContentType}}{{.Webhook.ContentType}}{{else}}1{{end}}">
|
||||||
|
<div class="default text"></div>
|
||||||
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
|
<div class="menu">
|
||||||
|
<div class="item" data-value="1">application/json</div>
|
||||||
|
<div class="item" data-value="2">application/x-www-form-urlencoded</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field {{if .Err_Secret}}error{{end}}">
|
||||||
|
<label for="secret">{{.locale.Tr "repo.settings.secret"}}</label>
|
||||||
|
<input id="secret" name="secret" type="password" value="{{.Webhook.Secret}}" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
{{template "repo/settings/webhook/settings" .}}
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached segment">
|
<div class="ui attached segment">
|
||||||
|
{{template "repo/settings/webhook/forgejo" .}}
|
||||||
{{template "repo/settings/webhook/gitea" .}}
|
{{template "repo/settings/webhook/gitea" .}}
|
||||||
{{template "repo/settings/webhook/gogs" .}}
|
{{template "repo/settings/webhook/gogs" .}}
|
||||||
{{template "repo/settings/webhook/slack" .}}
|
{{template "repo/settings/webhook/slack" .}}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
{{if .Size}}
|
{{if .Size}}
|
||||||
{{$size = .Size}}
|
{{$size = .Size}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if eq .HookType "gitea"}}
|
{{if eq .HookType "forgejo"}}
|
||||||
|
<img width="{{$size}}" height="{{$size}}" src="{{AssetUrlPrefix}}/img/forgejo.svg">
|
||||||
|
{{else if eq .HookType "gitea"}}
|
||||||
<img width="{{$size}}" height="{{$size}}" src="{{AssetUrlPrefix}}/img/gitea.svg">
|
<img width="{{$size}}" height="{{$size}}" src="{{AssetUrlPrefix}}/img/gitea.svg">
|
||||||
{{else if eq .HookType "gogs"}}
|
{{else if eq .HookType "gogs"}}
|
||||||
<img width="{{$size}}" height="{{$size}}" src="{{AssetUrlPrefix}}/img/gogs.ico">
|
<img width="{{$size}}" height="{{$size}}" src="{{AssetUrlPrefix}}/img/gogs.ico">
|
||||||
|
|
|
||||||
1
templates/swagger/v1_json.tmpl
generated
1
templates/swagger/v1_json.tmpl
generated
|
|
@ -16911,6 +16911,7 @@
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
"forgejo",
|
||||||
"dingtalk",
|
"dingtalk",
|
||||||
"discord",
|
"discord",
|
||||||
"gitea",
|
"gitea",
|
||||||
|
|
|
||||||
|
|
@ -174,3 +174,33 @@ func TestLinksLogin(t *testing.T) {
|
||||||
|
|
||||||
testLinksAsUser("user2", t)
|
testLinksAsUser("user2", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRedirectsWebhooks(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
//
|
||||||
|
// A redirect means the route exists but not if it performs as intended.
|
||||||
|
//
|
||||||
|
for _, kind := range []string{"forgejo", "gitea"} {
|
||||||
|
redirects := []struct {
|
||||||
|
from string
|
||||||
|
to string
|
||||||
|
verb string
|
||||||
|
}{
|
||||||
|
{from: "/user2/repo1/settings/hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
|
||||||
|
{from: "/user/settings/hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
|
||||||
|
{from: "/admin/system-hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
|
||||||
|
{from: "/admin/default-hooks/" + kind + "/new", to: "/user/login", verb: "GET"},
|
||||||
|
{from: "/user2/repo1/settings/hooks/" + kind + "/new", to: "/", verb: "POST"},
|
||||||
|
{from: "/admin/system-hooks/" + kind + "/new", to: "/", verb: "POST"},
|
||||||
|
{from: "/admin/default-hooks/" + kind + "/new", to: "/", verb: "POST"},
|
||||||
|
{from: "/user2/repo1/settings/hooks/" + kind + "/1", to: "/", verb: "POST"},
|
||||||
|
{from: "/admin/hooks/" + kind + "/1", to: "/", verb: "POST"},
|
||||||
|
}
|
||||||
|
for _, info := range redirects {
|
||||||
|
req := NewRequest(t, info.verb, info.from)
|
||||||
|
resp := MakeRequest(t, req, http.StatusSeeOther)
|
||||||
|
assert.EqualValues(t, path.Join(setting.AppSubURL, info.to), test.RedirectURL(resp), info.from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue