Compare commits

...

7 Commits

Author SHA1 Message Date
James Liu
e61ce934bc
Update Gmail mailer configuration (#22291)
This PR updates the `[mailer]` configuration snippet for Gmail:

- The `HELO_HOSTNAME` isn't required.
- The `USER` must not include the @gmail domain.
- `HOST` needs to be supplied, and the SMTP port number needs to be
appended to the URL.

I also added a note about the requirement to use App passwords instead
of your Google account password directly.

Co-authored-by: delvh <dev.lh@web.de>
2023-01-02 10:52:36 +08:00
Yarden Shoham
b994b2ea9c
Fix due date rendering the wrong date in issue (#22302)
Previously, the last minute of the chosen date caused bad timezone
rendering.

For example, I chose January 4th, 2023.

### Before
```html
<time data-format="date" datetime="Wed, 04 Jan 2023 23:59:59 +0000">January 5, 2023</time>
```

### After
```html
<time data-format="date" datetime="2023-01-04">January 4, 2023</time>
```

---

Closes #21999

Signed-off-by: Yarden Shoham <hrsi88@gmail.com>
2023-01-02 10:49:05 +08:00
Lunny Xiao
a1c30740bb
Fix get system setting bug when enabled redis cache (#22295)
Fix #22281

In #21621 , `Get[V]` and `Set[V]` has been introduced, so that cache
value will be `*Setting`. For memory cache it's OK. But for redis cache,
it can only store `string` for the current implementation. This PR
revert some of changes of that and just store or return a `string` for
system setting.
2023-01-02 00:06:52 +08:00
delvh
0f4e1b9ac6
Restructure webhook module (#22256)
Previously, there was an `import services/webhooks` inside
`modules/notification/webhook`.
This import was removed (after fighting against many import cycles).
Additionally, `modules/notification/webhook` was moved to
`modules/webhook`,
and a few structs/constants were extracted from `models/webhooks` to
`modules/webhook`.

Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-01-01 23:23:15 +08:00
Jason Song
f8e93ce423
Reminder for no more logs to console (#22282)
Even if the log mode is `file`, there are still few logs printed to the
console at the very beginning.

That's fine but confusing. Someone will think the console is the only
place to find logs, and get nothing helpful. See
https://github.com/go-gitea/gitea/issues/22274#issuecomment-1367917717.

There should be a reminder that there are no more logs to the console.

And to avoid log loss, we should add configured loggers first, then
remove console logger if there's no `console` in the mode.

Tests with `MODE = file`:

Before:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/210079862-d591677f-347e-46ed-a548-bb2ddbb0885c.png">

After:
<img width="1792" alt="image"
src="https://user-images.githubusercontent.com/9418365/210080002-d66cc418-6888-4909-b370-d03f5986ef41.png">

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
2023-01-01 22:00:33 +08:00
Lunny Xiao
9c8fc7f677
Fix bug of DisableGravatar default value (#22296)
#18058 made a mistake. The disableGravatar's default value depends on
`OfflineMode`. If it's `true`, then `disableGravatar` is true, otherwise
it's `false`. But not opposite.

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
2023-01-01 20:19:23 +08:00
Lunny Xiao
2bbf9e7302
Upgrade go-chi to v5.0.8 (#22304) 2023-01-01 11:23:26 +01:00
49 changed files with 485 additions and 441 deletions

View File

@ -76,12 +76,15 @@ The following configuration should work with GMail's SMTP server:
```ini ```ini
[mailer] [mailer]
ENABLED = true ENABLED = true
HOST = smtp.gmail.com:465 ; Remove this line for Gitea >= 1.18.0
SMTP_ADDR = smtp.gmail.com SMTP_ADDR = smtp.gmail.com
SMTP_PORT = 465 SMTP_PORT = 465
FROM = example@gmail.com FROM = example.user@gmail.com
USER = example@gmail.com USER = example.user
PASSWD = *** PASSWD = ***
MAILER_TYPE = smtp MAILER_TYPE = smtp
IS_TLS_ENABLED = true IS_TLS_ENABLED = true
HELO_HOSTNAME = example.com
``` ```
Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google
account. You won't be able to use your Google account password directly.

2
go.mod
View File

@ -33,7 +33,7 @@ require (
github.com/gliderlabs/ssh v0.3.5 github.com/gliderlabs/ssh v0.3.5
github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0 github.com/go-ap/activitypub v0.0.0-20220917143152-e4e7018838c0
github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778 github.com/go-ap/jsonld v0.0.0-20220917142617-76bf51585778
github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/chi/v5 v5.0.8
github.com/go-chi/cors v1.2.1 github.com/go-chi/cors v1.2.1
github.com/go-enry/go-enry/v2 v2.8.3 github.com/go-enry/go-enry/v2 v2.8.3
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e

4
go.sum
View File

@ -475,8 +475,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw= github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=

View File

@ -153,8 +153,7 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
return DefaultAvatarLink() return DefaultAvatarLink()
} }
enableFederatedAvatarSetting, _ := system_model.GetSetting(system_model.KeyPictureEnableFederatedAvatar) enableFederatedAvatar := system_model.GetSettingBool(system_model.KeyPictureEnableFederatedAvatar)
enableFederatedAvatar := enableFederatedAvatarSetting.GetValueBool()
var err error var err error
if enableFederatedAvatar && system_model.LibravatarService != nil { if enableFederatedAvatar && system_model.LibravatarService != nil {
@ -175,9 +174,7 @@ func generateEmailAvatarLink(email string, size int, final bool) string {
return urlStr return urlStr
} }
disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) disableGravatar := system_model.GetSettingBool(system_model.KeyPictureDisableGravatar)
disableGravatar := disableGravatarSetting.GetValueBool()
if !disableGravatar { if !disableGravatar {
// copy GravatarSourceURL, because we will modify its Path. // copy GravatarSourceURL, because we will modify its Path.
avatarURLCopy := *system_model.GravatarSourceURL avatarURLCopy := *system_model.GravatarSourceURL

View File

@ -6,7 +6,6 @@ package v1_19 //nolint
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -56,9 +55,9 @@ func batchProcess[T any](x *xorm.Engine, buf []T, query func(limit, start int) *
func AddHeaderAuthorizationEncryptedColWebhook(x *xorm.Engine) error { func AddHeaderAuthorizationEncryptedColWebhook(x *xorm.Engine) error {
// Add the column to the table // Add the column to the table
type Webhook struct { type Webhook struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
Type webhook.HookType `xorm:"VARCHAR(16) 'type'"` Type string `xorm:"VARCHAR(16) 'type'"`
Meta string `xorm:"TEXT"` // store hook-specific attributes Meta string `xorm:"TEXT"` // store hook-specific attributes
// HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization() // HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization()
HeaderAuthorizationEncrypted string `xorm:"TEXT"` HeaderAuthorizationEncrypted string `xorm:"TEXT"`

View File

@ -7,10 +7,10 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/models/migrations/base"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -18,9 +18,9 @@ import (
func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) { func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) {
// Create Webhook table // Create Webhook table
type Webhook struct { type Webhook struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
Type webhook.HookType `xorm:"VARCHAR(16) 'type'"` Type webhook_module.HookType `xorm:"VARCHAR(16) 'type'"`
Meta string `xorm:"TEXT"` // store hook-specific attributes Meta string `xorm:"TEXT"` // store hook-specific attributes
// HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization() // HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization()
HeaderAuthorizationEncrypted string `xorm:"TEXT"` HeaderAuthorizationEncrypted string `xorm:"TEXT"`

View File

@ -92,13 +92,13 @@ func GetSettingNoCache(key string) (*Setting, error) {
} }
// GetSetting returns the setting value via the key // GetSetting returns the setting value via the key
func GetSetting(key string) (*Setting, error) { func GetSetting(key string) (string, error) {
return cache.Get(genSettingCacheKey(key), func() (*Setting, error) { return cache.GetString(genSettingCacheKey(key), func() (string, error) {
res, err := GetSettingNoCache(key) res, err := GetSettingNoCache(key)
if err != nil { if err != nil {
return nil, err return "", err
} }
return res, nil return res.SettingValue, nil
}) })
} }
@ -106,7 +106,8 @@ func GetSetting(key string) (*Setting, error) {
// none existing keys and errors are ignored and result in false // none existing keys and errors are ignored and result in false
func GetSettingBool(key string) bool { func GetSettingBool(key string) bool {
s, _ := GetSetting(key) s, _ := GetSetting(key)
return s.GetValueBool() v, _ := strconv.ParseBool(s)
return v
} }
// GetSettings returns specific settings // GetSettings returns specific settings
@ -183,8 +184,8 @@ func SetSettingNoVersion(key, value string) error {
// SetSetting updates a users' setting for a specific key // SetSetting updates a users' setting for a specific key
func SetSetting(setting *Setting) error { func SetSetting(setting *Setting) error {
_, err := cache.Set(genSettingCacheKey(setting.SettingKey), func() (*Setting, error) { _, err := cache.GetString(genSettingCacheKey(setting.SettingKey), func() (string, error) {
return setting, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version) return setting.SettingValue, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version)
}) })
if err != nil { if err != nil {
return err return err
@ -266,7 +267,7 @@ func Init() error {
enableFederatedAvatar = false enableFederatedAvatar = false
} }
if disableGravatar || !enableFederatedAvatar { if enableFederatedAvatar || !disableGravatar {
var err error var err error
GravatarSourceURL, err = url.Parse(setting.GravatarSource) GravatarSourceURL, err = url.Parse(setting.GravatarSource)
if err != nil { if err != nil {

View File

@ -67,9 +67,7 @@ func (u *User) AvatarLinkWithSize(size int) string {
useLocalAvatar := false useLocalAvatar := false
autoGenerateAvatar := false autoGenerateAvatar := false
disableGravatarSetting, _ := system_model.GetSetting(system_model.KeyPictureDisableGravatar) disableGravatar := system_model.GetSettingBool(system_model.KeyPictureDisableGravatar)
disableGravatar := disableGravatarSetting.GetValueBool()
switch { switch {
case u.UseCustomAvatar: case u.UseCustomAvatar:

View File

@ -53,13 +53,13 @@ func genSettingCacheKey(userID int64, key string) string {
} }
// GetSetting returns the setting value via the key // GetSetting returns the setting value via the key
func GetSetting(uid int64, key string) (*Setting, error) { func GetSetting(uid int64, key string) (string, error) {
return cache.Get(genSettingCacheKey(uid, key), func() (*Setting, error) { return cache.GetString(genSettingCacheKey(uid, key), func() (string, error) {
res, err := GetSettingNoCache(uid, key) res, err := GetSettingNoCache(uid, key)
if err != nil { if err != nil {
return nil, err return "", err
} }
return res, nil return res.SettingValue, nil
}) })
} }
@ -154,7 +154,7 @@ func SetUserSetting(userID int64, key, value string) error {
return err return err
} }
_, err := cache.Set(genSettingCacheKey(userID, key), func() (string, error) { _, err := cache.GetString(genSettingCacheKey(userID, key), func() (string, error) {
return value, upsertUserSettingValue(userID, key, value) return value, upsertUserSettingValue(userID, key, value)
}) })

View File

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
gouuid "github.com/google/uuid" gouuid "github.com/google/uuid"
) )
@ -107,7 +108,7 @@ type HookTask struct {
UUID string `xorm:"unique"` UUID string `xorm:"unique"`
api.Payloader `xorm:"-"` api.Payloader `xorm:"-"`
PayloadContent string `xorm:"LONGTEXT"` PayloadContent string `xorm:"LONGTEXT"`
EventType HookEventType EventType webhook_module.HookEventType
IsDelivered bool IsDelivered bool
Delivered int64 Delivered int64
DeliveredString string `xorm:"-"` DeliveredString string `xorm:"-"`

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
"xorm.io/builder" "xorm.io/builder"
) )
@ -46,7 +47,7 @@ type ErrHookTaskNotExist struct {
UUID string UUID string
} }
// IsErrWebhookNotExist checks if an error is a ErrWebhookNotExist. // IsErrHookTaskNotExist checks if an error is a ErrHookTaskNotExist.
func IsErrHookTaskNotExist(err error) bool { func IsErrHookTaskNotExist(err error) bool {
_, ok := err.(ErrHookTaskNotExist) _, ok := err.(ErrHookTaskNotExist)
return ok return ok
@ -117,84 +118,22 @@ func IsValidHookContentType(name string) bool {
return ok return ok
} }
// HookEvents is a set of web hook events
type HookEvents struct {
Create bool `json:"create"`
Delete bool `json:"delete"`
Fork bool `json:"fork"`
Issues bool `json:"issues"`
IssueAssign bool `json:"issue_assign"`
IssueLabel bool `json:"issue_label"`
IssueMilestone bool `json:"issue_milestone"`
IssueComment bool `json:"issue_comment"`
Push bool `json:"push"`
PullRequest bool `json:"pull_request"`
PullRequestAssign bool `json:"pull_request_assign"`
PullRequestLabel bool `json:"pull_request_label"`
PullRequestMilestone bool `json:"pull_request_milestone"`
PullRequestComment bool `json:"pull_request_comment"`
PullRequestReview bool `json:"pull_request_review"`
PullRequestSync bool `json:"pull_request_sync"`
Wiki bool `json:"wiki"`
Repository bool `json:"repository"`
Release bool `json:"release"`
Package bool `json:"package"`
}
// HookEvent represents events that will delivery hook.
type HookEvent struct {
PushOnly bool `json:"push_only"`
SendEverything bool `json:"send_everything"`
ChooseEvents bool `json:"choose_events"`
BranchFilter string `json:"branch_filter"`
HookEvents `json:"events"`
}
// HookType is the type of a webhook
type HookType = string
// Types of webhooks
const (
GITEA HookType = "gitea"
GOGS HookType = "gogs"
SLACK HookType = "slack"
DISCORD HookType = "discord"
DINGTALK HookType = "dingtalk"
TELEGRAM HookType = "telegram"
MSTEAMS HookType = "msteams"
FEISHU HookType = "feishu"
MATRIX HookType = "matrix"
WECHATWORK HookType = "wechatwork"
PACKAGIST HookType = "packagist"
)
// HookStatus is the status of a web hook
type HookStatus int
// Possible statuses of a web hook
const (
HookStatusNone = iota
HookStatusSucceed
HookStatusFail
)
// Webhook represents a web hook object. // Webhook represents a web hook object.
type Webhook struct { type Webhook struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX"` // An ID of 0 indicates either a default or system webhook RepoID int64 `xorm:"INDEX"` // An ID of 0 indicates either a default or system webhook
OrgID int64 `xorm:"INDEX"` OrgID int64 `xorm:"INDEX"`
IsSystemWebhook bool IsSystemWebhook bool
URL string `xorm:"url TEXT"` URL string `xorm:"url TEXT"`
HTTPMethod string `xorm:"http_method"` HTTPMethod string `xorm:"http_method"`
ContentType HookContentType ContentType HookContentType
Secret string `xorm:"TEXT"` Secret string `xorm:"TEXT"`
Events string `xorm:"TEXT"` Events string `xorm:"TEXT"`
*HookEvent `xorm:"-"` *webhook_module.HookEvent `xorm:"-"`
IsActive bool `xorm:"INDEX"` IsActive bool `xorm:"INDEX"`
Type HookType `xorm:"VARCHAR(16) 'type'"` Type webhook_module.HookType `xorm:"VARCHAR(16) 'type'"`
Meta string `xorm:"TEXT"` // store hook-specific attributes Meta string `xorm:"TEXT"` // store hook-specific attributes
LastStatus HookStatus // Last delivery status LastStatus webhook_module.HookStatus // Last delivery status
// HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization() // HeaderAuthorizationEncrypted should be accessed using HeaderAuthorization() and SetHeaderAuthorization()
HeaderAuthorizationEncrypted string `xorm:"TEXT"` HeaderAuthorizationEncrypted string `xorm:"TEXT"`
@ -209,7 +148,7 @@ func init() {
// AfterLoad updates the webhook object upon setting a column // AfterLoad updates the webhook object upon setting a column
func (w *Webhook) AfterLoad() { func (w *Webhook) AfterLoad() {
w.HookEvent = &HookEvent{} w.HookEvent = &webhook_module.HookEvent{}
if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil {
log.Error("Unmarshal[%d]: %v", w.ID, err) log.Error("Unmarshal[%d]: %v", w.ID, err)
} }
@ -362,34 +301,34 @@ func (w *Webhook) HasPackageEvent() bool {
// EventCheckers returns event checkers // EventCheckers returns event checkers
func (w *Webhook) EventCheckers() []struct { func (w *Webhook) EventCheckers() []struct {
Has func() bool Has func() bool
Type HookEventType Type webhook_module.HookEventType
} { } {
return []struct { return []struct {
Has func() bool Has func() bool
Type HookEventType Type webhook_module.HookEventType
}{ }{
{w.HasCreateEvent, HookEventCreate}, {w.HasCreateEvent, webhook_module.HookEventCreate},
{w.HasDeleteEvent, HookEventDelete}, {w.HasDeleteEvent, webhook_module.HookEventDelete},
{w.HasForkEvent, HookEventFork}, {w.HasForkEvent, webhook_module.HookEventFork},
{w.HasPushEvent, HookEventPush}, {w.HasPushEvent, webhook_module.HookEventPush},
{w.HasIssuesEvent, HookEventIssues}, {w.HasIssuesEvent, webhook_module.HookEventIssues},
{w.HasIssuesAssignEvent, HookEventIssueAssign}, {w.HasIssuesAssignEvent, webhook_module.HookEventIssueAssign},
{w.HasIssuesLabelEvent, HookEventIssueLabel}, {w.HasIssuesLabelEvent, webhook_module.HookEventIssueLabel},
{w.HasIssuesMilestoneEvent, HookEventIssueMilestone}, {w.HasIssuesMilestoneEvent, webhook_module.HookEventIssueMilestone},
{w.HasIssueCommentEvent, HookEventIssueComment}, {w.HasIssueCommentEvent, webhook_module.HookEventIssueComment},
{w.HasPullRequestEvent, HookEventPullRequest}, {w.HasPullRequestEvent, webhook_module.HookEventPullRequest},
{w.HasPullRequestAssignEvent, HookEventPullRequestAssign}, {w.HasPullRequestAssignEvent, webhook_module.HookEventPullRequestAssign},
{w.HasPullRequestLabelEvent, HookEventPullRequestLabel}, {w.HasPullRequestLabelEvent, webhook_module.HookEventPullRequestLabel},
{w.HasPullRequestMilestoneEvent, HookEventPullRequestMilestone}, {w.HasPullRequestMilestoneEvent, webhook_module.HookEventPullRequestMilestone},
{w.HasPullRequestCommentEvent, HookEventPullRequestComment}, {w.HasPullRequestCommentEvent, webhook_module.HookEventPullRequestComment},
{w.HasPullRequestApprovedEvent, HookEventPullRequestReviewApproved}, {w.HasPullRequestApprovedEvent, webhook_module.HookEventPullRequestReviewApproved},
{w.HasPullRequestRejectedEvent, HookEventPullRequestReviewRejected}, {w.HasPullRequestRejectedEvent, webhook_module.HookEventPullRequestReviewRejected},
{w.HasPullRequestCommentEvent, HookEventPullRequestReviewComment}, {w.HasPullRequestCommentEvent, webhook_module.HookEventPullRequestReviewComment},
{w.HasPullRequestSyncEvent, HookEventPullRequestSync}, {w.HasPullRequestSyncEvent, webhook_module.HookEventPullRequestSync},
{w.HasWikiEvent, HookEventWiki}, {w.HasWikiEvent, webhook_module.HookEventWiki},
{w.HasRepositoryEvent, HookEventRepository}, {w.HasRepositoryEvent, webhook_module.HookEventRepository},
{w.HasReleaseEvent, HookEventRelease}, {w.HasReleaseEvent, webhook_module.HookEventRelease},
{w.HasPackageEvent, HookEventPackage}, {w.HasPackageEvent, webhook_module.HookEventPackage},
} }
} }
@ -453,7 +392,7 @@ func getWebhook(bean *Webhook) (*Webhook, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, ErrWebhookNotExist{bean.ID} return nil, ErrWebhookNotExist{ID: bean.ID}
} }
return bean, nil return bean, nil
} }
@ -541,7 +480,7 @@ func GetSystemOrDefaultWebhook(id int64) (*Webhook, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
return nil, ErrWebhookNotExist{id} return nil, ErrWebhookNotExist{ID: id}
} }
return webhook, nil return webhook, nil
} }

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -46,11 +47,11 @@ func TestWebhook_History(t *testing.T) {
func TestWebhook_UpdateEvent(t *testing.T) { func TestWebhook_UpdateEvent(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}) webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
hookEvent := &HookEvent{ hookEvent := &webhook_module.HookEvent{
PushOnly: true, PushOnly: true,
SendEverything: false, SendEverything: false,
ChooseEvents: false, ChooseEvents: false,
HookEvents: HookEvents{ HookEvents: webhook_module.HookEvents{
Create: false, Create: false,
Push: true, Push: true,
PullRequest: false, PullRequest: false,
@ -59,7 +60,7 @@ func TestWebhook_UpdateEvent(t *testing.T) {
webhook.HookEvent = hookEvent webhook.HookEvent = hookEvent
assert.NoError(t, webhook.UpdateEvent()) assert.NoError(t, webhook.UpdateEvent())
assert.NotEmpty(t, webhook.Events) assert.NotEmpty(t, webhook.Events)
actualHookEvent := &HookEvent{} actualHookEvent := &webhook_module.HookEvent{}
assert.NoError(t, json.Unmarshal([]byte(webhook.Events), actualHookEvent)) assert.NoError(t, json.Unmarshal([]byte(webhook.Events), actualHookEvent))
assert.Equal(t, *hookEvent, *actualHookEvent) assert.Equal(t, *hookEvent, *actualHookEvent)
} }
@ -74,13 +75,13 @@ func TestWebhook_EventsArray(t *testing.T) {
"package", "package",
}, },
(&Webhook{ (&Webhook{
HookEvent: &HookEvent{SendEverything: true}, HookEvent: &webhook_module.HookEvent{SendEverything: true},
}).EventsArray(), }).EventsArray(),
) )
assert.Equal(t, []string{"push"}, assert.Equal(t, []string{"push"},
(&Webhook{ (&Webhook{
HookEvent: &HookEvent{PushOnly: true}, HookEvent: &webhook_module.HookEvent{PushOnly: true},
}).EventsArray(), }).EventsArray(),
) )
} }

View File

@ -45,39 +45,6 @@ func GetCache() mc.Cache {
return conn return conn
} }
// Get returns the key value from cache with callback when no key exists in cache
func Get[V interface{}](key string, getFunc func() (V, error)) (V, error) {
if conn == nil || setting.CacheService.TTL == 0 {
return getFunc()
}
cached := conn.Get(key)
if value, ok := cached.(V); ok {
return value, nil
}
value, err := getFunc()
if err != nil {
return value, err
}
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
}
// Set updates and returns the key value in the cache with callback. The old value is only removed if the updateFunc() is successful
func Set[V interface{}](key string, valueFunc func() (V, error)) (V, error) {
if conn == nil || setting.CacheService.TTL == 0 {
return valueFunc()
}
value, err := valueFunc()
if err != nil {
return value, err
}
return value, conn.Put(key, value, setting.CacheService.TTLSeconds())
}
// GetString returns the key value from cache with callback when no key exists in cache // GetString returns the key value from cache with callback when no key exists in cache
func GetString(key string, getFunc func() (string, error)) (string, error) { func GetString(key string, getFunc func() (string, error)) (string, error) {
if conn == nil || setting.CacheService.TTL == 0 { if conn == nil || setting.CacheService.TTL == 0 {

View File

@ -16,7 +16,6 @@ import (
"code.gitea.io/gitea/modules/notification/mail" "code.gitea.io/gitea/modules/notification/mail"
"code.gitea.io/gitea/modules/notification/mirror" "code.gitea.io/gitea/modules/notification/mirror"
"code.gitea.io/gitea/modules/notification/ui" "code.gitea.io/gitea/modules/notification/ui"
"code.gitea.io/gitea/modules/notification/webhook"
"code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -36,7 +35,6 @@ func NewContext() {
RegisterNotifier(mail.NewNotifier()) RegisterNotifier(mail.NewNotifier())
} }
RegisterNotifier(indexer.NewNotifier()) RegisterNotifier(indexer.NewNotifier())
RegisterNotifier(webhook.NewNotifier())
RegisterNotifier(action.NewNotifier()) RegisterNotifier(action.NewNotifier())
RegisterNotifier(mirror.NewNotifier()) RegisterNotifier(mirror.NewNotifier())
} }

View File

@ -284,8 +284,6 @@ func newRouterLogService() {
} }
func newLogService() { func newLogService() {
log.Info("Gitea v%s%s", AppVer, AppBuiltWith)
options := newDefaultLogOptions() options := newDefaultLogOptions()
options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000) options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000)
EnableSSHLog = Cfg.Section("log").Key("ENABLE_SSH_LOG").MustBool(false) EnableSSHLog = Cfg.Section("log").Key("ENABLE_SSH_LOG").MustBool(false)
@ -297,24 +295,14 @@ func newLogService() {
sections := strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",") sections := strings.Split(Cfg.Section("log").Key("MODE").MustString("console"), ",")
useConsole := false useConsole := false
for i := 0; i < len(sections); i++ {
sections[i] = strings.TrimSpace(sections[i])
if sections[i] == "console" {
useConsole = true
}
}
if !useConsole {
err := log.DelLogger("console")
if err != nil {
log.Fatal("DelLogger: %v", err)
}
}
for _, name := range sections { for _, name := range sections {
if len(name) == 0 { name = strings.TrimSpace(name)
if name == "" {
continue continue
} }
if name == "console" {
useConsole = true
}
sec, err := Cfg.GetSection("log." + name + ".default") sec, err := Cfg.GetSection("log." + name + ".default")
if err != nil { if err != nil {
@ -336,6 +324,13 @@ func newLogService() {
AddLogDescription(log.DEFAULT, &description) AddLogDescription(log.DEFAULT, &description)
if !useConsole {
log.Info("According to the configuration, subsequent logs will not be printed to the console")
if err := log.DelLogger("console"); err != nil {
log.Fatal("Cannot delete console logger: %v", err)
}
}
// Finally redirect the default golog to here // Finally redirect the default golog to here
golog.SetFlags(0) golog.SetFlags(0)
golog.SetPrefix("") golog.SetPrefix("")

View File

@ -68,7 +68,7 @@ func newPictureService() {
} }
func GetDefaultDisableGravatar() bool { func GetDefaultDisableGravatar() bool {
return !OfflineMode return OfflineMode
} }
func GetDefaultEnableFederatedAvatar(disableGravatar bool) bool { func GetDefaultEnableFederatedAvatar(disableGravatar bool) bool {

View File

@ -0,0 +1,38 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package webhook
// HookEvents is a set of web hook events
type HookEvents struct {
Create bool `json:"create"`
Delete bool `json:"delete"`
Fork bool `json:"fork"`
Issues bool `json:"issues"`
IssueAssign bool `json:"issue_assign"`
IssueLabel bool `json:"issue_label"`
IssueMilestone bool `json:"issue_milestone"`
IssueComment bool `json:"issue_comment"`
Push bool `json:"push"`
PullRequest bool `json:"pull_request"`
PullRequestAssign bool `json:"pull_request_assign"`
PullRequestLabel bool `json:"pull_request_label"`
PullRequestMilestone bool `json:"pull_request_milestone"`
PullRequestComment bool `json:"pull_request_comment"`
PullRequestReview bool `json:"pull_request_review"`
PullRequestSync bool `json:"pull_request_sync"`
Wiki bool `json:"wiki"`
Repository bool `json:"repository"`
Release bool `json:"release"`
Package bool `json:"package"`
}
// HookEvent represents events that will delivery hook.
type HookEvent struct {
PushOnly bool `json:"push_only"`
SendEverything bool `json:"send_everything"`
ChooseEvents bool `json:"choose_events"`
BranchFilter string `json:"branch_filter"`
HookEvents `json:"events"`
}

95
modules/webhook/type.go Normal file
View File

@ -0,0 +1,95 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package webhook
// HookEventType is the type of a hook event
type HookEventType string
// Types of hook events
const (
HookEventCreate HookEventType = "create"
HookEventDelete HookEventType = "delete"
HookEventFork HookEventType = "fork"
HookEventPush HookEventType = "push"
HookEventIssues HookEventType = "issues"
HookEventIssueAssign HookEventType = "issue_assign"
HookEventIssueLabel HookEventType = "issue_label"
HookEventIssueMilestone HookEventType = "issue_milestone"
HookEventIssueComment HookEventType = "issue_comment"
HookEventPullRequest HookEventType = "pull_request"
HookEventPullRequestAssign HookEventType = "pull_request_assign"
HookEventPullRequestLabel HookEventType = "pull_request_label"
HookEventPullRequestMilestone HookEventType = "pull_request_milestone"
HookEventPullRequestComment HookEventType = "pull_request_comment"
HookEventPullRequestReviewApproved HookEventType = "pull_request_review_approved"
HookEventPullRequestReviewRejected HookEventType = "pull_request_review_rejected"
HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment"
HookEventPullRequestSync HookEventType = "pull_request_sync"
HookEventWiki HookEventType = "wiki"
HookEventRepository HookEventType = "repository"
HookEventRelease HookEventType = "release"
HookEventPackage HookEventType = "package"
)
// Event returns the HookEventType as an event string
func (h HookEventType) Event() string {
switch h {
case HookEventCreate:
return "create"
case HookEventDelete:
return "delete"
case HookEventFork:
return "fork"
case HookEventPush:
return "push"
case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone:
return "issues"
case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone,
HookEventPullRequestSync:
return "pull_request"
case HookEventIssueComment, HookEventPullRequestComment:
return "issue_comment"
case HookEventPullRequestReviewApproved:
return "pull_request_approved"
case HookEventPullRequestReviewRejected:
return "pull_request_rejected"
case HookEventPullRequestReviewComment:
return "pull_request_comment"
case HookEventWiki:
return "wiki"
case HookEventRepository:
return "repository"
case HookEventRelease:
return "release"
}
return ""
}
// HookType is the type of a webhook
type HookType = string
// Types of webhooks
const (
GITEA HookType = "gitea"
GOGS HookType = "gogs"
SLACK HookType = "slack"
DISCORD HookType = "discord"
DINGTALK HookType = "dingtalk"
TELEGRAM HookType = "telegram"
MSTEAMS HookType = "msteams"
FEISHU HookType = "feishu"
MATRIX HookType = "matrix"
WECHATWORK HookType = "wechatwork"
PACKAGIST HookType = "packagist"
)
// HookStatus is the status of a web hook
type HookStatus int
// Possible statuses of a web hook
const (
HookStatusNone HookStatus = iota
HookStatusSucceed
HookStatusFail
)

View File

@ -6,12 +6,12 @@ package org
import ( import (
"net/http" "net/http"
"code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/convert" webhook_service "code.gitea.io/gitea/services/webhook"
) )
// ListHooks list an organziation's webhooks // ListHooks list an organziation's webhooks
@ -39,18 +39,18 @@ func ListHooks(ctx *context.APIContext) {
// "200": // "200":
// "$ref": "#/responses/HookList" // "$ref": "#/responses/HookList"
opts := &webhook.ListWebhookOptions{ opts := &webhook_model.ListWebhookOptions{
ListOptions: utils.GetListOptions(ctx), ListOptions: utils.GetListOptions(ctx),
OrgID: ctx.Org.Organization.ID, OrgID: ctx.Org.Organization.ID,
} }
count, err := webhook.CountWebhooksByOpts(opts) count, err := webhook_model.CountWebhooksByOpts(opts)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
} }
orgHooks, err := webhook.ListWebhooksByOpts(ctx, opts) orgHooks, err := webhook_model.ListWebhooksByOpts(ctx, opts)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -58,7 +58,7 @@ func ListHooks(ctx *context.APIContext) {
hooks := make([]*api.Hook, len(orgHooks)) hooks := make([]*api.Hook, len(orgHooks))
for i, hook := range orgHooks { for i, hook := range orgHooks {
hooks[i], err = convert.ToHook(ctx.Org.Organization.AsUser().HomeLink(), hook) hooks[i], err = webhook_service.ToHook(ctx.Org.Organization.AsUser().HomeLink(), hook)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -99,7 +99,7 @@ func GetHook(ctx *context.APIContext) {
return return
} }
apiHook, err := convert.ToHook(org.AsUser().HomeLink(), hook) apiHook, err := webhook_service.ToHook(org.AsUser().HomeLink(), hook)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -200,8 +200,8 @@ func DeleteHook(ctx *context.APIContext) {
org := ctx.Org.Organization org := ctx.Org.Organization
hookID := ctx.ParamsInt64(":id") hookID := ctx.ParamsInt64(":id")
if err := webhook.DeleteWebhookByOrgID(org.ID, hookID); err != nil { if err := webhook_model.DeleteWebhookByOrgID(org.ID, hookID); err != nil {
if webhook.IsErrWebhookNotExist(err) { if webhook_model.IsErrWebhookNotExist(err) {
ctx.NotFound() ctx.NotFound()
} else { } else {
ctx.Error(http.StatusInternalServerError, "DeleteWebhookByOrgID", err) ctx.Error(http.StatusInternalServerError, "DeleteWebhookByOrgID", err)

View File

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
webhook_module "code.gitea.io/gitea/modules/webhook"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/convert"
webhook_service "code.gitea.io/gitea/services/webhook" webhook_service "code.gitea.io/gitea/services/webhook"
@ -68,7 +69,7 @@ func ListHooks(ctx *context.APIContext) {
apiHooks := make([]*api.Hook, len(hooks)) apiHooks := make([]*api.Hook, len(hooks))
for i := range hooks { for i := range hooks {
apiHooks[i], err = convert.ToHook(ctx.Repo.RepoLink, hooks[i]) apiHooks[i], err = webhook_service.ToHook(ctx.Repo.RepoLink, hooks[i])
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -115,7 +116,7 @@ func GetHook(ctx *context.APIContext) {
if err != nil { if err != nil {
return return
} }
apiHook, err := convert.ToHook(repo.RepoLink, hook) apiHook, err := webhook_service.ToHook(repo.RepoLink, hook)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -176,7 +177,7 @@ func TestHook(ctx *context.APIContext) {
commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit) commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit)
commitID := ctx.Repo.Commit.ID.String() commitID := ctx.Repo.Commit.ID.String()
if err := webhook_service.PrepareWebhook(ctx, hook, webhook.HookEventPush, &api.PushPayload{ if err := webhook_service.PrepareWebhook(ctx, hook, webhook_module.HookEventPush, &api.PushPayload{
Ref: ref, Ref: ref,
Before: commitID, Before: commitID,
After: commitID, After: commitID,

View File

@ -13,7 +13,7 @@ import (
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/convert" webhook_module "code.gitea.io/gitea/modules/webhook"
webhook_service "code.gitea.io/gitea/services/webhook" webhook_service "code.gitea.io/gitea/services/webhook"
) )
@ -98,7 +98,7 @@ func AddRepoHook(ctx *context.APIContext, form *api.CreateHookOption) {
// toAPIHook converts the hook to its API representation. // toAPIHook converts the hook to its API representation.
// If there is an error, write to `ctx` accordingly. Return (hook, ok) // If there is an error, write to `ctx` accordingly. Return (hook, ok)
func toAPIHook(ctx *context.APIContext, repoLink string, hook *webhook.Webhook) (*api.Hook, bool) { func toAPIHook(ctx *context.APIContext, repoLink string, hook *webhook.Webhook) (*api.Hook, bool) {
apiHook, err := convert.ToHook(repoLink, hook) apiHook, err := webhook_service.ToHook(repoLink, hook)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "ToHook", err) ctx.Error(http.StatusInternalServerError, "ToHook", err)
return nil, false return nil, false
@ -127,9 +127,9 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
ContentType: webhook.ToHookContentType(form.Config["content_type"]), ContentType: webhook.ToHookContentType(form.Config["content_type"]),
Secret: form.Config["secret"], Secret: form.Config["secret"],
HTTPMethod: "POST", HTTPMethod: "POST",
HookEvent: &webhook.HookEvent{ HookEvent: &webhook_module.HookEvent{
ChooseEvents: true, ChooseEvents: true,
HookEvents: webhook.HookEvents{ HookEvents: webhook_module.HookEvents{
Create: util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true), Create: util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true),
Delete: util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true), Delete: util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true),
Fork: util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true), Fork: util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true),
@ -160,7 +160,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
ctx.Error(http.StatusInternalServerError, "SetHeaderAuthorization", err) ctx.Error(http.StatusInternalServerError, "SetHeaderAuthorization", err)
return nil, false return nil, false
} }
if w.Type == webhook.SLACK { if w.Type == webhook_module.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")
@ -253,7 +253,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh
w.ContentType = webhook.ToHookContentType(ct) w.ContentType = webhook.ToHookContentType(ct)
} }
if w.Type == webhook.SLACK { if w.Type == webhook_module.SLACK {
if channel, ok := form.Config["channel"]; ok { if channel, ok := form.Config["channel"]; ok {
meta, err := json.Marshal(&webhook_service.SlackMeta{ meta, err := json.Marshal(&webhook_service.SlackMeta{
Channel: channel, Channel: channel,

View File

@ -119,6 +119,7 @@ func GlobalInitInstalled(ctx context.Context) {
log.Info("Log path: %s", setting.LogRootPath) log.Info("Log path: %s", setting.LogRootPath)
log.Info("Configuration file: %s", setting.CustomConf) log.Info("Configuration file: %s", setting.CustomConf)
log.Info("Run Mode: %s", util.ToTitleCase(setting.RunMode)) log.Info("Run Mode: %s", util.ToTitleCase(setting.RunMode))
log.Info("Gitea v%s%s", setting.AppVer, setting.AppBuiltWith)
// Setup i18n // Setup i18n
translation.InitLocales(ctx) translation.InitLocales(ctx)

View File

@ -23,6 +23,7 @@ import (
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
webhook_module "code.gitea.io/gitea/modules/webhook"
"code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/forms"
webhook_service "code.gitea.io/gitea/services/webhook" webhook_service "code.gitea.io/gitea/services/webhook"
@ -119,7 +120,7 @@ func checkHookType(ctx *context.Context) string {
// WebhooksNew render creating webhook page // WebhooksNew render creating webhook page
func WebhooksNew(ctx *context.Context) { func WebhooksNew(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook_module.HookEvent{}}
orCtx, err := getOrgRepoCtx(ctx) orCtx, err := getOrgRepoCtx(ctx)
if err != nil { if err != nil {
@ -154,12 +155,12 @@ func WebhooksNew(ctx *context.Context) {
} }
// ParseHookEvent convert web form content to webhook.HookEvent // ParseHookEvent convert web form content to webhook.HookEvent
func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent { func ParseHookEvent(form forms.WebhookForm) *webhook_module.HookEvent {
return &webhook.HookEvent{ return &webhook_module.HookEvent{
PushOnly: form.PushOnly(), PushOnly: form.PushOnly(),
SendEverything: form.SendEverything(), SendEverything: form.SendEverything(),
ChooseEvents: form.ChooseEvents(), ChooseEvents: form.ChooseEvents(),
HookEvents: webhook.HookEvents{ HookEvents: webhook_module.HookEvents{
Create: form.Create, Create: form.Create,
Delete: form.Delete, Delete: form.Delete,
Fork: form.Fork, Fork: form.Fork,
@ -201,7 +202,7 @@ func createWebhook(ctx *context.Context, params webhookParams) {
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook") ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
ctx.Data["PageIsSettingsHooks"] = true ctx.Data["PageIsSettingsHooks"] = true
ctx.Data["PageIsSettingsHooksNew"] = true ctx.Data["PageIsSettingsHooksNew"] = true
ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}} ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook_module.HookEvent{}}
ctx.Data["HookType"] = params.Type ctx.Data["HookType"] = params.Type
orCtx, err := getOrgRepoCtx(ctx) orCtx, err := getOrgRepoCtx(ctx)
@ -326,7 +327,7 @@ func giteaHookParams(ctx *context.Context) webhookParams {
} }
return webhookParams{ return webhookParams{
Type: webhook.GITEA, Type: webhook_module.GITEA,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: contentType, ContentType: contentType,
Secret: form.Secret, Secret: form.Secret,
@ -354,7 +355,7 @@ func gogsHookParams(ctx *context.Context) webhookParams {
} }
return webhookParams{ return webhookParams{
Type: webhook.GOGS, Type: webhook_module.GOGS,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: contentType, ContentType: contentType,
Secret: form.Secret, Secret: form.Secret,
@ -376,7 +377,7 @@ func discordHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewDiscordHookForm) form := web.GetForm(ctx).(*forms.NewDiscordHookForm)
return webhookParams{ return webhookParams{
Type: webhook.DISCORD, Type: webhook_module.DISCORD,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -401,7 +402,7 @@ func dingtalkHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewDingtalkHookForm) form := web.GetForm(ctx).(*forms.NewDingtalkHookForm)
return webhookParams{ return webhookParams{
Type: webhook.DINGTALK, Type: webhook_module.DINGTALK,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -422,7 +423,7 @@ func telegramHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewTelegramHookForm) form := web.GetForm(ctx).(*forms.NewTelegramHookForm)
return webhookParams{ return webhookParams{
Type: webhook.TELEGRAM, Type: webhook_module.TELEGRAM,
URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)), URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)),
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -447,7 +448,7 @@ func matrixHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewMatrixHookForm) form := web.GetForm(ctx).(*forms.NewMatrixHookForm)
return webhookParams{ return webhookParams{
Type: webhook.MATRIX, Type: webhook_module.MATRIX,
URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)), URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)),
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
HTTPMethod: http.MethodPut, HTTPMethod: http.MethodPut,
@ -474,7 +475,7 @@ func mSTeamsHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm) form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm)
return webhookParams{ return webhookParams{
Type: webhook.MSTEAMS, Type: webhook_module.MSTEAMS,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -495,7 +496,7 @@ func slackHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewSlackHookForm) form := web.GetForm(ctx).(*forms.NewSlackHookForm)
return webhookParams{ return webhookParams{
Type: webhook.SLACK, Type: webhook_module.SLACK,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -522,7 +523,7 @@ func feishuHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewFeishuHookForm) form := web.GetForm(ctx).(*forms.NewFeishuHookForm)
return webhookParams{ return webhookParams{
Type: webhook.FEISHU, Type: webhook_module.FEISHU,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -543,7 +544,7 @@ func wechatworkHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm) form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm)
return webhookParams{ return webhookParams{
Type: webhook.WECHATWORK, Type: webhook_module.WECHATWORK,
URL: form.PayloadURL, URL: form.PayloadURL,
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -564,7 +565,7 @@ func packagistHookParams(ctx *context.Context) webhookParams {
form := web.GetForm(ctx).(*forms.NewPackagistHookForm) form := web.GetForm(ctx).(*forms.NewPackagistHookForm)
return webhookParams{ return webhookParams{
Type: webhook.PACKAGIST, Type: webhook_module.PACKAGIST,
URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)), URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)),
ContentType: webhook.ContentTypeJSON, ContentType: webhook.ContentTypeJSON,
WebhookForm: form.WebhookForm, WebhookForm: form.WebhookForm,
@ -603,15 +604,15 @@ func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) {
ctx.Data["HookType"] = w.Type ctx.Data["HookType"] = w.Type
switch w.Type { switch w.Type {
case webhook.SLACK: case webhook_module.SLACK:
ctx.Data["SlackHook"] = webhook_service.GetSlackHook(w) ctx.Data["SlackHook"] = webhook_service.GetSlackHook(w)
case webhook.DISCORD: case webhook_module.DISCORD:
ctx.Data["DiscordHook"] = webhook_service.GetDiscordHook(w) ctx.Data["DiscordHook"] = webhook_service.GetDiscordHook(w)
case webhook.TELEGRAM: case webhook_module.TELEGRAM:
ctx.Data["TelegramHook"] = webhook_service.GetTelegramHook(w) ctx.Data["TelegramHook"] = webhook_service.GetTelegramHook(w)
case webhook.MATRIX: case webhook_module.MATRIX:
ctx.Data["MatrixHook"] = webhook_service.GetMatrixHook(w) ctx.Data["MatrixHook"] = webhook_service.GetMatrixHook(w)
case webhook.PACKAGIST: case webhook_module.PACKAGIST:
ctx.Data["PackagistHook"] = webhook_service.GetPackagistHook(w) ctx.Data["PackagistHook"] = webhook_service.GetPackagistHook(w)
} }
@ -688,7 +689,7 @@ func TestWebhook(ctx *context.Context) {
Pusher: apiUser, Pusher: apiUser,
Sender: apiUser, Sender: apiUser,
} }
if err := webhook_service.PrepareWebhook(ctx, w, webhook.HookEventPush, p); err != nil { if err := webhook_service.PrepareWebhook(ctx, w, webhook_module.HookEventPush, p); err != nil {
ctx.Flash.Error("PrepareWebhook: " + err.Error()) ctx.Flash.Error("PrepareWebhook: " + err.Error())
ctx.Status(http.StatusInternalServerError) ctx.Status(http.StatusInternalServerError)
} else { } else {

View File

@ -22,13 +22,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/gitdiff" "code.gitea.io/gitea/services/gitdiff"
webhook_service "code.gitea.io/gitea/services/webhook"
) )
// ToEmail convert models.EmailAddress to api.Email // ToEmail convert models.EmailAddress to api.Email
@ -242,38 +240,6 @@ func ToGPGKeyEmail(email *user_model.EmailAddress) *api.GPGKeyEmail {
} }
} }
// ToHook convert models.Webhook to api.Hook
func ToHook(repoLink string, w *webhook.Webhook) (*api.Hook, error) {
config := map[string]string{
"url": w.URL,
"content_type": w.ContentType.Name(),
}
if w.Type == webhook.SLACK {
s := webhook_service.GetSlackHook(w)
config["channel"] = s.Channel
config["username"] = s.Username
config["icon_url"] = s.IconURL
config["color"] = s.Color
}
authorizationHeader, err := w.HeaderAuthorization()
if err != nil {
return nil, err
}
return &api.Hook{
ID: w.ID,
Type: w.Type,
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
AuthorizationHeader: authorizationHeader,
Updated: w.UpdatedUnix.AsTime(),
Created: w.CreatedUnix.AsTime(),
}, nil
}
// ToGitHook convert git.Hook to api.GitHook // ToGitHook convert git.Hook to api.GitHook
func ToGitHook(h *git.Hook) *api.GitHook { func ToGitHook(h *git.Hook) *api.GitHook {
return &api.GitHook{ return &api.GitHook{

View File

@ -26,6 +26,7 @@ import (
"code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/proxy"
"code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob" "github.com/gobwas/glob"
) )
@ -89,7 +90,7 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
} }
case http.MethodPut: case http.MethodPut:
switch w.Type { switch w.Type {
case webhook_model.MATRIX: case webhook_module.MATRIX:
txnID, err := getMatrixTxnID([]byte(t.PayloadContent)) txnID, err := getMatrixTxnID([]byte(t.PayloadContent))
if err != nil { if err != nil {
return err return err
@ -189,9 +190,9 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
// Update webhook last delivery status. // Update webhook last delivery status.
if t.IsSucceed { if t.IsSucceed {
w.LastStatus = webhook_model.HookStatusSucceed w.LastStatus = webhook_module.HookStatusSucceed
} else { } else {
w.LastStatus = webhook_model.HookStatusFail w.LastStatus = webhook_module.HookStatusFail
} }
if err = webhook_model.UpdateWebhookLastStatus(w); err != nil { if err = webhook_model.UpdateWebhookLastStatus(w); err != nil {
log.Error("UpdateWebhookLastStatus: %v", err) log.Error("UpdateWebhookLastStatus: %v", err)

View File

@ -16,6 +16,7 @@ import (
webhook_model "code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -62,14 +63,14 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) {
URL: s.URL + "/webhook", URL: s.URL + "/webhook",
ContentType: webhook_model.ContentTypeJSON, ContentType: webhook_model.ContentTypeJSON,
IsActive: true, IsActive: true,
Type: webhook_model.GITEA, Type: webhook_module.GITEA,
} }
err := hook.SetHeaderAuthorization("Bearer s3cr3t-t0ken") err := hook.SetHeaderAuthorization("Bearer s3cr3t-t0ken")
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook)) assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook))
db.GetEngine(db.DefaultContext).NoAutoTime().DB().Logger.ShowSQL(true) db.GetEngine(db.DefaultContext).NoAutoTime().DB().Logger.ShowSQL(true)
hookTask := &webhook_model.HookTask{HookID: hook.ID, EventType: webhook_model.HookEventPush, Payloader: &api.PushPayload{}} hookTask := &webhook_model.HookTask{HookID: hook.ID, EventType: webhook_module.HookEventPush, Payloader: &api.PushPayload{}}
hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask) hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask)
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -8,11 +8,11 @@ import (
"net/url" "net/url"
"strings" "strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
dingtalk "gitea.com/lunny/dingtalk_webhook" dingtalk "gitea.com/lunny/dingtalk_webhook"
) )
@ -129,7 +129,7 @@ func (d *DingtalkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader,
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (d *DingtalkPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (d *DingtalkPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
var text, title string var text, title string
switch p.Action { switch p.Action {
case api.HookIssueReviewed: case api.HookIssueReviewed:
@ -190,6 +190,6 @@ func createDingtalkPayload(title, text, singleTitle, singleURL string) *Dingtalk
} }
// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload // GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload
func GetDingtalkPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetDingtalkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
return convertPayloader(new(DingtalkPayload), p, event) return convertPayloader(new(DingtalkPayload), p, event)
} }

View File

@ -7,8 +7,8 @@ import (
"net/url" "net/url"
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -162,7 +162,7 @@ func TestDingTalkPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(DingtalkPayload) d := new(DingtalkPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &DingtalkPayload{}, pl) require.IsType(t, &DingtalkPayload{}, pl)

View File

@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -190,7 +191,7 @@ func (d *DiscordPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader,
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (d *DiscordPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (d *DiscordPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
var text, title string var text, title string
var color int var color int
switch p.Action { switch p.Action {
@ -204,11 +205,11 @@ func (d *DiscordPayload) Review(p *api.PullRequestPayload, event webhook_model.H
text = p.Review.Content text = p.Review.Content
switch event { switch event {
case webhook_model.HookEventPullRequestReviewApproved: case webhook_module.HookEventPullRequestReviewApproved:
color = greenColor color = greenColor
case webhook_model.HookEventPullRequestReviewRejected: case webhook_module.HookEventPullRequestReviewRejected:
color = redColor color = redColor
case webhook_model.HookEventPullRequestComment: case webhook_module.HookEventPullRequestComment:
color = greyColor color = greyColor
default: default:
color = yellowColor color = yellowColor
@ -256,7 +257,7 @@ func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
} }
// GetDiscordPayload converts a discord webhook into a DiscordPayload // GetDiscordPayload converts a discord webhook into a DiscordPayload
func GetDiscordPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetDiscordPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
s := new(DiscordPayload) s := new(DiscordPayload)
discord := &DiscordMeta{} discord := &DiscordMeta{}
@ -269,14 +270,14 @@ func GetDiscordPayload(p api.Payloader, event webhook_model.HookEventType, meta
return convertPayloader(s, p, event) return convertPayloader(s, p, event)
} }
func parseHookPullRequestEventType(event webhook_model.HookEventType) (string, error) { func parseHookPullRequestEventType(event webhook_module.HookEventType) (string, error) {
switch event { switch event {
case webhook_model.HookEventPullRequestReviewApproved: case webhook_module.HookEventPullRequestReviewApproved:
return "approved", nil return "approved", nil
case webhook_model.HookEventPullRequestReviewRejected: case webhook_module.HookEventPullRequestReviewRejected:
return "rejected", nil return "rejected", nil
case webhook_model.HookEventPullRequestComment: case webhook_module.HookEventPullRequestComment:
return "comment", nil return "comment", nil
default: default:

View File

@ -6,9 +6,9 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -179,7 +179,7 @@ func TestDiscordPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(DiscordPayload) d := new(DiscordPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &DiscordPayload{}, pl) require.IsType(t, &DiscordPayload{}, pl)

View File

@ -7,10 +7,10 @@ import (
"fmt" "fmt"
"strings" "strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -117,7 +117,7 @@ func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, e
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (f *FeishuPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (f *FeishuPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
action, err := parseHookPullRequestEventType(event) action, err := parseHookPullRequestEventType(event)
if err != nil { if err != nil {
return nil, err return nil, err
@ -159,6 +159,6 @@ func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
} }
// GetFeishuPayload converts a ding talk webhook into a FeishuPayload // GetFeishuPayload converts a ding talk webhook into a FeishuPayload
func GetFeishuPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetFeishuPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
return convertPayloader(new(FeishuPayload), p, event) return convertPayloader(new(FeishuPayload), p, event)
} }

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -124,7 +124,7 @@ func TestFeishuPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(FeishuPayload) d := new(FeishuPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &FeishuPayload{}, pl) require.IsType(t, &FeishuPayload{}, pl)

View File

@ -9,9 +9,11 @@ import (
"net/url" "net/url"
"strings" "strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type linkFormatter = func(string, string) string type linkFormatter = func(string, string) string
@ -223,3 +225,36 @@ func getIssueCommentPayloadInfo(p *api.IssueCommentPayload, linkFormatter linkFo
return text, issueTitle, color return text, issueTitle, color
} }
// ToHook convert models.Webhook to api.Hook
// This function is not part of the convert package to prevent an import cycle
func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) {
config := map[string]string{
"url": w.URL,
"content_type": w.ContentType.Name(),
}
if w.Type == webhook_module.SLACK {
s := GetSlackHook(w)
config["channel"] = s.Channel
config["username"] = s.Username
config["icon_url"] = s.IconURL
config["color"] = s.Color
}
authorizationHeader, err := w.HeaderAuthorization()
if err != nil {
return nil, err
}
return &api.Hook{
ID: w.ID,
Type: w.Type,
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
AuthorizationHeader: authorizationHeader,
Updated: w.UpdatedUnix.AsTime(),
Created: w.CreatedUnix.AsTime(),
}, nil
}

View File

@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
const matrixPayloadSizeLimit = 1024 * 64 const matrixPayloadSizeLimit = 1024 * 64
@ -173,7 +174,7 @@ func (m *MatrixPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, e
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (m *MatrixPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (m *MatrixPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
senderLink := MatrixLinkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) senderLink := MatrixLinkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title) title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
titleLink := MatrixLinkFormatter(p.PullRequest.URL, title) titleLink := MatrixLinkFormatter(p.PullRequest.URL, title)
@ -210,7 +211,7 @@ func (m *MatrixPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err
} }
// GetMatrixPayload converts a Matrix webhook into a MatrixPayload // GetMatrixPayload converts a Matrix webhook into a MatrixPayload
func GetMatrixPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetMatrixPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
s := new(MatrixPayload) s := new(MatrixPayload)
matrix := &MatrixMeta{} matrix := &MatrixMeta{}

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -133,7 +133,7 @@ func TestMatrixPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(MatrixPayload) d := new(MatrixPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &MatrixPayload{}, pl) require.IsType(t, &MatrixPayload{}, pl)

View File

@ -8,11 +8,11 @@ import (
"net/url" "net/url"
"strings" "strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -205,7 +205,7 @@ func (m *MSTeamsPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader,
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (m *MSTeamsPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (m *MSTeamsPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
var text, title string var text, title string
var color int var color int
switch p.Action { switch p.Action {
@ -219,11 +219,11 @@ func (m *MSTeamsPayload) Review(p *api.PullRequestPayload, event webhook_model.H
text = p.Review.Content text = p.Review.Content
switch event { switch event {
case webhook_model.HookEventPullRequestReviewApproved: case webhook_module.HookEventPullRequestReviewApproved:
color = greenColor color = greenColor
case webhook_model.HookEventPullRequestReviewRejected: case webhook_module.HookEventPullRequestReviewRejected:
color = redColor color = redColor
case webhook_model.HookEventPullRequestComment: case webhook_module.HookEventPullRequestComment:
color = greyColor color = greyColor
default: default:
color = yellowColor color = yellowColor
@ -297,7 +297,7 @@ func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
} }
// GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload // GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload
func GetMSTeamsPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetMSTeamsPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
return convertPayloader(new(MSTeamsPayload), p, event) return convertPayloader(new(MSTeamsPayload), p, event)
} }

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -277,7 +277,7 @@ func TestMSTeamsPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(MSTeamsPayload) d := new(MSTeamsPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &MSTeamsPayload{}, pl) require.IsType(t, &MSTeamsPayload{}, pl)

View File

@ -13,17 +13,21 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/notification/base" "code.gitea.io/gitea/modules/notification/base"
"code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/convert"
webhook_services "code.gitea.io/gitea/services/webhook"
) )
func init() {
notification.RegisterNotifier(&webhookNotifier{})
}
type webhookNotifier struct { type webhookNotifier struct {
base.NullNotifier base.NullNotifier
} }
@ -54,7 +58,7 @@ func (m *webhookNotifier) NotifyIssueClearLabels(ctx context.Context, doer *user
return return
} }
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequestLabel, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{
Action: api.HookIssueLabelCleared, Action: api.HookIssueLabelCleared,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
@ -62,7 +66,7 @@ func (m *webhookNotifier) NotifyIssueClearLabels(ctx context.Context, doer *user
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueLabel, &api.IssuePayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
Action: api.HookIssueLabelCleared, Action: api.HookIssueLabelCleared,
Index: issue.Index, Index: issue.Index,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
@ -80,7 +84,7 @@ func (m *webhookNotifier) NotifyForkRepository(ctx context.Context, doer *user_m
mode, _ := access_model.AccessLevel(ctx, doer, repo) mode, _ := access_model.AccessLevel(ctx, doer, repo)
// forked webhook // forked webhook
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: oldRepo}, webhook.HookEventFork, &api.ForkPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: oldRepo}, webhook_module.HookEventFork, &api.ForkPayload{
Forkee: convert.ToRepo(ctx, oldRepo, oldMode), Forkee: convert.ToRepo(ctx, oldRepo, oldMode),
Repo: convert.ToRepo(ctx, repo, mode), Repo: convert.ToRepo(ctx, repo, mode),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
@ -92,7 +96,7 @@ func (m *webhookNotifier) NotifyForkRepository(ctx context.Context, doer *user_m
// Add to hook queue for created repo after session commit. // Add to hook queue for created repo after session commit.
if u.IsOrganization() { if u.IsOrganization() {
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
@ -105,7 +109,7 @@ func (m *webhookNotifier) NotifyForkRepository(ctx context.Context, doer *user_m
func (m *webhookNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { func (m *webhookNotifier) NotifyCreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
// Add to hook queue for created repo after session commit. // Add to hook queue for created repo after session commit.
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
@ -116,7 +120,7 @@ func (m *webhookNotifier) NotifyCreateRepository(ctx context.Context, doer, u *u
} }
func (m *webhookNotifier) NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) { func (m *webhookNotifier) NotifyDeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) {
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoDeleted, Action: api.HookRepoDeleted,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Organization: convert.ToUser(repo.MustOwner(ctx), nil), Organization: convert.ToUser(repo.MustOwner(ctx), nil),
@ -128,7 +132,7 @@ func (m *webhookNotifier) NotifyDeleteRepository(ctx context.Context, doer *user
func (m *webhookNotifier) NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { func (m *webhookNotifier) NotifyMigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) {
// Add to hook queue for created repo after session commit. // Add to hook queue for created repo after session commit.
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventRepository, &api.RepositoryPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
@ -159,7 +163,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *u
apiPullRequest.Action = api.HookIssueAssigned apiPullRequest.Action = api.HookIssueAssigned
} }
// Assignee comment triggers a webhook // Assignee comment triggers a webhook
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequestAssign, apiPullRequest); err != nil { if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestAssign, apiPullRequest); err != nil {
log.Error("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err) log.Error("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return return
} }
@ -177,7 +181,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *u
apiIssue.Action = api.HookIssueAssigned apiIssue.Action = api.HookIssueAssigned
} }
// Assignee comment triggers a webhook // Assignee comment triggers a webhook
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueAssign, apiIssue); err != nil { if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueAssign, apiIssue); err != nil {
log.Error("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err) log.Error("PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, removed, err)
return return
} }
@ -193,7 +197,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user
return return
} }
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
@ -206,7 +210,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, &api.IssuePayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
@ -245,7 +249,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *use
} else { } else {
apiPullRequest.Action = api.HookIssueReOpened apiPullRequest.Action = api.HookIssueReOpened
} }
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, apiPullRequest) err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, apiPullRequest)
} else { } else {
apiIssue := &api.IssuePayload{ apiIssue := &api.IssuePayload{
Index: issue.Index, Index: issue.Index,
@ -258,7 +262,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(ctx context.Context, doer *use
} else { } else {
apiIssue.Action = api.HookIssueReOpened apiIssue.Action = api.HookIssueReOpened
} }
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, apiIssue) err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, apiIssue)
} }
if err != nil { if err != nil {
log.Error("PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err) log.Error("PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
@ -276,7 +280,7 @@ func (m *webhookNotifier) NotifyNewIssue(ctx context.Context, issue *issues_mode
} }
mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo) mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, &api.IssuePayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{
Action: api.HookIssueOpened, Action: api.HookIssueOpened,
Index: issue.Index, Index: issue.Index,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
@ -302,7 +306,7 @@ func (m *webhookNotifier) NotifyNewPullRequest(ctx context.Context, pull *issues
} }
mode, _ := access_model.AccessLevel(ctx, pull.Issue.Poster, pull.Issue.Repo) mode, _ := access_model.AccessLevel(ctx, pull.Issue.Poster, pull.Issue.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pull.Issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: pull.Issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueOpened, Action: api.HookIssueOpened,
Index: pull.Issue.Index, Index: pull.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pull, nil), PullRequest: convert.ToAPIPullRequest(ctx, pull, nil),
@ -323,7 +327,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *us
var err error var err error
if issue.IsPull { if issue.IsPull {
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
@ -336,7 +340,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *us
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssues, &api.IssuePayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
@ -369,15 +373,15 @@ func (m *webhookNotifier) NotifyUpdateComment(ctx context.Context, doer *user_mo
return return
} }
var eventType webhook.HookEventType var eventType webhook_module.HookEventType
if c.Issue.IsPull { if c.Issue.IsPull {
eventType = webhook.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
} else { } else {
eventType = webhook.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
mode, _ := access_model.AccessLevel(ctx, doer, c.Issue.Repo) mode, _ := access_model.AccessLevel(ctx, doer, c.Issue.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentEdited, Action: api.HookIssueCommentEdited,
Issue: convert.ToAPIIssue(ctx, c.Issue), Issue: convert.ToAPIIssue(ctx, c.Issue),
Comment: convert.ToComment(c), Comment: convert.ToComment(c),
@ -397,15 +401,15 @@ func (m *webhookNotifier) NotifyUpdateComment(ctx context.Context, doer *user_mo
func (m *webhookNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, func (m *webhookNotifier) NotifyCreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository,
issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User,
) { ) {
var eventType webhook.HookEventType var eventType webhook_module.HookEventType
if issue.IsPull { if issue.IsPull {
eventType = webhook.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
} else { } else {
eventType = webhook.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
mode, _ := access_model.AccessLevel(ctx, doer, repo) mode, _ := access_model.AccessLevel(ctx, doer, repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentCreated, Action: api.HookIssueCommentCreated,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
Comment: convert.ToComment(comment), Comment: convert.ToComment(comment),
@ -434,15 +438,15 @@ func (m *webhookNotifier) NotifyDeleteComment(ctx context.Context, doer *user_mo
return return
} }
var eventType webhook.HookEventType var eventType webhook_module.HookEventType
if comment.Issue.IsPull { if comment.Issue.IsPull {
eventType = webhook.HookEventPullRequestComment eventType = webhook_module.HookEventPullRequestComment
} else { } else {
eventType = webhook.HookEventIssueComment eventType = webhook_module.HookEventIssueComment
} }
mode, _ := access_model.AccessLevel(ctx, doer, comment.Issue.Repo) mode, _ := access_model.AccessLevel(ctx, doer, comment.Issue.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{
Action: api.HookIssueCommentDeleted, Action: api.HookIssueCommentDeleted,
Issue: convert.ToAPIIssue(ctx, comment.Issue), Issue: convert.ToAPIIssue(ctx, comment.Issue),
Comment: convert.ToComment(comment), Comment: convert.ToComment(comment),
@ -456,7 +460,7 @@ func (m *webhookNotifier) NotifyDeleteComment(ctx context.Context, doer *user_mo
func (m *webhookNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { func (m *webhookNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
// Add to hook queue for created wiki page. // Add to hook queue for created wiki page.
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventWiki, &api.WikiPayload{
Action: api.HookWikiCreated, Action: api.HookWikiCreated,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
@ -469,7 +473,7 @@ func (m *webhookNotifier) NotifyNewWikiPage(ctx context.Context, doer *user_mode
func (m *webhookNotifier) NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { func (m *webhookNotifier) NotifyEditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) {
// Add to hook queue for edit wiki page. // Add to hook queue for edit wiki page.
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventWiki, &api.WikiPayload{
Action: api.HookWikiEdited, Action: api.HookWikiEdited,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
@ -482,7 +486,7 @@ func (m *webhookNotifier) NotifyEditWikiPage(ctx context.Context, doer *user_mod
func (m *webhookNotifier) NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) { func (m *webhookNotifier) NotifyDeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) {
// Add to hook queue for edit wiki page. // Add to hook queue for edit wiki page.
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventWiki, &api.WikiPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventWiki, &api.WikiPayload{
Action: api.HookWikiDeleted, Action: api.HookWikiDeleted,
Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner), Repository: convert.ToRepo(ctx, repo, perm.AccessModeOwner),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
@ -517,7 +521,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *use
log.Error("LoadIssue: %v", err) log.Error("LoadIssue: %v", err)
return return
} }
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequestLabel, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestLabel, &api.PullRequestPayload{
Action: api.HookIssueLabelUpdated, Action: api.HookIssueLabelUpdated,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
@ -525,7 +529,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(ctx context.Context, doer *use
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueLabel, &api.IssuePayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueLabel, &api.IssuePayload{
Action: api.HookIssueLabelUpdated, Action: api.HookIssueLabelUpdated,
Index: issue.Index, Index: issue.Index,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
@ -559,7 +563,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(ctx context.Context, doer *
log.Error("LoadIssue: %v", err) log.Error("LoadIssue: %v", err)
return return
} }
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequestMilestone, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequestMilestone, &api.PullRequestPayload{
Action: hookAction, Action: hookAction,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
@ -567,7 +571,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(ctx context.Context, doer *
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
err = webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventIssueMilestone, &api.IssuePayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssueMilestone, &api.IssuePayload{
Action: hookAction, Action: hookAction,
Index: issue.Index, Index: issue.Index,
Issue: convert.ToAPIIssue(ctx, issue), Issue: convert.ToAPIIssue(ctx, issue),
@ -588,7 +592,7 @@ func (m *webhookNotifier) NotifyPushCommits(ctx context.Context, pusher *user_mo
return return
} }
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventPush, &api.PushPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{
Ref: opts.RefFullName, Ref: opts.RefFullName,
Before: opts.OldCommitID, Before: opts.OldCommitID,
After: opts.NewCommitID, After: opts.NewCommitID,
@ -641,7 +645,7 @@ func (*webhookNotifier) NotifyMergePullRequest(ctx context.Context, doer *user_m
Action: api.HookIssueClosed, Action: api.HookIssueClosed,
} }
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pr.Issue.Repo}, webhook.HookEventPullRequest, apiPullRequest); err != nil { if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequest, apiPullRequest); err != nil {
log.Error("PrepareWebhooks: %v", err) log.Error("PrepareWebhooks: %v", err)
} }
} }
@ -655,7 +659,7 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Contex
issue := pr.Issue issue := pr.Issue
mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo) mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: issue.Repo}, webhook.HookEventPullRequest, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
Changes: &api.ChangesPayload{ Changes: &api.ChangesPayload{
@ -672,15 +676,15 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(ctx context.Contex
} }
func (m *webhookNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { func (m *webhookNotifier) NotifyPullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) {
var reviewHookType webhook.HookEventType var reviewHookType webhook_module.HookEventType
switch review.Type { switch review.Type {
case issues_model.ReviewTypeApprove: case issues_model.ReviewTypeApprove:
reviewHookType = webhook.HookEventPullRequestReviewApproved reviewHookType = webhook_module.HookEventPullRequestReviewApproved
case issues_model.ReviewTypeComment: case issues_model.ReviewTypeComment:
reviewHookType = webhook.HookEventPullRequestComment reviewHookType = webhook_module.HookEventPullRequestComment
case issues_model.ReviewTypeReject: case issues_model.ReviewTypeReject:
reviewHookType = webhook.HookEventPullRequestReviewRejected reviewHookType = webhook_module.HookEventPullRequestReviewRejected
default: default:
// unsupported review webhook type here // unsupported review webhook type here
log.Error("Unsupported review webhook type") log.Error("Unsupported review webhook type")
@ -697,7 +701,7 @@ func (m *webhookNotifier) NotifyPullRequestReview(ctx context.Context, pr *issue
log.Error("models.AccessLevel: %v", err) log.Error("models.AccessLevel: %v", err)
return return
} }
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: review.Issue.Repo}, reviewHookType, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: review.Issue.Repo}, reviewHookType, &api.PullRequestPayload{
Action: api.HookIssueReviewed, Action: api.HookIssueReviewed,
Index: review.Issue.Index, Index: review.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
@ -717,7 +721,7 @@ func (m *webhookNotifier) NotifyCreateRef(ctx context.Context, pusher *user_mode
apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone)
refName := git.RefEndName(refFullName) refName := git.RefEndName(refFullName)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventCreate, &api.CreatePayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventCreate, &api.CreatePayload{
Ref: refName, Ref: refName,
Sha: refID, Sha: refID,
RefType: refType, RefType: refType,
@ -738,7 +742,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(ctx context.Context, doe
return return
} }
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: pr.Issue.Repo}, webhook.HookEventPullRequestSync, &api.PullRequestPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: pr.Issue.Repo}, webhook_module.HookEventPullRequestSync, &api.PullRequestPayload{
Action: api.HookIssueSynchronized, Action: api.HookIssueSynchronized,
Index: pr.Issue.Index, Index: pr.Issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, pr, nil), PullRequest: convert.ToAPIPullRequest(ctx, pr, nil),
@ -754,7 +758,7 @@ func (m *webhookNotifier) NotifyDeleteRef(ctx context.Context, pusher *user_mode
apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone) apiRepo := convert.ToRepo(ctx, repo, perm.AccessModeNone)
refName := git.RefEndName(refFullName) refName := git.RefEndName(refFullName)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventDelete, &api.DeletePayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventDelete, &api.DeletePayload{
Ref: refName, Ref: refName,
RefType: refType, RefType: refType,
PusherType: api.PusherTypeUser, PusherType: api.PusherTypeUser,
@ -772,7 +776,7 @@ func sendReleaseHook(ctx context.Context, doer *user_model.User, rel *repo_model
} }
mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo) mode, _ := access_model.AccessLevel(ctx, doer, rel.Repo)
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: rel.Repo}, webhook.HookEventRelease, &api.ReleasePayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: rel.Repo}, webhook_module.HookEventRelease, &api.ReleasePayload{
Action: action, Action: action,
Release: convert.ToRelease(rel), Release: convert.ToRelease(rel),
Repository: convert.ToRepo(ctx, rel.Repo, mode), Repository: convert.ToRepo(ctx, rel.Repo, mode),
@ -802,7 +806,7 @@ func (m *webhookNotifier) NotifySyncPushCommits(ctx context.Context, pusher *use
return return
} }
if err := webhook_services.PrepareWebhooks(ctx, webhook_services.EventSource{Repository: repo}, webhook.HookEventPush, &api.PushPayload{ if err := PrepareWebhooks(ctx, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{
Ref: opts.RefFullName, Ref: opts.RefFullName,
Before: opts.OldCommitID, Before: opts.OldCommitID,
After: opts.NewCommitID, After: opts.NewCommitID,
@ -835,7 +839,7 @@ func (m *webhookNotifier) NotifyPackageDelete(ctx context.Context, doer *user_mo
} }
func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_model.PackageDescriptor, action api.HookPackageAction) { func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_model.PackageDescriptor, action api.HookPackageAction) {
source := webhook_services.EventSource{ source := EventSource{
Repository: pd.Repository, Repository: pd.Repository,
Owner: pd.Owner, Owner: pd.Owner,
} }
@ -846,7 +850,7 @@ func notifyPackage(ctx context.Context, sender *user_model.User, pd *packages_mo
return return
} }
if err := webhook_services.PrepareWebhooks(ctx, source, webhook.HookEventPackage, &api.PackagePayload{ if err := PrepareWebhooks(ctx, source, webhook_module.HookEventPackage, &api.PackagePayload{
Action: action, Action: action,
Package: apiPackage, Package: apiPackage,
Sender: convert.ToUser(sender, nil), Sender: convert.ToUser(sender, nil),

View File

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -20,7 +21,7 @@ type (
} `json:"repository"` } `json:"repository"`
} }
// PackagistMeta contains the meta data for the webhook // PackagistMeta contains the metadata for the webhook
PackagistMeta struct { PackagistMeta struct {
Username string `json:"username"` Username string `json:"username"`
APIToken string `json:"api_token"` APIToken string `json:"api_token"`
@ -49,62 +50,62 @@ func (f *PackagistPayload) JSONPayload() ([]byte, error) {
var _ PayloadConvertor = &PackagistPayload{} var _ PayloadConvertor = &PackagistPayload{}
// Create implements PayloadConvertor Create method // Create implements PayloadConvertor Create method
func (f *PackagistPayload) Create(p *api.CreatePayload) (api.Payloader, error) { func (f *PackagistPayload) Create(_ *api.CreatePayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Delete implements PayloadConvertor Delete method // Delete implements PayloadConvertor Delete method
func (f *PackagistPayload) Delete(p *api.DeletePayload) (api.Payloader, error) { func (f *PackagistPayload) Delete(_ *api.DeletePayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Fork implements PayloadConvertor Fork method // Fork implements PayloadConvertor Fork method
func (f *PackagistPayload) Fork(p *api.ForkPayload) (api.Payloader, error) { func (f *PackagistPayload) Fork(_ *api.ForkPayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Push implements PayloadConvertor Push method // Push implements PayloadConvertor Push method
func (f *PackagistPayload) Push(p *api.PushPayload) (api.Payloader, error) { func (f *PackagistPayload) Push(_ *api.PushPayload) (api.Payloader, error) {
return f, nil return f, nil
} }
// Issue implements PayloadConvertor Issue method // Issue implements PayloadConvertor Issue method
func (f *PackagistPayload) Issue(p *api.IssuePayload) (api.Payloader, error) { func (f *PackagistPayload) Issue(_ *api.IssuePayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// IssueComment implements PayloadConvertor IssueComment method // IssueComment implements PayloadConvertor IssueComment method
func (f *PackagistPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) { func (f *PackagistPayload) IssueComment(_ *api.IssueCommentPayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// PullRequest implements PayloadConvertor PullRequest method // PullRequest implements PayloadConvertor PullRequest method
func (f *PackagistPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) { func (f *PackagistPayload) PullRequest(_ *api.PullRequestPayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (f *PackagistPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (f *PackagistPayload) Review(_ *api.PullRequestPayload, _ webhook_module.HookEventType) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Repository implements PayloadConvertor Repository method // Repository implements PayloadConvertor Repository method
func (f *PackagistPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) { func (f *PackagistPayload) Repository(_ *api.RepositoryPayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Wiki implements PayloadConvertor Wiki method // Wiki implements PayloadConvertor Wiki method
func (f *PackagistPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) { func (f *PackagistPayload) Wiki(_ *api.WikiPayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// Release implements PayloadConvertor Release method // Release implements PayloadConvertor Release method
func (f *PackagistPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { func (f *PackagistPayload) Release(_ *api.ReleasePayload) (api.Payloader, error) {
return nil, nil return nil, nil
} }
// GetPackagistPayload converts a packagist webhook into a PackagistPayload // GetPackagistPayload converts a packagist webhook into a PackagistPayload
func GetPackagistPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetPackagistPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
s := new(PackagistPayload) s := new(PackagistPayload)
packagist := &PackagistMeta{} packagist := &PackagistMeta{}

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -101,7 +101,7 @@ func TestPackagistPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(PackagistPayload) d := new(PackagistPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.Nil(t, pl) require.Nil(t, pl)
}) })

View File

@ -4,8 +4,8 @@
package webhook package webhook
import ( import (
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
// PayloadConvertor defines the interface to convert system webhook payload to external payload // PayloadConvertor defines the interface to convert system webhook payload to external payload
@ -18,40 +18,40 @@ type PayloadConvertor interface {
IssueComment(*api.IssueCommentPayload) (api.Payloader, error) IssueComment(*api.IssueCommentPayload) (api.Payloader, error)
Push(*api.PushPayload) (api.Payloader, error) Push(*api.PushPayload) (api.Payloader, error)
PullRequest(*api.PullRequestPayload) (api.Payloader, error) PullRequest(*api.PullRequestPayload) (api.Payloader, error)
Review(*api.PullRequestPayload, webhook_model.HookEventType) (api.Payloader, error) Review(*api.PullRequestPayload, webhook_module.HookEventType) (api.Payloader, error)
Repository(*api.RepositoryPayload) (api.Payloader, error) Repository(*api.RepositoryPayload) (api.Payloader, error)
Release(*api.ReleasePayload) (api.Payloader, error) Release(*api.ReleasePayload) (api.Payloader, error)
Wiki(*api.WikiPayload) (api.Payloader, error) Wiki(*api.WikiPayload) (api.Payloader, error)
} }
func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_model.HookEventType) (api.Payloader, error) { func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module.HookEventType) (api.Payloader, error) {
switch event { switch event {
case webhook_model.HookEventCreate: case webhook_module.HookEventCreate:
return s.Create(p.(*api.CreatePayload)) return s.Create(p.(*api.CreatePayload))
case webhook_model.HookEventDelete: case webhook_module.HookEventDelete:
return s.Delete(p.(*api.DeletePayload)) return s.Delete(p.(*api.DeletePayload))
case webhook_model.HookEventFork: case webhook_module.HookEventFork:
return s.Fork(p.(*api.ForkPayload)) return s.Fork(p.(*api.ForkPayload))
case webhook_model.HookEventIssues, webhook_model.HookEventIssueAssign, webhook_model.HookEventIssueLabel, webhook_model.HookEventIssueMilestone: case webhook_module.HookEventIssues, webhook_module.HookEventIssueAssign, webhook_module.HookEventIssueLabel, webhook_module.HookEventIssueMilestone:
return s.Issue(p.(*api.IssuePayload)) return s.Issue(p.(*api.IssuePayload))
case webhook_model.HookEventIssueComment, webhook_model.HookEventPullRequestComment: case webhook_module.HookEventIssueComment, webhook_module.HookEventPullRequestComment:
pl, ok := p.(*api.IssueCommentPayload) pl, ok := p.(*api.IssueCommentPayload)
if ok { if ok {
return s.IssueComment(pl) return s.IssueComment(pl)
} }
return s.PullRequest(p.(*api.PullRequestPayload)) return s.PullRequest(p.(*api.PullRequestPayload))
case webhook_model.HookEventPush: case webhook_module.HookEventPush:
return s.Push(p.(*api.PushPayload)) return s.Push(p.(*api.PushPayload))
case webhook_model.HookEventPullRequest, webhook_model.HookEventPullRequestAssign, webhook_model.HookEventPullRequestLabel, case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel,
webhook_model.HookEventPullRequestMilestone, webhook_model.HookEventPullRequestSync: webhook_module.HookEventPullRequestMilestone, webhook_module.HookEventPullRequestSync:
return s.PullRequest(p.(*api.PullRequestPayload)) return s.PullRequest(p.(*api.PullRequestPayload))
case webhook_model.HookEventPullRequestReviewApproved, webhook_model.HookEventPullRequestReviewRejected, webhook_model.HookEventPullRequestReviewComment: case webhook_module.HookEventPullRequestReviewApproved, webhook_module.HookEventPullRequestReviewRejected, webhook_module.HookEventPullRequestReviewComment:
return s.Review(p.(*api.PullRequestPayload), event) return s.Review(p.(*api.PullRequestPayload), event)
case webhook_model.HookEventRepository: case webhook_module.HookEventRepository:
return s.Repository(p.(*api.RepositoryPayload)) return s.Repository(p.(*api.RepositoryPayload))
case webhook_model.HookEventRelease: case webhook_module.HookEventRelease:
return s.Release(p.(*api.ReleasePayload)) return s.Release(p.(*api.ReleasePayload))
case webhook_model.HookEventWiki: case webhook_module.HookEventWiki:
return s.Wiki(p.(*api.WikiPayload)) return s.Wiki(p.(*api.WikiPayload))
} }
return s, nil return s, nil

View File

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
// SlackMeta contains the slack metadata // SlackMeta contains the slack metadata
@ -231,7 +232,7 @@ func (s *SlackPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, er
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (s *SlackPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (s *SlackPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title) title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index) titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
@ -278,7 +279,7 @@ func (s *SlackPayload) createPayload(text string, attachments []SlackAttachment)
} }
// GetSlackPayload converts a slack webhook into a SlackPayload // GetSlackPayload converts a slack webhook into a SlackPayload
func GetSlackPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetSlackPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
s := new(SlackPayload) s := new(SlackPayload)
slack := &SlackMeta{} slack := &SlackMeta{}

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -124,7 +124,7 @@ func TestSlackPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(SlackPayload) d := new(SlackPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &SlackPayload{}, pl) require.IsType(t, &SlackPayload{}, pl)

View File

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -140,7 +141,7 @@ func (t *TelegramPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader,
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (t *TelegramPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (t *TelegramPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
var text, attachmentText string var text, attachmentText string
switch p.Action { switch p.Action {
case api.HookIssueReviewed: case api.HookIssueReviewed:
@ -185,7 +186,7 @@ func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error)
} }
// GetTelegramPayload converts a telegram webhook into a TelegramPayload // GetTelegramPayload converts a telegram webhook into a TelegramPayload
func GetTelegramPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetTelegramPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
return convertPayloader(new(TelegramPayload), p, event) return convertPayloader(new(TelegramPayload), p, event)
} }

View File

@ -6,8 +6,8 @@ package webhook
import ( import (
"testing" "testing"
webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -124,7 +124,7 @@ func TestTelegramPayload(t *testing.T) {
p.Action = api.HookIssueReviewed p.Action = api.HookIssueReviewed
d := new(TelegramPayload) d := new(TelegramPayload)
pl, err := d.Review(p, webhook_model.HookEventPullRequestReviewApproved) pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, pl) require.NotNil(t, pl)
require.IsType(t, &TelegramPayload{}, pl) require.IsType(t, &TelegramPayload{}, pl)

View File

@ -18,62 +18,58 @@ import (
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/gobwas/glob" "github.com/gobwas/glob"
) )
type webhook struct { type webhook struct {
name webhook_model.HookType name webhook_module.HookType
payloadCreator func(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) payloadCreator func(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error)
} }
var webhooks = map[webhook_model.HookType]*webhook{ var webhooks = map[webhook_module.HookType]*webhook{
webhook_model.SLACK: { webhook_module.SLACK: {
name: webhook_model.SLACK, name: webhook_module.SLACK,
payloadCreator: GetSlackPayload, payloadCreator: GetSlackPayload,
}, },
webhook_model.DISCORD: { webhook_module.DISCORD: {
name: webhook_model.DISCORD, name: webhook_module.DISCORD,
payloadCreator: GetDiscordPayload, payloadCreator: GetDiscordPayload,
}, },
webhook_model.DINGTALK: { webhook_module.DINGTALK: {
name: webhook_model.DINGTALK, name: webhook_module.DINGTALK,
payloadCreator: GetDingtalkPayload, payloadCreator: GetDingtalkPayload,
}, },
webhook_model.TELEGRAM: { webhook_module.TELEGRAM: {
name: webhook_model.TELEGRAM, name: webhook_module.TELEGRAM,
payloadCreator: GetTelegramPayload, payloadCreator: GetTelegramPayload,
}, },
webhook_model.MSTEAMS: { webhook_module.MSTEAMS: {
name: webhook_model.MSTEAMS, name: webhook_module.MSTEAMS,
payloadCreator: GetMSTeamsPayload, payloadCreator: GetMSTeamsPayload,
}, },
webhook_model.FEISHU: { webhook_module.FEISHU: {
name: webhook_model.FEISHU, name: webhook_module.FEISHU,
payloadCreator: GetFeishuPayload, payloadCreator: GetFeishuPayload,
}, },
webhook_model.MATRIX: { webhook_module.MATRIX: {
name: webhook_model.MATRIX, name: webhook_module.MATRIX,
payloadCreator: GetMatrixPayload, payloadCreator: GetMatrixPayload,
}, },
webhook_model.WECHATWORK: { webhook_module.WECHATWORK: {
name: webhook_model.WECHATWORK, name: webhook_module.WECHATWORK,
payloadCreator: GetWechatworkPayload, payloadCreator: GetWechatworkPayload,
}, },
webhook_model.PACKAGIST: { webhook_module.PACKAGIST: {
name: webhook_model.PACKAGIST, name: webhook_module.PACKAGIST,
payloadCreator: GetPackagistPayload, payloadCreator: GetPackagistPayload,
}, },
} }
// RegisterWebhook registers a webhook
func RegisterWebhook(name string, webhook *webhook) {
webhooks[name] = 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_model.GITEA || name == webhook_model.GOGS { if name == webhook_module.GITEA || name == webhook_module.GOGS {
return true return true
} }
_, ok := webhooks[name] _, ok := webhooks[name]
@ -157,7 +153,7 @@ func checkBranch(w *webhook_model.Webhook, branch string) bool {
} }
// PrepareWebhook creates a hook task and enqueues it for processing // PrepareWebhook creates a hook task and enqueues it for processing
func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook_model.HookEventType, p api.Payloader) error { func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook_module.HookEventType, p api.Payloader) error {
// Skip sending if webhooks are disabled. // Skip sending if webhooks are disabled.
if setting.DisableWebhooks { if setting.DisableWebhooks {
return nil return nil
@ -176,7 +172,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_model.GITEA && w.Type != webhook_model.GOGS && w.Type != webhook_module.GITEA && w.Type != webhook_module.GOGS &&
len(pushEvent.Commits) == 0 { len(pushEvent.Commits) == 0 {
return nil return nil
} }
@ -215,7 +211,7 @@ func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook
} }
// PrepareWebhooks adds new webhooks to task queue for given payload. // PrepareWebhooks adds new webhooks to task queue for given payload.
func PrepareWebhooks(ctx context.Context, source EventSource, event webhook_model.HookEventType, p api.Payloader) error { func PrepareWebhooks(ctx context.Context, source EventSource, event webhook_module.HookEventType, p api.Payloader) error {
owner := source.Owner owner := source.Owner
var ws []*webhook_model.Webhook var ws []*webhook_model.Webhook

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
webhook_model "code.gitea.io/gitea/models/webhook" webhook_model "code.gitea.io/gitea/models/webhook"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -32,12 +33,12 @@ func TestPrepareWebhooks(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
hookTasks := []*webhook_model.HookTask{ hookTasks := []*webhook_model.HookTask{
{HookID: 1, EventType: webhook_model.HookEventPush}, {HookID: 1, EventType: webhook_module.HookEventPush},
} }
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertNotExistsBean(t, hookTask) unittest.AssertNotExistsBean(t, hookTask)
} }
assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_model.HookEventPush, &api.PushPayload{Commits: []*api.PayloadCommit{{}}})) assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Commits: []*api.PayloadCommit{{}}}))
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertExistsAndLoadBean(t, hookTask) unittest.AssertExistsAndLoadBean(t, hookTask)
} }
@ -48,13 +49,13 @@ func TestPrepareWebhooksBranchFilterMatch(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
hookTasks := []*webhook_model.HookTask{ hookTasks := []*webhook_model.HookTask{
{HookID: 4, EventType: webhook_model.HookEventPush}, {HookID: 4, EventType: webhook_module.HookEventPush},
} }
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertNotExistsBean(t, hookTask) unittest.AssertNotExistsBean(t, hookTask)
} }
// this test also ensures that * doesn't handle / in any special way (like shell would) // this test also ensures that * doesn't handle / in any special way (like shell would)
assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_model.HookEventPush, &api.PushPayload{Ref: "refs/heads/feature/7791", Commits: []*api.PayloadCommit{{}}})) assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/feature/7791", Commits: []*api.PayloadCommit{{}}}))
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertExistsAndLoadBean(t, hookTask) unittest.AssertExistsAndLoadBean(t, hookTask)
} }
@ -65,12 +66,12 @@ func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
hookTasks := []*webhook_model.HookTask{ hookTasks := []*webhook_model.HookTask{
{HookID: 4, EventType: webhook_model.HookEventPush}, {HookID: 4, EventType: webhook_module.HookEventPush},
} }
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertNotExistsBean(t, hookTask) unittest.AssertNotExistsBean(t, hookTask)
} }
assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_model.HookEventPush, &api.PushPayload{Ref: "refs/heads/fix_weird_bug"})) assert.NoError(t, PrepareWebhooks(db.DefaultContext, EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/fix_weird_bug"}))
for _, hookTask := range hookTasks { for _, hookTask := range hookTasks {
unittest.AssertNotExistsBean(t, hookTask) unittest.AssertNotExistsBean(t, hookTask)

View File

@ -7,10 +7,10 @@ import (
"fmt" "fmt"
"strings" "strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
) )
type ( type (
@ -135,7 +135,7 @@ func (f *WechatworkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloade
} }
// Review implements PayloadConvertor Review method // Review implements PayloadConvertor Review method
func (f *WechatworkPayload) Review(p *api.PullRequestPayload, event webhook_model.HookEventType) (api.Payloader, error) { func (f *WechatworkPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
var text, title string var text, title string
switch p.Action { switch p.Action {
case api.HookIssueReviewed: case api.HookIssueReviewed:
@ -180,6 +180,6 @@ func (f *WechatworkPayload) Release(p *api.ReleasePayload) (api.Payloader, error
} }
// GetWechatworkPayload GetWechatworkPayload converts a ding talk webhook into a WechatworkPayload // GetWechatworkPayload GetWechatworkPayload converts a ding talk webhook into a WechatworkPayload
func GetWechatworkPayload(p api.Payloader, event webhook_model.HookEventType, meta string) (api.Payloader, error) { func GetWechatworkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
return convertPayloader(new(WechatworkPayload), p, event) return convertPayloader(new(WechatworkPayload), p, event)
} }

View File

@ -413,7 +413,7 @@
<div class="df sb ac"> <div class="df sb ac">
<div class="due-date tooltip {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-content="{{.locale.Tr "repo.issues.due_date_overdue"}}"{{end}}> <div class="due-date tooltip {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-content="{{.locale.Tr "repo.issues.due_date_overdue"}}"{{end}}>
{{svg "octicon-calendar" 16 "mr-3"}} {{svg "octicon-calendar" 16 "mr-3"}}
<time data-format="date" datetime="{{.Issue.DeadlineUnix.FormatLong}}">{{.Issue.DeadlineUnix.FormatDate}}</time> <time data-format="date" datetime="{{.Issue.DeadlineUnix.FormatDate}}">{{.Issue.DeadlineUnix.FormatDate}}</time>
</div> </div>
<div> <div>
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}} {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}