mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-30 02:48:26 +00:00 
			
		
		
		
	Tag creation/deletion was triggering push webhooks even when branch filters were configured, causing unintended pipeline executions. This change modifies the branch filter logic to check the full ref name directly instead of first determining if it's a "branch" event. Fixes: Tag events now properly respect branch filters - Add getPayloadRef() function to extract full ref names - Update PrepareWebhook() to use direct ref matching - Prevents refs/tags/* from matching refs/heads/* filters Closes #35449 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package webhook
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	repo_model "code.gitea.io/gitea/models/repo"
 | |
| 	"code.gitea.io/gitea/models/unittest"
 | |
| 	user_model "code.gitea.io/gitea/models/user"
 | |
| 	webhook_model "code.gitea.io/gitea/models/webhook"
 | |
| 	"code.gitea.io/gitea/modules/git"
 | |
| 	"code.gitea.io/gitea/modules/setting"
 | |
| 	api "code.gitea.io/gitea/modules/structs"
 | |
| 	"code.gitea.io/gitea/modules/test"
 | |
| 	webhook_module "code.gitea.io/gitea/modules/webhook"
 | |
| 	"code.gitea.io/gitea/services/convert"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestWebhook_GetSlackHook(t *testing.T) {
 | |
| 	w := &webhook_model.Webhook{
 | |
| 		Meta: `{"channel": "foo", "username": "username", "color": "blue"}`,
 | |
| 	}
 | |
| 	slackHook := GetSlackHook(w)
 | |
| 	assert.Equal(t, SlackMeta{
 | |
| 		Channel:  "foo",
 | |
| 		Username: "username",
 | |
| 		Color:    "blue",
 | |
| 	}, *slackHook)
 | |
| }
 | |
| 
 | |
| func TestPrepareWebhooks(t *testing.T) {
 | |
| 	assert.NoError(t, unittest.PrepareTestDatabase())
 | |
| 
 | |
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | |
| 	hookTasks := []*webhook_model.HookTask{
 | |
| 		{HookID: 1, EventType: webhook_module.HookEventPush},
 | |
| 	}
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertNotExistsBean(t, hookTask)
 | |
| 	}
 | |
| 	assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Commits: []*api.PayloadCommit{{}}}))
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertExistsAndLoadBean(t, hookTask)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestPrepareWebhooksBranchFilterMatch(t *testing.T) {
 | |
| 	assert.NoError(t, unittest.PrepareTestDatabase())
 | |
| 
 | |
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
 | |
| 	hookTasks := []*webhook_model.HookTask{
 | |
| 		{HookID: 4, EventType: webhook_module.HookEventPush},
 | |
| 	}
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertNotExistsBean(t, hookTask)
 | |
| 	}
 | |
| 	// this test also ensures that * doesn't handle / in any special way (like shell would)
 | |
| 	assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/feature/7791", Commits: []*api.PayloadCommit{{}}}))
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertExistsAndLoadBean(t, hookTask)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) {
 | |
| 	assert.NoError(t, unittest.PrepareTestDatabase())
 | |
| 
 | |
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
 | |
| 	hookTasks := []*webhook_model.HookTask{
 | |
| 		{HookID: 4, EventType: webhook_module.HookEventPush},
 | |
| 	}
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertNotExistsBean(t, hookTask)
 | |
| 	}
 | |
| 	assert.NoError(t, PrepareWebhooks(t.Context(), EventSource{Repository: repo}, webhook_module.HookEventPush, &api.PushPayload{Ref: "refs/heads/fix_weird_bug"}))
 | |
| 
 | |
| 	for _, hookTask := range hookTasks {
 | |
| 		unittest.AssertNotExistsBean(t, hookTask)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestWebhookUserMail(t *testing.T) {
 | |
| 	require.NoError(t, unittest.PrepareTestDatabase())
 | |
| 	defer test.MockVariableValue(&setting.Service.NoReplyAddress, "no-reply.com")()
 | |
| 
 | |
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
 | |
| 	assert.Equal(t, user.GetPlaceholderEmail(), convert.ToUser(t.Context(), user, nil).Email)
 | |
| 	assert.Equal(t, user.Email, convert.ToUser(t.Context(), user, user).Email)
 | |
| }
 | |
| 
 | |
| func TestCheckBranchFilter(t *testing.T) {
 | |
| 	cases := []struct {
 | |
| 		filter string
 | |
| 		ref    git.RefName
 | |
| 		match  bool
 | |
| 	}{
 | |
| 		{"", "any-ref", true},
 | |
| 		{"*", "any-ref", true},
 | |
| 		{"**", "any-ref", true},
 | |
| 
 | |
| 		{"main", git.RefNameFromBranch("main"), true},
 | |
| 		{"main", git.RefNameFromTag("main"), false},
 | |
| 
 | |
| 		{"feature/*", git.RefNameFromBranch("feature"), false},
 | |
| 		{"feature/*", git.RefNameFromBranch("feature/foo"), true},
 | |
| 		{"feature/*", git.RefNameFromTag("feature/foo"), false},
 | |
| 
 | |
| 		{"{refs/heads/feature/*,refs/tags/release/*}", git.RefNameFromBranch("feature/foo"), true},
 | |
| 		{"{refs/heads/feature/*,refs/tags/release/*}", git.RefNameFromBranch("main"), false},
 | |
| 		{"{refs/heads/feature/*,refs/tags/release/*}", git.RefNameFromTag("release/bar"), true},
 | |
| 		{"{refs/heads/feature/*,refs/tags/release/*}", git.RefNameFromTag("dev"), false},
 | |
| 	}
 | |
| 	for _, v := range cases {
 | |
| 		assert.Equal(t, v.match, checkBranchFilter(v.filter, v.ref), "filter: %q ref: %q", v.filter, v.ref)
 | |
| 	}
 | |
| }
 |