From 4c37b6f088da3d35e4254e75a5ecc2cc644c9a24 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 14 Jan 2026 23:39:54 -0800 Subject: [PATCH 1/2] Add test for webhook branch filter with glob pattern --- tests/integration/repo_webhook_test.go | 113 +++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 3ecbddb649..5272073046 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -435,6 +435,119 @@ func Test_WebhookPushDevBranch(t *testing.T) { }) } +func Test_WebhookPushBranchPatternGlob(t *testing.T) { + testCases := []struct { + name string + branchFilter string + matchBranch string + nonMatchBranch string + branchesToCreate []string + verifyCommits bool + }{ + { + name: "PrefixWildcard", + branchFilter: "feature/*", + matchBranch: "feature/glob-branch", + nonMatchBranch: "master", + branchesToCreate: []string{"feature/glob-branch"}, + verifyCommits: true, + }, + { + name: "NegatedCharacterClass", + branchFilter: "feature/[!h]lob-branch", + matchBranch: "feature/glob-branch", + nonMatchBranch: "feature/hlob-branch", + branchesToCreate: []string{"feature/glob-branch", "feature/hlob-branch"}, + }, + { + name: "DoubleStarFullRef", + branchFilter: "refs/heads/release/**/rc", + matchBranch: "release/v1/rc", + nonMatchBranch: "release/v1/beta", + branchesToCreate: []string{"release/v1/rc", "release/v1/beta"}, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + var payloads []api.PushPayload + var triggeredEvent string + provider := newMockWebhookProvider(func(r *http.Request) { + content, _ := io.ReadAll(r.Body) + var payload api.PushPayload + err := json.Unmarshal(content, &payload) + assert.NoError(t, err) + payloads = append(payloads, payload) + triggeredEvent = "push" + }, http.StatusOK) + defer provider.Close() + + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + session := loginUser(t, "user2") + slug := strings.ToLower(tc.name) + + for _, branch := range tc.branchesToCreate { + testAPICreateBranch(t, session, "user2", "repo1", "master", branch, http.StatusCreated) + } + + testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push", tc.branchFilter) + + if tc.nonMatchBranch != "" { + payloads = nil + triggeredEvent = "" + nonMatchFile := fmt.Sprintf("test_webhook_push_glob_%s_nonmatch.md", slug) + testCreateFile(t, session, "user2", "repo1", tc.nonMatchBranch, "", nonMatchFile, fmt.Sprintf("# push filtered by glob %s", tc.name)) + assert.Empty(t, triggeredEvent) + assert.Empty(t, payloads) + } + + payloads = nil + triggeredEvent = "" + matchFile := fmt.Sprintf("test_webhook_push_glob_%s_match.md", slug) + + var ( + gitRepo *git.Repository + beforeCommitID string + ) + if tc.verifyCommits { + repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1}) + var err error + gitRepo, err = gitrepo.OpenRepository(t.Context(), repo1) + assert.NoError(t, err) + defer gitRepo.Close() + beforeCommitID, err = gitRepo.GetBranchCommitID(tc.matchBranch) + assert.NoError(t, err) + } + + testCreateFile(t, session, "user2", "repo1", tc.matchBranch, "", matchFile, fmt.Sprintf("# push allowed by glob %s", tc.name)) + + var afterCommitID string + if tc.verifyCommits { + var err error + afterCommitID, err = gitRepo.GetBranchCommitID(tc.matchBranch) + assert.NoError(t, err) + } + + assert.Equal(t, "push", triggeredEvent) + require.Len(t, payloads, 1) + assert.Equal(t, "refs/heads/"+tc.matchBranch, payloads[0].Ref) + assert.Equal(t, tc.matchBranch, payloads[0].Branch()) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) + require.Len(t, payloads[0].Commits, 1) + assert.Equal(t, []string{matchFile}, payloads[0].Commits[0].Added) + + if tc.verifyCommits { + assert.Equal(t, beforeCommitID, payloads[0].Before) + assert.Equal(t, afterCommitID, payloads[0].After) + assert.Equal(t, setting.AppURL+"user2/repo1/compare/"+beforeCommitID+"..."+afterCommitID, payloads[0].CompareURL) + } + }) + }) + } +} + func Test_WebhookPushToNewBranch(t *testing.T) { var payloads []api.PushPayload var triggeredEvent string From 5ba70580395702a61c92760f2db59eb3ac321aa1 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 15 Jan 2026 11:34:08 -0800 Subject: [PATCH 2/2] fix test --- tests/integration/repo_webhook_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 5272073046..a278bddd62 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -469,7 +469,6 @@ func Test_WebhookPushBranchPatternGlob(t *testing.T) { } for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { var payloads []api.PushPayload var triggeredEvent string @@ -497,7 +496,7 @@ func Test_WebhookPushBranchPatternGlob(t *testing.T) { payloads = nil triggeredEvent = "" nonMatchFile := fmt.Sprintf("test_webhook_push_glob_%s_nonmatch.md", slug) - testCreateFile(t, session, "user2", "repo1", tc.nonMatchBranch, "", nonMatchFile, fmt.Sprintf("# push filtered by glob %s", tc.name)) + testCreateFile(t, session, "user2", "repo1", tc.nonMatchBranch, "", nonMatchFile, "# push filtered by glob "+tc.name) assert.Empty(t, triggeredEvent) assert.Empty(t, payloads) } @@ -520,7 +519,7 @@ func Test_WebhookPushBranchPatternGlob(t *testing.T) { assert.NoError(t, err) } - testCreateFile(t, session, "user2", "repo1", tc.matchBranch, "", matchFile, fmt.Sprintf("# push allowed by glob %s", tc.name)) + testCreateFile(t, session, "user2", "repo1", tc.matchBranch, "", matchFile, "# push allowed by glob "+tc.name) var afterCommitID string if tc.verifyCommits {