mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-29 15:28:38 +00:00
fix
This commit is contained in:
parent
39718b2ee3
commit
9682610d9a
@ -1,7 +1,7 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_24
|
||||
package v1_25
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
@ -9,8 +9,8 @@ import (
|
||||
|
||||
func AddWebhookPayloadOptimizationColumns(x *xorm.Engine) error {
|
||||
type Webhook struct {
|
||||
ExcludeFilesLimit int `xorm:"exclude_files_limit NOT NULL DEFAULT 0"`
|
||||
ExcludeCommitsLimit int `xorm:"exclude_commits_limit NOT NULL DEFAULT 0"`
|
||||
ExcludeFilesLimit int `xorm:"exclude_files_limit NOT NULL DEFAULT -1"`
|
||||
ExcludeCommitsLimit int `xorm:"exclude_commits_limit NOT NULL DEFAULT -1"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(
|
||||
xorm.SyncOptions{
|
@ -140,8 +140,8 @@ type Webhook struct {
|
||||
HeaderAuthorizationEncrypted string `xorm:"TEXT"`
|
||||
|
||||
// Payload size optimization options
|
||||
ExcludeFilesLimit int `xorm:"exclude_files_limit"` // Limit number of file changes in commit payloads, 0 means unlimited
|
||||
ExcludeCommitsLimit int `xorm:"exclude_commits_limit"` // Limit number of commits in push payloads, 0 means unlimited
|
||||
ExcludeFilesLimit int `xorm:"exclude_files_limit"` // -1: do not trim, 0: trim all (none kept), >0: keep N file changes in commit payloads
|
||||
ExcludeCommitsLimit int `xorm:"exclude_commits_limit"` // -1: do not trim, 0: trim all (none kept), >0: keep N commits in push payloads
|
||||
|
||||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
||||
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
||||
|
@ -2426,9 +2426,9 @@ settings.branch_filter = Branch filter
|
||||
settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. If empty or <code>*</code>, events for all branches are reported. See <a href="%[1]s">%[2]s</a> documentation for syntax. Examples: <code>master</code>, <code>{master,release*}</code>.
|
||||
settings.payload_optimization = Payload Size Optimization
|
||||
settings.exclude_files_limit = Limit file changes
|
||||
settings.exclude_files_limit_desc = Limit the number of file changes (added, removed, modified) included in each commit payload. 0 means unlimited.
|
||||
settings.exclude_files_limit_desc = -1: do not trim, 0: trim all (none kept), >0: keep N file changes
|
||||
settings.exclude_commits_limit = Limit commits
|
||||
settings.exclude_commits_limit_desc = Limit the number of commits included in push payloads. 0 means unlimited.
|
||||
settings.exclude_commits_limit_desc = -1: do not trim, 0: trim all (none kept), >0: keep N commits
|
||||
settings.authorization_header = Authorization Header
|
||||
settings.authorization_header_desc = Will be included as authorization header for requests when present. Examples: %s.
|
||||
settings.active = Active
|
||||
@ -3287,7 +3287,7 @@ auths.tip.github = Register a new OAuth application on %s
|
||||
auths.tip.gitlab_new = Register a new application on %s
|
||||
auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at %s
|
||||
auths.tip.openid_connect = Use the OpenID Connect Discovery URL "https://{server}/.well-known/openid-configuration" to specify the endpoints
|
||||
auths.tip.twitter = Go to %s, create an application and ensure that the “Allow this application to be used to Sign in with Twitter” option is enabled
|
||||
auths.tip.twitter = Go to %s, create an application and ensure that the "Allow this application to be used to Sign in with Twitter" option is enabled
|
||||
auths.tip.discord = Register a new application on %s
|
||||
auths.tip.gitea = Register a new OAuth2 application. Guide can be found at %s
|
||||
auths.tip.yandex = Create a new application at %s. Select following permissions from the "Yandex.Passport API" section: "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"
|
||||
|
@ -240,8 +240,8 @@ type WebhookForm struct {
|
||||
AuthorizationHeader string
|
||||
Secret string
|
||||
// Payload size optimization options
|
||||
ExcludeFilesLimit int // Limit number of file changes in commit payloads, 0 means unlimited
|
||||
ExcludeCommitsLimit int // Limit number of commits in push payloads, 0 means unlimited
|
||||
ExcludeFilesLimit int // -1: do not trim, 0: trim all (none kept), >0: keep N file changes in commit payloads
|
||||
ExcludeCommitsLimit int // -1: do not trim, 0: trim all (none kept), >0: keep N commits in push payloads
|
||||
}
|
||||
|
||||
// PushOnly if the hook will be triggered when push
|
||||
|
@ -657,47 +657,76 @@ func (m *webhookNotifier) applyWebhookPayloadOptimizations(ctx context.Context,
|
||||
}
|
||||
|
||||
// Check if any webhook has payload optimization options enabled
|
||||
hasFilesLimit := 0
|
||||
hasCommitsLimit := 0
|
||||
hasFilesLimit := -1
|
||||
hasCommitsLimit := -1
|
||||
for _, webhook := range webhooks {
|
||||
if webhook.HasEvent(webhook_module.HookEventPush) {
|
||||
if webhook.ExcludeFilesLimit > 0 && (hasFilesLimit == 0 || webhook.ExcludeFilesLimit < hasFilesLimit) {
|
||||
if webhook.ExcludeFilesLimit >= 0 && (hasFilesLimit == -1 || webhook.ExcludeFilesLimit < hasFilesLimit) {
|
||||
hasFilesLimit = webhook.ExcludeFilesLimit
|
||||
}
|
||||
if webhook.ExcludeCommitsLimit > 0 && (hasCommitsLimit == 0 || webhook.ExcludeCommitsLimit < hasCommitsLimit) {
|
||||
if webhook.ExcludeCommitsLimit >= 0 && (hasCommitsLimit == -1 || webhook.ExcludeCommitsLimit < hasCommitsLimit) {
|
||||
hasCommitsLimit = webhook.ExcludeCommitsLimit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply payload optimizations based on webhook configurations
|
||||
if hasFilesLimit > 0 {
|
||||
// -1 not trim, 0 trim all (none kept), >0 trim to N commits
|
||||
if hasFilesLimit != -1 {
|
||||
for _, commit := range apiCommits {
|
||||
if commit.Added != nil && len(commit.Added) > hasFilesLimit {
|
||||
commit.Added = commit.Added[:hasFilesLimit]
|
||||
if commit.Added != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
commit.Added = nil
|
||||
} else if hasFilesLimit > 0 && len(commit.Added) > hasFilesLimit {
|
||||
commit.Added = commit.Added[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
if commit.Removed != nil && len(commit.Removed) > hasFilesLimit {
|
||||
commit.Removed = commit.Removed[:hasFilesLimit]
|
||||
if commit.Removed != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
commit.Removed = nil
|
||||
} else if hasFilesLimit > 0 && len(commit.Removed) > hasFilesLimit {
|
||||
commit.Removed = commit.Removed[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
if commit.Modified != nil && len(commit.Modified) > hasFilesLimit {
|
||||
commit.Modified = commit.Modified[:hasFilesLimit]
|
||||
if commit.Modified != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
commit.Modified = nil
|
||||
} else if hasFilesLimit > 0 && len(commit.Modified) > hasFilesLimit {
|
||||
commit.Modified = commit.Modified[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
}
|
||||
if apiHeadCommit != nil {
|
||||
if apiHeadCommit.Added != nil && len(apiHeadCommit.Added) > hasFilesLimit {
|
||||
apiHeadCommit.Added = apiHeadCommit.Added[:hasFilesLimit]
|
||||
if apiHeadCommit.Added != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
apiHeadCommit.Added = nil
|
||||
} else if hasFilesLimit > 0 && len(apiHeadCommit.Added) > hasFilesLimit {
|
||||
apiHeadCommit.Added = apiHeadCommit.Added[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
if apiHeadCommit.Removed != nil && len(apiHeadCommit.Removed) > hasFilesLimit {
|
||||
apiHeadCommit.Removed = apiHeadCommit.Removed[:hasFilesLimit]
|
||||
if apiHeadCommit.Removed != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
apiHeadCommit.Removed = nil
|
||||
} else if hasFilesLimit > 0 && len(apiHeadCommit.Removed) > hasFilesLimit {
|
||||
apiHeadCommit.Removed = apiHeadCommit.Removed[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
if apiHeadCommit.Modified != nil && len(apiHeadCommit.Modified) > hasFilesLimit {
|
||||
apiHeadCommit.Modified = apiHeadCommit.Modified[:hasFilesLimit]
|
||||
if apiHeadCommit.Modified != nil {
|
||||
if hasFilesLimit == 0 {
|
||||
apiHeadCommit.Modified = nil
|
||||
} else if hasFilesLimit > 0 && len(apiHeadCommit.Modified) > hasFilesLimit {
|
||||
apiHeadCommit.Modified = apiHeadCommit.Modified[:hasFilesLimit]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hasCommitsLimit > 0 && len(apiCommits) > hasCommitsLimit {
|
||||
apiCommits = apiCommits[:hasCommitsLimit]
|
||||
if hasCommitsLimit != -1 {
|
||||
if hasCommitsLimit == 0 {
|
||||
apiCommits = nil
|
||||
} else if hasCommitsLimit > 0 && len(apiCommits) > hasCommitsLimit {
|
||||
apiCommits = apiCommits[:hasCommitsLimit]
|
||||
}
|
||||
}
|
||||
|
||||
return apiCommits, apiHeadCommit
|
||||
|
@ -98,10 +98,17 @@ func TestWebhookPayloadOptimization(t *testing.T) {
|
||||
var optimizedCommits []*api.PayloadCommit
|
||||
var optimizedHeadCommit *api.PayloadCommit
|
||||
|
||||
// Create a test repository
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
|
||||
// Create a webhook with file limit = 1
|
||||
// Clean up all webhooks for this repo to avoid interference
|
||||
webhooks, err := db.Find[webhook_model.Webhook](db.DefaultContext, webhook_model.ListWebhookOptions{RepoID: repo.ID})
|
||||
assert.NoError(t, err)
|
||||
for _, wh := range webhooks {
|
||||
err = webhook_model.DeleteWebhookByID(db.DefaultContext, wh.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// Case: -1 (no trimming)
|
||||
webhook := &webhook_model.Webhook{
|
||||
RepoID: repo.ID,
|
||||
URL: "http://example.com/webhook",
|
||||
@ -110,21 +117,19 @@ func TestWebhookPayloadOptimization(t *testing.T) {
|
||||
Secret: "secret",
|
||||
IsActive: true,
|
||||
Type: webhook_module.GITEA,
|
||||
ExcludeFilesLimit: 1,
|
||||
ExcludeCommitsLimit: 0,
|
||||
ExcludeFilesLimit: -1,
|
||||
ExcludeCommitsLimit: -1,
|
||||
HookEvent: &webhook_module.HookEvent{
|
||||
PushOnly: true,
|
||||
},
|
||||
}
|
||||
|
||||
err := webhook.UpdateEvent()
|
||||
err = webhook.UpdateEvent()
|
||||
assert.NoError(t, err)
|
||||
err = webhook_model.CreateWebhook(db.DefaultContext, webhook)
|
||||
assert.NoError(t, err)
|
||||
assert.NotZero(t, webhook.ID)
|
||||
|
||||
// Test payload optimization: should truncate to 1 file per field
|
||||
notifier := &webhookNotifier{}
|
||||
apiCommits := []*api.PayloadCommit{
|
||||
{
|
||||
ID: "abc123",
|
||||
@ -148,52 +153,22 @@ func TestWebhookPayloadOptimization(t *testing.T) {
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
}
|
||||
optimizedCommits, _ = notifier.applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedCommits[0].Added)
|
||||
assert.Equal(t, []string{"oldfile.txt"}, optimizedCommits[0].Removed)
|
||||
assert.Equal(t, []string{"modified.txt"}, optimizedCommits[0].Modified)
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedCommits[1].Added)
|
||||
assert.Equal(t, []string{}, optimizedCommits[1].Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedCommits[1].Modified)
|
||||
|
||||
_, optimizedHeadCommit = notifier.applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedHeadCommit.Added)
|
||||
assert.Equal(t, []string{}, optimizedHeadCommit.Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedHeadCommit.Modified)
|
||||
|
||||
// Test with commit limit = 1
|
||||
webhook.ExcludeFilesLimit = 0
|
||||
webhook.ExcludeCommitsLimit = 1
|
||||
err = webhook_model.UpdateWebhook(db.DefaultContext, webhook)
|
||||
assert.NoError(t, err)
|
||||
apiCommits = []*api.PayloadCommit{
|
||||
{
|
||||
ID: "abc123",
|
||||
Message: "Test commit",
|
||||
Added: []string{"file1.txt", "file2.txt"},
|
||||
Removed: []string{"oldfile.txt"},
|
||||
Modified: []string{"modified.txt"},
|
||||
},
|
||||
{
|
||||
ID: "def456",
|
||||
Message: "Another commit",
|
||||
Added: []string{"file3.txt"},
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
},
|
||||
optimizedCommits, optimizedHeadCommit = (&webhookNotifier{}).applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
if assert.NotNil(t, optimizedCommits) && len(optimizedCommits) == 2 {
|
||||
assert.Equal(t, []string{"file1.txt", "file2.txt"}, optimizedCommits[0].Added)
|
||||
assert.Equal(t, []string{"oldfile.txt"}, optimizedCommits[0].Removed)
|
||||
assert.Equal(t, []string{"modified.txt"}, optimizedCommits[0].Modified)
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedCommits[1].Added)
|
||||
assert.Equal(t, []string{}, optimizedCommits[1].Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedCommits[1].Modified)
|
||||
}
|
||||
apiHeadCommit = &api.PayloadCommit{
|
||||
ID: "def456",
|
||||
Message: "Another commit",
|
||||
Added: []string{"file3.txt"},
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
if assert.NotNil(t, optimizedHeadCommit) {
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedHeadCommit.Added)
|
||||
assert.Equal(t, []string{}, optimizedHeadCommit.Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedHeadCommit.Modified)
|
||||
}
|
||||
optimizedCommits, _ = notifier.applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
assert.Len(t, optimizedCommits, 1)
|
||||
assert.Equal(t, "abc123", optimizedCommits[0].ID)
|
||||
|
||||
// Test with no limits (0 means unlimited)
|
||||
// Case: 0 (keep nothing)
|
||||
webhook.ExcludeFilesLimit = 0
|
||||
webhook.ExcludeCommitsLimit = 0
|
||||
err = webhook_model.UpdateWebhook(db.DefaultContext, webhook)
|
||||
@ -221,14 +196,52 @@ func TestWebhookPayloadOptimization(t *testing.T) {
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
}
|
||||
optimizedCommits, optimizedHeadCommit = notifier.applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
assert.Equal(t, []string{"file1.txt", "file2.txt"}, optimizedCommits[0].Added)
|
||||
assert.Equal(t, []string{"oldfile.txt"}, optimizedCommits[0].Removed)
|
||||
assert.Equal(t, []string{"modified.txt"}, optimizedCommits[0].Modified)
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedCommits[1].Added)
|
||||
assert.Equal(t, []string{}, optimizedCommits[1].Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedCommits[1].Modified)
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedHeadCommit.Added)
|
||||
assert.Equal(t, []string{}, optimizedHeadCommit.Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedHeadCommit.Modified)
|
||||
optimizedCommits, optimizedHeadCommit = (&webhookNotifier{}).applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
assert.Nil(t, optimizedCommits)
|
||||
if assert.NotNil(t, optimizedHeadCommit) {
|
||||
assert.Nil(t, optimizedHeadCommit.Added)
|
||||
assert.Nil(t, optimizedHeadCommit.Removed)
|
||||
assert.Nil(t, optimizedHeadCommit.Modified)
|
||||
}
|
||||
|
||||
// Case: 1 (keep only 1)
|
||||
webhook.ExcludeFilesLimit = 1
|
||||
webhook.ExcludeCommitsLimit = 1
|
||||
err = webhook_model.UpdateWebhook(db.DefaultContext, webhook)
|
||||
assert.NoError(t, err)
|
||||
apiCommits = []*api.PayloadCommit{
|
||||
{
|
||||
ID: "abc123",
|
||||
Message: "Test commit",
|
||||
Added: []string{"file1.txt", "file2.txt"},
|
||||
Removed: []string{"oldfile.txt"},
|
||||
Modified: []string{"modified.txt"},
|
||||
},
|
||||
{
|
||||
ID: "def456",
|
||||
Message: "Another commit",
|
||||
Added: []string{"file3.txt"},
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
},
|
||||
}
|
||||
apiHeadCommit = &api.PayloadCommit{
|
||||
ID: "def456",
|
||||
Message: "Another commit",
|
||||
Added: []string{"file3.txt"},
|
||||
Removed: []string{},
|
||||
Modified: []string{"file1.txt"},
|
||||
}
|
||||
optimizedCommits, optimizedHeadCommit = (&webhookNotifier{}).applyWebhookPayloadOptimizations(db.DefaultContext, repo, apiCommits, apiHeadCommit)
|
||||
if assert.NotNil(t, optimizedCommits) && len(optimizedCommits) == 1 {
|
||||
assert.Equal(t, "abc123", optimizedCommits[0].ID)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedCommits[0].Added)
|
||||
assert.Equal(t, []string{"oldfile.txt"}, optimizedCommits[0].Removed)
|
||||
assert.Equal(t, []string{"modified.txt"}, optimizedCommits[0].Modified)
|
||||
}
|
||||
if assert.NotNil(t, optimizedHeadCommit) {
|
||||
assert.Equal(t, []string{"file3.txt"}, optimizedHeadCommit.Added)
|
||||
assert.Equal(t, []string{}, optimizedHeadCommit.Removed)
|
||||
assert.Equal(t, []string{"file1.txt"}, optimizedHeadCommit.Modified)
|
||||
}
|
||||
}
|
||||
|
@ -52,12 +52,12 @@
|
||||
<h4>{{ctx.Locale.Tr "repo.settings.payload_optimization"}}</h4>
|
||||
<div class="field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.exclude_files_limit"}}</label>
|
||||
<input name="exclude_files_limit" type="number" min="0" value="{{.Webhook.ExcludeFilesLimit}}" placeholder="0">
|
||||
<input name="exclude_files_limit" type="number" min="-1" value="{{.Webhook.ExcludeFilesLimit}}" placeholder="-1">
|
||||
<span class="help">{{ctx.Locale.Tr "repo.settings.exclude_files_limit_desc"}}</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ctx.Locale.Tr "repo.settings.exclude_commits_limit"}}</label>
|
||||
<input name="exclude_commits_limit" type="number" min="0" value="{{.Webhook.ExcludeCommitsLimit}}" placeholder="0">
|
||||
<input name="exclude_commits_limit" type="number" min="-1" value="{{.Webhook.ExcludeCommitsLimit}}" placeholder="-1">
|
||||
<span class="help">{{ctx.Locale.Tr "repo.settings.exclude_commits_limit_desc"}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user