Skip to content

Commit 4100eed

Browse files
authored
Merge branch 'main' into non-hover-ci
2 parents b55aa67 + 3349fd8 commit 4100eed

File tree

20 files changed

+416
-3
lines changed

20 files changed

+416
-3
lines changed

docs/content/doc/features/webhooks.en-us.md

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ All event pushes are POST requests. The methods currently supported are:
2828
- Microsoft Teams
2929
- Feishu
3030
- Wechatwork
31+
- Packagist
3132

3233
### Event information
3334

docs/content/doc/features/webhooks.zh-cn.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ Gitea 的存储 webhook。这可以有存储库管路设定页 `/:username/:repo
2727
- Microsoft Teams
2828
- Feishu
2929
- Wechatwork
30+
- Packagist
3031

3132
## TBD

docs/content/doc/features/webhooks.zh-tw.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Gitea 的儲存庫事件支援 web hook。這可以有儲存庫管理員在設
2727
- Microsoft Teams
2828
- Feishu
2929
- Wechatwork
30+
- Packagist
3031

3132
### 事件資訊
3233

models/webhook/webhook.go

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ const (
161161
FEISHU HookType = "feishu"
162162
MATRIX HookType = "matrix"
163163
WECHATWORK HookType = "wechatwork"
164+
PACKAGIST HookType = "packagist"
164165
)
165166

166167
// HookStatus is the status of a web hook

modules/setting/webhook.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func newWebhookService() {
3636
Webhook.DeliverTimeout = sec.Key("DELIVER_TIMEOUT").MustInt(5)
3737
Webhook.SkipTLSVerify = sec.Key("SKIP_TLS_VERIFY").MustBool()
3838
Webhook.AllowedHostList = sec.Key("ALLOWED_HOST_LIST").MustString("")
39-
Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork"}
39+
Webhook.Types = []string{"gitea", "gogs", "slack", "discord", "dingtalk", "telegram", "msteams", "feishu", "matrix", "wechatwork", "packagist"}
4040
Webhook.PagingNum = sec.Key("PAGING_NUM").MustInt(10)
4141
Webhook.ProxyURL = sec.Key("PROXY_URL").MustString("")
4242
if Webhook.ProxyURL != "" {

modules/structs/hook.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type CreateHookOptionConfig map[string]string
4040
// CreateHookOption options when create a hook
4141
type CreateHookOption struct {
4242
// required: true
43-
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork
43+
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
4444
Type string `json:"type" binding:"Required"`
4545
// required: true
4646
Config CreateHookOptionConfig `json:"config" binding:"Required"`

options/locale/locale_en-US.ini

+4
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,10 @@ settings.add_matrix_hook_desc = Integrate <a href="%s">Matrix</a> into your repo
19471947
settings.add_msteams_hook_desc = Integrate <a href="%s">Microsoft Teams</a> into your repository.
19481948
settings.add_feishu_hook_desc = Integrate <a href="%s">Feishu</a> into your repository.
19491949
settings.add_Wechat_hook_desc = Integrate <a href="%s">Wechatwork</a> into your repository.
1950+
settings.add_packagist_hook_desc = Integrate <a href="%s">Packagist</a> into your repository.
1951+
settings.packagist_username = Packagist username
1952+
settings.packagist_api_token = API token
1953+
settings.packagist_package_url = Packagist package URL
19501954
settings.deploy_keys = Deploy Keys
19511955
settings.add_deploy_key = Add Deploy Key
19521956
settings.deploy_key_desc = Deploy keys have read-only pull access to the repository.

public/img/packagist.png

4.47 KB
Loading

routers/web/repo/webhook.go

+99
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,59 @@ func WechatworkHooksNewPost(ctx *context.Context) {
682682
ctx.Redirect(orCtx.Link)
683683
}
684684

685+
// PackagistHooksNewPost response for creating packagist hook
686+
func PackagistHooksNewPost(ctx *context.Context) {
687+
form := web.GetForm(ctx).(*forms.NewPackagistHookForm)
688+
ctx.Data["Title"] = ctx.Tr("repo.settings")
689+
ctx.Data["PageIsSettingsHooks"] = true
690+
ctx.Data["PageIsSettingsHooksNew"] = true
691+
ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
692+
ctx.Data["HookType"] = webhook.PACKAGIST
693+
694+
orCtx, err := getOrgRepoCtx(ctx)
695+
if err != nil {
696+
ctx.ServerError("getOrgRepoCtx", err)
697+
return
698+
}
699+
700+
if ctx.HasError() {
701+
ctx.HTML(http.StatusOK, orCtx.NewTemplate)
702+
return
703+
}
704+
705+
meta, err := json.Marshal(&webhook_service.PackagistMeta{
706+
Username: form.Username,
707+
APIToken: form.APIToken,
708+
PackageURL: form.PackageURL,
709+
})
710+
if err != nil {
711+
ctx.ServerError("Marshal", err)
712+
return
713+
}
714+
715+
w := &webhook.Webhook{
716+
RepoID: orCtx.RepoID,
717+
URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)),
718+
ContentType: webhook.ContentTypeJSON,
719+
HookEvent: ParseHookEvent(form.WebhookForm),
720+
IsActive: form.Active,
721+
Type: webhook.PACKAGIST,
722+
Meta: string(meta),
723+
OrgID: orCtx.OrgID,
724+
IsSystemWebhook: orCtx.IsSystemWebhook,
725+
}
726+
if err := w.UpdateEvent(); err != nil {
727+
ctx.ServerError("UpdateEvent", err)
728+
return
729+
} else if err := webhook.CreateWebhook(db.DefaultContext, w); err != nil {
730+
ctx.ServerError("CreateWebhook", err)
731+
return
732+
}
733+
734+
ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
735+
ctx.Redirect(orCtx.Link)
736+
}
737+
685738
func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) {
686739
ctx.Data["RequireHighlightJS"] = true
687740

@@ -719,6 +772,8 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) {
719772
ctx.Data["TelegramHook"] = webhook_service.GetTelegramHook(w)
720773
case webhook.MATRIX:
721774
ctx.Data["MatrixHook"] = webhook_service.GetMatrixHook(w)
775+
case webhook.PACKAGIST:
776+
ctx.Data["PackagistHook"] = webhook_service.GetPackagistHook(w)
722777
}
723778

724779
ctx.Data["History"], err = w.History(1)
@@ -1137,6 +1192,50 @@ func WechatworkHooksEditPost(ctx *context.Context) {
11371192
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
11381193
}
11391194

1195+
// PackagistHooksEditPost response for editing packagist hook
1196+
func PackagistHooksEditPost(ctx *context.Context) {
1197+
form := web.GetForm(ctx).(*forms.NewPackagistHookForm)
1198+
ctx.Data["Title"] = ctx.Tr("repo.settings")
1199+
ctx.Data["PageIsSettingsHooks"] = true
1200+
ctx.Data["PageIsSettingsHooksEdit"] = true
1201+
1202+
orCtx, w := checkWebhook(ctx)
1203+
if ctx.Written() {
1204+
return
1205+
}
1206+
ctx.Data["Webhook"] = w
1207+
1208+
if ctx.HasError() {
1209+
ctx.HTML(http.StatusOK, orCtx.NewTemplate)
1210+
return
1211+
}
1212+
1213+
meta, err := json.Marshal(&webhook_service.PackagistMeta{
1214+
Username: form.Username,
1215+
APIToken: form.APIToken,
1216+
PackageURL: form.PackageURL,
1217+
})
1218+
if err != nil {
1219+
ctx.ServerError("Marshal", err)
1220+
return
1221+
}
1222+
1223+
w.Meta = string(meta)
1224+
w.URL = fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken))
1225+
w.HookEvent = ParseHookEvent(form.WebhookForm)
1226+
w.IsActive = form.Active
1227+
if err := w.UpdateEvent(); err != nil {
1228+
ctx.ServerError("UpdateEvent", err)
1229+
return
1230+
} else if err := webhook.UpdateWebhook(w); err != nil {
1231+
ctx.ServerError("UpdateWebhook", err)
1232+
return
1233+
}
1234+
1235+
ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success"))
1236+
ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
1237+
}
1238+
11401239
// TestWebhook test if web hook is work fine
11411240
func TestWebhook(ctx *context.Context) {
11421241
hookID := ctx.ParamsInt64(":id")

routers/web/web.go

+4
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ func RegisterRoutes(m *web.Route) {
448448
m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
449449
m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
450450
m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost)
451+
m.Post("/packagist/{id}", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost)
451452
}, webhooksEnabled)
452453

453454
m.Group("/{configType:default-hooks|system-hooks}", func() {
@@ -462,6 +463,7 @@ func RegisterRoutes(m *web.Route) {
462463
m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
463464
m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost)
464465
m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost)
466+
m.Post("/packagist/new", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost)
465467
})
466468

467469
m.Group("/auths", func() {
@@ -657,6 +659,7 @@ func RegisterRoutes(m *web.Route) {
657659
m.Post("/msteams/new", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksNewPost)
658660
m.Post("/feishu/new", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksNewPost)
659661
m.Post("/wechatwork/new", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksNewPost)
662+
m.Post("/packagist/new", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksNewPost)
660663
m.Group("/{id}", func() {
661664
m.Get("", repo.WebHooksEdit)
662665
m.Post("/test", repo.TestWebhook)
@@ -672,6 +675,7 @@ func RegisterRoutes(m *web.Route) {
672675
m.Post("/msteams/{id}", bindIgnErr(forms.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
673676
m.Post("/feishu/{id}", bindIgnErr(forms.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
674677
m.Post("/wechatwork/{id}", bindIgnErr(forms.NewWechatWorkHookForm{}), repo.WechatworkHooksEditPost)
678+
m.Post("/packagist/{id}", bindIgnErr(forms.NewPackagistHookForm{}), repo.PackagistHooksEditPost)
675679
}, webhooksEnabled)
676680

677681
m.Group("/keys", func() {

services/forms/repo_form.go

+14
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,20 @@ func (f *NewWechatWorkHookForm) Validate(req *http.Request, errs binding.Errors)
396396
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
397397
}
398398

399+
// NewPackagistHookForm form for creating packagist hook
400+
type NewPackagistHookForm struct {
401+
Username string `binding:"Required"`
402+
APIToken string `binding:"Required"`
403+
PackageURL string `binding:"Required;ValidUrl"`
404+
WebhookForm
405+
}
406+
407+
// Validate validates the fields
408+
func (f *NewPackagistHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
409+
ctx := context.GetContext(req)
410+
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
411+
}
412+
399413
// .___
400414
// | | ______ ________ __ ____
401415
// | |/ ___// ___/ | \_/ __ \

services/webhook/packagist.go

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package webhook
6+
7+
import (
8+
"errors"
9+
10+
webhook_model "code.gitea.io/gitea/models/webhook"
11+
"code.gitea.io/gitea/modules/json"
12+
"code.gitea.io/gitea/modules/log"
13+
api "code.gitea.io/gitea/modules/structs"
14+
)
15+
16+
type (
17+
// PackagistPayload represents
18+
PackagistPayload struct {
19+
PackagistRepository struct {
20+
URL string `json:"url"`
21+
} `json:"repository"`
22+
}
23+
24+
// PackagistMeta contains the meta data for the webhook
25+
PackagistMeta struct {
26+
Username string `json:"username"`
27+
APIToken string `json:"api_token"`
28+
PackageURL string `json:"package_url"`
29+
}
30+
)
31+
32+
// GetPackagistHook returns packagist metadata
33+
func GetPackagistHook(w *webhook_model.Webhook) *PackagistMeta {
34+
s := &PackagistMeta{}
35+
if err := json.Unmarshal([]byte(w.Meta), s); err != nil {
36+
log.Error("webhook.GetPackagistHook(%d): %v", w.ID, err)
37+
}
38+
return s
39+
}
40+
41+
// JSONPayload Marshals the PackagistPayload to json
42+
func (f *PackagistPayload) JSONPayload() ([]byte, error) {
43+
data, err := json.MarshalIndent(f, "", " ")
44+
if err != nil {
45+
return []byte{}, err
46+
}
47+
return data, nil
48+
}
49+
50+
var _ PayloadConvertor = &PackagistPayload{}
51+
52+
// Create implements PayloadConvertor Create method
53+
func (f *PackagistPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
54+
return nil, nil
55+
}
56+
57+
// Delete implements PayloadConvertor Delete method
58+
func (f *PackagistPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
59+
return nil, nil
60+
}
61+
62+
// Fork implements PayloadConvertor Fork method
63+
func (f *PackagistPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
64+
return nil, nil
65+
}
66+
67+
// Push implements PayloadConvertor Push method
68+
func (f *PackagistPayload) Push(p *api.PushPayload) (api.Payloader, error) {
69+
return f, nil
70+
}
71+
72+
// Issue implements PayloadConvertor Issue method
73+
func (f *PackagistPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
74+
return nil, nil
75+
}
76+
77+
// IssueComment implements PayloadConvertor IssueComment method
78+
func (f *PackagistPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
79+
return nil, nil
80+
}
81+
82+
// PullRequest implements PayloadConvertor PullRequest method
83+
func (f *PackagistPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
84+
return nil, nil
85+
}
86+
87+
// Review implements PayloadConvertor Review method
88+
func (f *PackagistPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) {
89+
return nil, nil
90+
}
91+
92+
// Repository implements PayloadConvertor Repository method
93+
func (f *PackagistPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
94+
return nil, nil
95+
}
96+
97+
// Release implements PayloadConvertor Release method
98+
func (f *PackagistPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
99+
return nil, nil
100+
}
101+
102+
// GetPackagistPayload converts a packagist webhook into a PackagistPayload
103+
func GetPackagistPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) {
104+
s := new(PackagistPayload)
105+
106+
packagist := &PackagistMeta{}
107+
if err := json.Unmarshal([]byte(meta), &packagist); err != nil {
108+
return s, errors.New("GetPackagistPayload meta json:" + err.Error())
109+
}
110+
s.PackagistRepository.URL = packagist.PackageURL
111+
return convertPayloader(s, p, event)
112+
}

0 commit comments

Comments
 (0)