Skip to content

Commit a732c70

Browse files
committed
Refactor to support positive and negative head branch filters
This replaces the proposed `head_branch_filter` option with two options: `head_branches` selects PRs that match the specified glob, and `ignore_head_branches` selects PRs that do not match the specified glob. This provides more control over filtering PRs based on the head branch, and brings head branch filtering in line with what already exists for path filtering.
1 parent 67ba06c commit a732c70

5 files changed

Lines changed: 81 additions & 21 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ Make sure to check out [#migrating](#migrating) to learn more.
3434
| `git_crypt_key` | No | `AEdJVENSWVBUS0VZAAAAA...` | Base64 encoded git-crypt key. Setting this will unlock / decrypt the repository with git-crypt. To get the key simply execute `git-crypt export-key -- - | base64` in an encrypted repository. |
3535
| `base_branch` | No | `master` | Name of a branch. The pipeline will only trigger on pull requests against the specified branch. |
3636
| `labels` | No | `["bug", "enhancement"]` | The labels on the PR. The pipeline will only trigger on pull requests having at least one of the specified labels. |
37-
| `head_branch_filter` | No | `release/*` | If specified, the pipeline will only trigger on pull requests for which the head branch name matches the specified glob pattern. |
37+
| `head_branches` | No | `release/*` | If specified, the pipeline will only trigger on pull requests for which the head branch name matches the specified glob pattern. |
38+
| `ignore_head_branches` | No | `release/*` | Inverse of the above |
3839

3940
Notes:
4041
- If `v3_endpoint` is set, `v4_endpoint` must also be set (and the other way around).

check.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ Loop:
3838
continue
3939
}
4040

41-
// Filter pull request if the HeadRefName does not match the HeadBranchFilter specified in source
42-
if request.Source.HeadBranchFilter != "" {
43-
matched, err := filepath.Match(request.Source.HeadBranchFilter, p.PullRequestObject.HeadRefName)
41+
// Skip pull request if the HeadRefName does not match the head_branches glob specified in source
42+
if request.Source.HeadBranches != "" {
43+
matched, err := filepath.Match(request.Source.HeadBranches, p.PullRequestObject.HeadRefName)
4444
if err != nil {
4545
return nil, fmt.Errorf("failed to apply head branch filter: %s", err)
4646
}
@@ -49,6 +49,17 @@ Loop:
4949
}
5050
}
5151

52+
// Skip pull request if the HeadRefName matches the ignore_head_branches glob specified in source
53+
if request.Source.IgnoreHeadBranches != "" {
54+
matched, err := filepath.Match(request.Source.IgnoreHeadBranches, p.PullRequestObject.HeadRefName)
55+
if err != nil {
56+
return nil, fmt.Errorf("failed to apply ignore head branch filter: %s", err)
57+
}
58+
if matched {
59+
continue
60+
}
61+
}
62+
5263
// Filter out pull request if it does not contain at least one of the desired labels
5364
if len(request.Source.Labels) > 0 {
5465
labelFound := false

check_test.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,30 @@ func TestCheck(t *testing.T) {
189189
{
190190
description: "check correctly ignores PRs that do not match the head branch filter",
191191
source: resource.Source{
192-
Repository: "itsdalmo/test-repository",
193-
AccessToken: "oauthtoken",
194-
HeadBranchFilter: "pr2*",
192+
Repository: "itsdalmo/test-repository",
193+
AccessToken: "oauthtoken",
194+
HeadBranches: "pr8*",
195195
},
196196
version: resource.Version{},
197197
pullRequests: testPullRequests,
198198
files: [][]string{},
199199
expected: resource.CheckResponse{
200-
resource.NewVersion(testPullRequests[1]),
200+
resource.NewVersion(testPullRequests[7]),
201+
},
202+
},
203+
204+
{
205+
description: "check correctly ignores PRs that do match the ignore head branch filter",
206+
source: resource.Source{
207+
Repository: "itsdalmo/test-repository",
208+
AccessToken: "oauthtoken",
209+
IgnoreHeadBranches: "pr2*",
210+
},
211+
version: resource.Version{},
212+
pullRequests: testPullRequests,
213+
files: [][]string{},
214+
expected: resource.CheckResponse{
215+
resource.NewVersion(testPullRequests[2]),
201216
},
202217
},
203218
}

e2e/e2e_test.go

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,12 @@ func TestCheckE2E(t *testing.T) {
177177
{
178178
description: "check returns latest PR that matches the head branch filter",
179179
source: resource.Source{
180-
Repository: "itsdalmo/test-repository",
181-
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
182-
V3Endpoint: "https://api.github.com/",
183-
V4Endpoint: "https://api.github.com/graphql",
184-
HeadBranchFilter: "my*",
185-
DisableCISkip: true,
180+
Repository: "itsdalmo/test-repository",
181+
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
182+
V3Endpoint: "https://api.github.com/",
183+
V4Endpoint: "https://api.github.com/graphql",
184+
HeadBranches: "my*",
185+
DisableCISkip: true,
186186
},
187187
version: resource.Version{},
188188
expected: resource.CheckResponse{
@@ -193,16 +193,48 @@ func TestCheckE2E(t *testing.T) {
193193
{
194194
description: "check works when head branch filter doesn't match any PRs",
195195
source: resource.Source{
196-
Repository: "itsdalmo/test-repository",
197-
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
198-
V3Endpoint: "https://api.github.com/",
199-
V4Endpoint: "https://api.github.com/graphql",
200-
HeadBranchFilter: "feature/*",
201-
DisableCISkip: true,
196+
Repository: "itsdalmo/test-repository",
197+
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
198+
V3Endpoint: "https://api.github.com/",
199+
V4Endpoint: "https://api.github.com/graphql",
200+
HeadBranches: "feature/*",
201+
DisableCISkip: true,
202202
},
203203
version: resource.Version{},
204204
expected: resource.CheckResponse(nil),
205205
},
206+
207+
{
208+
description: "check returns latest PR that matches the ignore head branch filter",
209+
source: resource.Source{
210+
Repository: "itsdalmo/test-repository",
211+
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
212+
V3Endpoint: "https://api.github.com/",
213+
V4Endpoint: "https://api.github.com/graphql",
214+
IgnoreHeadBranches: "test*",
215+
DisableCISkip: true,
216+
},
217+
version: resource.Version{},
218+
expected: resource.CheckResponse{
219+
resource.Version{PR: targetPullRequestID, Commit: targetCommitID, CommittedDate: targetDateTime},
220+
},
221+
},
222+
223+
{
224+
description: "check works when ignore head branch filter doesn't match any PRs",
225+
source: resource.Source{
226+
Repository: "itsdalmo/test-repository",
227+
AccessToken: os.Getenv("GITHUB_ACCESS_TOKEN"),
228+
V3Endpoint: "https://api.github.com/",
229+
V4Endpoint: "https://api.github.com/graphql",
230+
IgnoreHeadBranches: "feature/*",
231+
DisableCISkip: true,
232+
},
233+
version: resource.Version{},
234+
expected: resource.CheckResponse{
235+
resource.Version{PR: developPullRequestID, Commit: developCommitID, CommittedDate: developDateTime},
236+
},
237+
},
206238
}
207239

208240
for _, tc := range tests {

models.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ type Source struct {
2121
DisableForks bool `json:"disable_forks"`
2222
GitCryptKey string `json:"git_crypt_key"`
2323
BaseBranch string `json:"base_branch"`
24-
HeadBranchFilter string `json:"head_branch_filter"`
24+
HeadBranches string `json:"head_branches"`
25+
IgnoreHeadBranches string `json:"ignore_head_branches"`
2526
RequiredReviewApprovals int `json:"required_review_approvals"`
2627
Labels []string `json:"labels"`
2728
}

0 commit comments

Comments
 (0)