Fix webhook

This commit is contained in:
Lunny Xiao
2026-04-20 12:19:36 -07:00
parent 20914a1375
commit 469a6d3466
6 changed files with 117 additions and 104 deletions

View File

@@ -89,14 +89,6 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error {
config["secret"] = secret config["secret"] = secret
} }
if branchFilter != "" {
config["branch_filter"] = branchFilter
}
if authHeader != "" {
config["authorization_header"] = authHeader
}
var hook *gitea.Hook var hook *gitea.Hook
if c.IsGlobal { if c.IsGlobal {
return fmt.Errorf("global webhooks not yet supported in this version") return fmt.Errorf("global webhooks not yet supported in this version")
@@ -106,6 +98,8 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error {
Config: config, Config: config,
Events: events, Events: events,
Active: active, Active: active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} else { } else {
hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{ hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{
@@ -113,6 +107,8 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error {
Config: config, Config: config,
Events: events, Events: events,
Active: active, Active: active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} }
if err != nil { if err != nil {

View File

@@ -79,8 +79,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
name string name string
url string url string
secret string secret string
branchFilter string
authHeader string
expectedKeys []string expectedKeys []string
expectedValues map[string]string expectedValues map[string]string
}{ }{
@@ -106,44 +104,16 @@ func TestWebhookConfigConstruction(t *testing.T) {
"secret": "my-secret", "secret": "my-secret",
}, },
}, },
{
name: "Config with branch filter",
url: "https://example.com/webhook",
branchFilter: "main,develop",
expectedKeys: []string{"url", "http_method", "content_type", "branch_filter"},
expectedValues: map[string]string{
"url": "https://example.com/webhook",
"http_method": "post",
"content_type": "json",
"branch_filter": "main,develop",
},
},
{
name: "Config with auth header",
url: "https://example.com/webhook",
authHeader: "Bearer token123",
expectedKeys: []string{"url", "http_method", "content_type", "authorization_header"},
expectedValues: map[string]string{
"url": "https://example.com/webhook",
"http_method": "post",
"content_type": "json",
"authorization_header": "Bearer token123",
},
},
{ {
name: "Complete config", name: "Complete config",
url: "https://example.com/webhook", url: "https://example.com/webhook",
secret: "secret123", secret: "secret123",
branchFilter: "main", expectedKeys: []string{"url", "http_method", "content_type", "secret"},
authHeader: "X-Token: abc",
expectedKeys: []string{"url", "http_method", "content_type", "secret", "branch_filter", "authorization_header"},
expectedValues: map[string]string{ expectedValues: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
"secret": "secret123", "secret": "secret123",
"branch_filter": "main",
"authorization_header": "X-Token: abc",
}, },
}, },
} }
@@ -159,12 +129,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
if tt.secret != "" { if tt.secret != "" {
config["secret"] = tt.secret config["secret"] = tt.secret
} }
if tt.branchFilter != "" {
config["branch_filter"] = tt.branchFilter
}
if tt.authHeader != "" {
config["authorization_header"] = tt.authHeader
}
// Check all expected keys exist // Check all expected keys exist
for _, key := range tt.expectedKeys { for _, key := range tt.expectedKeys {
@@ -189,6 +153,8 @@ func TestWebhookCreateOptions(t *testing.T) {
events []string events []string
active bool active bool
config map[string]string config map[string]string
branchFilter string
authHeader string
}{ }{
{ {
name: "Gitea webhook", name: "Gitea webhook",
@@ -200,6 +166,8 @@ func TestWebhookCreateOptions(t *testing.T) {
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
}, },
branchFilter: "main",
authHeader: "X-Token: abc",
}, },
{ {
name: "Slack webhook", name: "Slack webhook",
@@ -232,12 +200,16 @@ func TestWebhookCreateOptions(t *testing.T) {
Config: tt.config, Config: tt.config,
Events: tt.events, Events: tt.events,
Active: tt.active, Active: tt.active,
BranchFilter: tt.branchFilter,
AuthorizationHeader: tt.authHeader,
} }
assert.Equal(t, gitea.HookType(tt.webhookType), option.Type) assert.Equal(t, gitea.HookType(tt.webhookType), option.Type)
assert.Equal(t, tt.events, option.Events) assert.Equal(t, tt.events, option.Events)
assert.Equal(t, tt.active, option.Active) assert.Equal(t, tt.active, option.Active)
assert.Equal(t, tt.config, option.Config) assert.Equal(t, tt.config, option.Config)
assert.Equal(t, tt.branchFilter, option.BranchFilter)
assert.Equal(t, tt.authHeader, option.AuthorizationHeader)
}) })
} }
} }

View File

@@ -97,11 +97,14 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
if cmd.IsSet("secret") { if cmd.IsSet("secret") {
config["secret"] = cmd.String("secret") config["secret"] = cmd.String("secret")
} }
branchFilter := hook.BranchFilter
if cmd.IsSet("branch-filter") { if cmd.IsSet("branch-filter") {
config["branch_filter"] = cmd.String("branch-filter") branchFilter = cmd.String("branch-filter")
} }
authHeader := hook.AuthorizationHeader
if cmd.IsSet("authorization-header") { if cmd.IsSet("authorization-header") {
config["authorization_header"] = cmd.String("authorization-header") authHeader = cmd.String("authorization-header")
} }
// Update events if specified // Update events if specified
@@ -129,12 +132,16 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
Config: config, Config: config,
Events: events, Events: events,
Active: &active, Active: &active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} else { } else {
_, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{ _, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{
Config: config, Config: config,
Events: events, Events: events,
Active: &active, Active: &active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} }
if err != nil { if err != nil {

View File

@@ -130,8 +130,6 @@ func TestUpdateConfigPreservation(t *testing.T) {
originalConfig := map[string]string{ originalConfig := map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main",
"authorization_header": "Bearer old-token",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
} }
@@ -149,37 +147,18 @@ func TestUpdateConfigPreservation(t *testing.T) {
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://new.example.com/webhook", "url": "https://new.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main",
"authorization_header": "Bearer old-token",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
}, },
}, },
{ {
name: "Update secret and auth header", name: "Update secret",
updates: map[string]string{ updates: map[string]string{
"secret": "new-secret", "secret": "new-secret",
"authorization_header": "X-Token: new-token",
}, },
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "new-secret", "secret": "new-secret",
"branch_filter": "main",
"authorization_header": "X-Token: new-token",
"http_method": "post",
"content_type": "json",
},
},
{
name: "Clear branch filter",
updates: map[string]string{
"branch_filter": "",
},
expectedConfig: map[string]string{
"url": "https://old.example.com/webhook",
"secret": "old-secret",
"branch_filter": "",
"authorization_header": "Bearer old-token",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
}, },
@@ -190,8 +169,6 @@ func TestUpdateConfigPreservation(t *testing.T) {
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main",
"authorization_header": "Bearer old-token",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
}, },
@@ -217,6 +194,61 @@ func TestUpdateConfigPreservation(t *testing.T) {
} }
} }
func TestUpdateBranchFilterAndAuthHeaderHandling(t *testing.T) {
tests := []struct {
name string
originalBranchFilter string
originalAuthHeader string
setBranchFilter bool
newBranchFilter string
setAuthorizationHeader bool
newAuthHeader string
expectedBranchFilter string
expectedAuthHeader string
}{
{
name: "Preserve values",
originalBranchFilter: "main",
originalAuthHeader: "Bearer old-token",
expectedBranchFilter: "main",
expectedAuthHeader: "Bearer old-token",
},
{
name: "Update branch filter",
originalBranchFilter: "main",
setBranchFilter: true,
newBranchFilter: "develop",
expectedBranchFilter: "develop",
expectedAuthHeader: "",
},
{
name: "Update authorization header",
originalAuthHeader: "Bearer old-token",
setAuthorizationHeader: true,
newAuthHeader: "X-Token: new-token",
expectedBranchFilter: "",
expectedAuthHeader: "X-Token: new-token",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
branchFilter := tt.originalBranchFilter
if tt.setBranchFilter {
branchFilter = tt.newBranchFilter
}
authHeader := tt.originalAuthHeader
if tt.setAuthorizationHeader {
authHeader = tt.newAuthHeader
}
assert.Equal(t, tt.expectedBranchFilter, branchFilter)
assert.Equal(t, tt.expectedAuthHeader, authHeader)
})
}
}
func TestUpdateEventsHandling(t *testing.T) { func TestUpdateEventsHandling(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

View File

@@ -67,13 +67,21 @@ func WebhookDetails(hook *gitea.Hook) {
if method, ok := hook.Config["http_method"]; ok { if method, ok := hook.Config["http_method"]; ok {
fmt.Printf("- **HTTP Method**: %s\n", method) fmt.Printf("- **HTTP Method**: %s\n", method)
} }
if branchFilter, ok := hook.Config["branch_filter"]; ok && branchFilter != "" { branchFilter := hook.BranchFilter
if branchFilter == "" {
branchFilter = hook.Config["branch_filter"]
}
if branchFilter != "" {
fmt.Printf("- **Branch Filter**: %s\n", branchFilter) fmt.Printf("- **Branch Filter**: %s\n", branchFilter)
} }
if _, hasSecret := hook.Config["secret"]; hasSecret { if _, hasSecret := hook.Config["secret"]; hasSecret {
fmt.Printf("- **Secret**: (configured)\n") fmt.Printf("- **Secret**: (configured)\n")
} }
if _, hasAuth := hook.Config["authorization_header"]; hasAuth { hasAuth := hook.AuthorizationHeader != ""
if !hasAuth {
_, hasAuth = hook.Config["authorization_header"]
}
if hasAuth {
fmt.Printf("- **Authorization Header**: (configured)\n") fmt.Printf("- **Authorization Header**: (configured)\n")
} }
} }

View File

@@ -84,10 +84,10 @@ func TestWebhookDetails(t *testing.T) {
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"content_type": "json", "content_type": "json",
"http_method": "post", "http_method": "post",
"branch_filter": "main,develop",
"secret": "secret-value", "secret": "secret-value",
"authorization_header": "Bearer token123",
}, },
BranchFilter: "main,develop",
AuthorizationHeader: "Bearer token123",
Events: []string{"push", "pull_request", "issues"}, Events: []string{"push", "pull_request", "issues"},
Active: true, Active: true,
Created: now.Add(-24 * time.Hour), Created: now.Add(-24 * time.Hour),
@@ -240,14 +240,12 @@ func TestWebhookConfigHandling(t *testing.T) {
config: map[string]string{ config: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"secret": "my-secret", "secret": "my-secret",
"authorization_header": "Bearer token",
"content_type": "json", "content_type": "json",
"http_method": "post", "http_method": "post",
"branch_filter": "main",
}, },
expectedURL: "https://example.com/webhook", expectedURL: "https://example.com/webhook",
hasSecret: true, hasSecret: true,
hasAuthHeader: true, hasAuthHeader: false,
}, },
{ {
name: "Config with minimal fields", name: "Config with minimal fields",
@@ -344,10 +342,10 @@ func TestWebhookDetailsFormatting(t *testing.T) {
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"content_type": "json", "content_type": "json",
"http_method": "post", "http_method": "post",
"branch_filter": "main,develop",
"secret": "secret-value", "secret": "secret-value",
"authorization_header": "Bearer token123",
}, },
BranchFilter: "main,develop",
AuthorizationHeader: "Bearer token123",
Events: []string{"push", "pull_request", "issues"}, Events: []string{"push", "pull_request", "issues"},
Active: true, Active: true,
Created: now.Add(-24 * time.Hour), Created: now.Add(-24 * time.Hour),
@@ -379,8 +377,8 @@ func TestWebhookDetailsFormatting(t *testing.T) {
assert.Equal(t, "https://example.com/webhook", hook.Config["url"]) assert.Equal(t, "https://example.com/webhook", hook.Config["url"])
assert.Equal(t, "json", hook.Config["content_type"]) assert.Equal(t, "json", hook.Config["content_type"])
assert.Equal(t, "post", hook.Config["http_method"]) assert.Equal(t, "post", hook.Config["http_method"])
assert.Equal(t, "main,develop", hook.Config["branch_filter"]) assert.Equal(t, "main,develop", hook.BranchFilter)
assert.Contains(t, hook.Config, "secret") assert.Contains(t, hook.Config, "secret")
assert.Contains(t, hook.Config, "authorization_header") assert.Equal(t, "Bearer token123", hook.AuthorizationHeader)
assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events) assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events)
} }