Skip to content

Commit

Permalink
Allow filtering PRs by state
Browse files Browse the repository at this point in the history
In some situations we might only want to pick up resource versions
from PRs that have been merged or closed. For example, to trigger a
job based once a PR gets closed.
  • Loading branch information
vixus0 committed Oct 20, 2020
1 parent a506a61 commit 8aa1ece
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 49 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ Make sure to check out [#migrating](#migrating) to learn more.
| `access_token` | Yes | | A Github Access Token with repository access (required for setting status on commits). N.B. If you want github-pr-resource to work with a private repository. Set `repo:full` permissions on the access token you create on GitHub. If it is a public repository, `repo:status` is enough. |
| `v3_endpoint` | No | `https://api.github.com` | Endpoint to use for the V3 Github API (Restful). |
| `v4_endpoint` | No | `https://api.github.com/graphql` | Endpoint to use for the V4 Github API (Graphql). |
| `paths` | No | `["terraform/*/*.tf"]` | Only produce new versions if the PR includes changes to files that match one or more glob patterns or prefixes. |
| `ignore_paths` | No | `[".ci/"]` | Inverse of the above. Pattern syntax is documented in [filepath.Match](https://golang.org/pkg/path/filepath/#Match), or a path prefix can be specified (e.g. `.ci/` will match everything in the `.ci` directory). |
| `paths` | No | `["terraform/*/*.tf"]` | Only produce new versions if the PR includes changes to files that match one or more glob patterns or prefixes. |
| `ignore_paths` | No | `[".ci/"]` | Inverse of the above. Pattern syntax is documented in [filepath.Match](https://golang.org/pkg/path/filepath/#Match), or a path prefix can be specified (e.g. `.ci/` will match everything in the `.ci` directory). |
| `disable_ci_skip` | No | `true` | Disable ability to skip builds with `[ci skip]` and `[skip ci]` in commit message or pull request title. |
| `skip_ssl_verification` | No | `true` | Disable SSL/TLS certificate validation on git and API clients. Use with care! |
| `disable_forks` | No | `true` | Disable triggering of the resource if the pull request's fork repository is different to the configured repository. |
Expand All @@ -35,6 +35,7 @@ Make sure to check out [#migrating](#migrating) to learn more.
| `base_branch` | No | `master` | Name of a branch. The pipeline will only trigger on pull requests against the specified branch. |
| `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. |
| `disable_git_lfs` | No | `true` | Disable Git LFS, skipping an attempt to convert pointers of files tracked into their corresponding objects when checked out into a working copy. |
| `states` | No | `["OPEN", "MERGED"]` | The PR states to select (`OPEN`, `MERGED` or `CLOSED`). The pipeline will only trigger on pull requests matching one of the specified states. Default is ["OPEN"]. |

Notes:
- If `v3_endpoint` is set, `v4_endpoint` must also be set (and the other way around).
Expand Down
16 changes: 16 additions & 0 deletions check.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ Loop:
continue
}

// Filter out pull request if it does not have a filtered state
if len(request.Source.States) > 0 {
stateFound := false

for _, state := range request.Source.States {
if p.State == state {
stateFound = true
break
}
}

if !stateFound {
continue
}
}

// Filter out pull request if it does not contain at least one of the desired labels
if len(request.Source.Labels) > 0 {
labelFound := false
Expand Down
66 changes: 57 additions & 9 deletions check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ package resource_test
import (
"testing"

"github.com/shurcooL/githubv4"
"github.com/stretchr/testify/assert"
resource "github.com/telia-oss/github-pr-resource"
"github.com/telia-oss/github-pr-resource/fakes"
)

var (
testPullRequests = []*resource.PullRequest{
createTestPR(1, "master", true, false, 0, nil),
createTestPR(2, "master", false, false, 0, nil),
createTestPR(3, "master", false, false, 0, nil),
createTestPR(4, "master", false, false, 0, nil),
createTestPR(5, "master", false, true, 0, nil),
createTestPR(6, "master", false, false, 0, nil),
createTestPR(7, "develop", false, false, 0, []string{"enhancement"}),
createTestPR(8, "master", false, false, 1, []string{"wontfix"}),
createTestPR(9, "master", false, false, 0, nil),
createTestPR(1, "master", true, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(2, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(3, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(4, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(5, "master", false, true, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(6, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(7, "develop", false, false, 0, []string{"enhancement"}, githubv4.PullRequestStateOpen),
createTestPR(8, "master", false, false, 1, []string{"wontfix"}, githubv4.PullRequestStateOpen),
createTestPR(9, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
createTestPR(10, "master", false, false, 0, nil, githubv4.PullRequestStateClosed),
createTestPR(11, "master", false, false, 0, nil, githubv4.PullRequestStateMerged),
createTestPR(12, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
}
)

Expand Down Expand Up @@ -185,6 +189,50 @@ func TestCheck(t *testing.T) {
resource.NewVersion(testPullRequests[6]),
},
},

{
description: "check returns latest version from a PR with a single state filter",
source: resource.Source{
Repository: "itsdalmo/test-repository",
AccessToken: "oauthtoken",
States: []githubv4.PullRequestState{githubv4.PullRequestStateClosed},
},
version: resource.Version{},
pullRequests: testPullRequests,
files: [][]string{},
expected: resource.CheckResponse{
resource.NewVersion(testPullRequests[9]),
},
},

{
description: "check filters out versions from a PR which do not match the state filter",
source: resource.Source{
Repository: "itsdalmo/test-repository",
AccessToken: "oauthtoken",
States: []githubv4.PullRequestState{githubv4.PullRequestStateOpen},
},
version: resource.Version{},
pullRequests: testPullRequests[9:11],
files: [][]string{},
expected: resource.CheckResponse(nil),
},

{
description: "check returns versions from a PR with multiple state filters",
source: resource.Source{
Repository: "itsdalmo/test-repository",
AccessToken: "oauthtoken",
States: []githubv4.PullRequestState{githubv4.PullRequestStateClosed, githubv4.PullRequestStateMerged},
},
version: resource.NewVersion(testPullRequests[11]),
pullRequests: testPullRequests,
files: [][]string{},
expected: resource.CheckResponse{
resource.NewVersion(testPullRequests[10]),
resource.NewVersion(testPullRequests[9]),
},
},
}

for _, tc := range tests {
Expand Down
2 changes: 1 addition & 1 deletion github.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (m *GithubClient) ListOpenPullRequests() ([]*PullRequest, error) {
"repositoryOwner": githubv4.String(m.Owner),
"repositoryName": githubv4.String(m.Repository),
"prFirst": githubv4.Int(100),
"prStates": []githubv4.PullRequestState{githubv4.PullRequestStateOpen},
"prStates": []githubv4.PullRequestState{githubv4.PullRequestStateOpen, githubv4.PullRequestStateClosed, githubv4.PullRequestStateMerged},
"prCursor": (*githubv4.String)(nil),
"commitsLast": githubv4.Int(1),
"prReviewStates": []githubv4.PullRequestReviewState{githubv4.PullRequestReviewStateApproved},
Expand Down
1 change: 1 addition & 0 deletions in.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func Get(request GetRequest, github Github, git Git, outputDir string) (*GetResp
metadata.Add("message", pull.Tip.Message)
metadata.Add("author", pull.Tip.Author.User.Login)
metadata.Add("author_email", pull.Tip.Author.Email)
metadata.Add("state", string(pull.State))

// Write version and metadata for reuse in PUT
path := filepath.Join(outputDir, ".git", "resource")
Expand Down
26 changes: 14 additions & 12 deletions in_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ func TestGet(t *testing.T) {
ApprovedReviewCount: "0",
},
parameters: resource.GetParameters{},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
},
{
description: "get supports unlocking with git crypt",
Expand All @@ -59,9 +59,9 @@ func TestGet(t *testing.T) {
ApprovedReviewCount: "0",
},
parameters: resource.GetParameters{},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
},
{
description: "get supports rebasing",
Expand All @@ -78,9 +78,9 @@ func TestGet(t *testing.T) {
parameters: resource.GetParameters{
IntegrationTool: "rebase",
},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
},
{
description: "get supports checkout",
Expand All @@ -97,9 +97,9 @@ func TestGet(t *testing.T) {
parameters: resource.GetParameters{
IntegrationTool: "checkout",
},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
},
{
description: "get supports git_depth",
Expand All @@ -116,9 +116,9 @@ func TestGet(t *testing.T) {
parameters: resource.GetParameters{
GitDepth: 2,
},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
},
{
description: "get supports list_changed_files",
Expand All @@ -135,7 +135,7 @@ func TestGet(t *testing.T) {
parameters: resource.GetParameters{
ListChangedFiles: true,
},
pullRequest: createTestPR(1, "master", false, false, 0, nil),
pullRequest: createTestPR(1, "master", false, false, 0, nil, githubv4.PullRequestStateOpen),
files: []resource.ChangedFileObject{
{
Path: "README.md",
Expand All @@ -145,7 +145,7 @@ func TestGet(t *testing.T) {
},
},
versionString: `{"pr":"pr1","commit":"commit1","committed":"0001-01-01T00:00:00Z","approved_review_count":"0"}`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"}]`,
metadataString: `[{"name":"pr","value":"1"},{"name":"title","value":"pr1 title"},{"name":"url","value":"pr1 url"},{"name":"head_name","value":"pr1"},{"name":"head_sha","value":"oid1"},{"name":"base_name","value":"master"},{"name":"base_sha","value":"sha"},{"name":"message","value":"commit message1"},{"name":"author","value":"login1"},{"name":"author_email","value":"[email protected]"},{"name":"state","value":"OPEN"}]`,
filesString: "README.md\nOther.md\n",
},
}
Expand Down Expand Up @@ -319,6 +319,7 @@ func createTestPR(
isCrossRepo bool,
approvedReviews int,
labels []string,
state githubv4.PullRequestState,
) *resource.PullRequest {
n := strconv.Itoa(count)
d := time.Now().AddDate(0, 0, -count)
Expand Down Expand Up @@ -349,6 +350,7 @@ func createTestPR(
URL: fmt.Sprintf("repo%s url", n),
},
IsCrossRepository: isCrossRepo,
State: state,
},
Tip: resource.CommitObject{
ID: fmt.Sprintf("commit%s", n),
Expand Down
Loading

0 comments on commit 8aa1ece

Please sign in to comment.