Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
7fe61b9
Add author_email to metadata
Oct 22, 2019
8592fbe
Merge branch 'master' into vy-add-author-email
v-yarotsky Nov 20, 2019
a4a51ca
Add git-lfs package
spire-allyjweir Jan 25, 2020
b8e495e
Add ability to disable git-lfs
spire-allyjweir Jan 25, 2020
072def4
Configure origin for pulling
spire-allyjweir Jan 25, 2020
0d47791
Merge branch 'master' into vy-add-author-email
Apr 24, 2020
1cbc155
Bump go version used for builds
Apr 24, 2020
8565372
Bump all go dependencies to latest minor version
Apr 24, 2020
75e217b
Remove GO111MODULE from taskfile
Apr 24, 2020
7027a1a
Use alpine 3.11 instead of 3.8 (end of support)
Apr 24, 2020
57c30ee
Merge pull request #195 from telia-oss/bump-toolchain
Apr 24, 2020
c1061f4
Update paths parameter to reflect as a list item (#180)
rickgeorges Apr 24, 2020
39a072d
Merge branch 'master' into vy-add-author-email
Apr 24, 2020
68bf513
Merge pull request #158 from v-yarotsky/vy-add-author-email
Apr 24, 2020
313638b
add PR title to metadata (#172)
mjdouble Apr 24, 2020
8eaccf8
Fix e2e tests after changes to metadata
Apr 24, 2020
3fd61ac
Merge pull request #196 from telia-oss/fix-e2e-tests
Apr 24, 2020
735beaf
Reorder metadata so the PR title is more visible
Apr 25, 2020
ddf8693
Merge pull request #197 from telia-oss/reorder-metadata
Apr 25, 2020
c646b78
feat: add submodule support, with safe checkout using access tokens (…
jhosteny Apr 27, 2020
a2ec386
Add e2e test for submodules (#199)
Apr 27, 2020
92bd0f7
Merge branch 'master' into add-git-lfs-support
spire-allyjweir Apr 28, 2020
8628f31
Moving example closer to text
May 28, 2020
c41729d
Merge pull request #207 from maxknee/patch-1
May 29, 2020
be7b6a6
Merge branch 'master' into add-git-lfs-support
spire-allyjweir Jun 11, 2020
e2d84b3
Adds approved review count to the version
isaacsanders Aug 19, 2020
b083b8c
fix: Updates tests
isaacsanders Aug 19, 2020
c2077ff
Write version and metadata before the integration step
gabro Aug 21, 2020
3f16855
feat: add support for optionally fetching tags
jhosteny Sep 26, 2020
a55fe82
Merge branch 'master' into feat/add-fetch-tags
jhosteny Sep 26, 2020
cf19122
Merge pull request #224 from thoroai/feat/add-fetch-tags
rickardl Oct 19, 2020
97539d8
Merge branch 'master' into report-merge-conflict
rickardl Oct 19, 2020
b8a2ffc
Create test.yml
rickardl Oct 19, 2020
5b2e101
Update test.yml
rickardl Oct 19, 2020
c06a2c0
Remove windows-latest runner
rickardl Oct 19, 2020
76ea6d4
Restore windows-runner to CI/CD flow
rickardl Oct 19, 2020
05d7426
Conditional rule to task
rickardl Oct 19, 2020
4edb60b
Restore windows-latest
rickardl Oct 19, 2020
940551a
Remove windows-latest
rickardl Oct 19, 2020
43c9bd9
Merge pull request #220 from gabro/report-merge-conflict
rickardl Oct 19, 2020
c4b5c6d
Merge branch 'master' into feat/add-approved-review-count-to-the-version
rickardl Oct 19, 2020
c161a2d
Merge branch 'master' into add-git-lfs-support
rickardl Oct 19, 2020
06364c8
Merge pull request #219 from isaacsanders/feat/add-approved-review-co…
rickardl Oct 20, 2020
9ff47d2
docs: Updates README to reflect approved review count
isaacsanders Oct 20, 2020
ad669ca
fix: Converts Approved Review Count to string
isaacsanders Oct 20, 2020
fc1d0fb
fix: Converts more ints to strings
isaacsanders Oct 20, 2020
2ab0f31
Merge pull request #231 from isaacsanders/fix/strconv-approved-review…
rickardl Oct 20, 2020
9c40cd3
Merge branch 'master' into patch-1
rickardl Oct 20, 2020
fc3b6ae
Merge branch 'master' into add-github-actions-ci-cd
rickardl Oct 20, 2020
77c75a3
Merge pull request #228 from telia-oss/add-github-actions-ci-cd
rickardl Oct 20, 2020
042cba7
Merge branch 'master' into patch-1
rickardl Oct 20, 2020
e371a05
Merge pull request #230 from isaacsanders/patch-1
rickardl Oct 20, 2020
fae4c1d
Merge branch 'master' into add-git-lfs-support
rickardl Oct 20, 2020
a506a61
Merge pull request #186 from spire-allyjweir/add-git-lfs-support
rickardl Oct 20, 2020
8aa1ece
Allow filtering PRs by state
vixus0 Oct 14, 2020
c1d2f94
Add PR state to resource version
vixus0 Oct 15, 2020
2e9461a
Use closedAt and mergedAt when comparing version timestamps
vixus0 Oct 15, 2020
39b1f9d
Merge pull request #226 from vixus0/pr-state-filtering
rickardl Oct 20, 2020
60e7a0c
Add ignore_drafts option to skip draft pull requests (#225)
mariash Oct 20, 2020
99cb3ee
Expand Env Vars in context (#146) (#202)
mattburgess Oct 21, 2020
a98122f
Fix os.FileMode was meant to be in octal. (#236)
rickardl Oct 23, 2020
9ec47e2
fix: filter pull requests on the server, not client (#240)
jhosteny Feb 6, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
on: [push, pull_request]
name: Test
jobs:
test:
strategy:
matrix:
go-version: [1.14.x, 1.15.x]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Install Task
run: curl -sL https://taskfile.dev/install.sh | sh
- name: Run CI Task
run: ./bin/task ci

4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ sudo: false
matrix:
include:
- os: osx
go: 1.13.x
go: 1.14.x
- os: linux
go: 1.13.x
go: 1.14.x
notifications:
email: false
script:
Expand Down
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
FROM golang:1.13 as builder
FROM golang:1.14 as builder
ADD . /go/src/github.com/telia-oss/github-pr-resource
WORKDIR /go/src/github.com/telia-oss/github-pr-resource
RUN curl -sL https://taskfile.dev/install.sh | sh
RUN ./bin/task build

FROM alpine:3.8 as resource
FROM alpine:3.11 as resource
COPY --from=builder /go/src/github.com/telia-oss/github-pr-resource/build /opt/resource
RUN apk add --update --no-cache \
git \
git-lfs \
openssh \
&& chmod +x /opt/resource/*
COPY scripts/askpass.sh /usr/local/bin/askpass.sh
ADD scripts/install_git_crypt.sh install_git_crypt.sh
RUN ./install_git_crypt.sh && rm ./install_git_crypt.sh

Expand Down
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ 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. |
| `ignore_drafts` | No | `false` | Disable triggering of the resource if the pull request is in Draft status. |
| `required_review_approvals` | No | `2` | Disable triggering of the resource if the pull request does not have at least `X` approved review(s). |
| `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. |
| `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 All @@ -51,6 +54,7 @@ A version is represented as follows:
- `pr`: The pull request number.
- `commit`: The commit SHA.
- `committed`: Timestamp of when the commit was committed. Used to filter subsequent checks.
- `approved_review_count`: The number of reviews approving of the PR.

If several commits are pushed to a given PR at the same time, the last commit will be the new version.

Expand All @@ -68,7 +72,9 @@ generate notifications over the webhook. So if you have a repository with little
| `skip_download` | No | `true` | Use with `get_params` in a `put` step to do nothing on the implicit get. |
| `integration_tool` | No | `rebase` | The integration tool to use, `merge`, `rebase` or `checkout`. Defaults to `merge`. |
| `git_depth` | No | `1` | Shallow clone the repository using the `--depth` Git option |
| `submodules` | No | `true` | Recursively clone git submodules. Defaults to false. |
| `list_changed_files` | No | `true` | Generate a list of changed files and save alongside metadata |
| `fetch_tags` | No | `true` | Fetch tags from remote repository |

Clones the base (e.g. `master` branch) at the latest commit, and merges the pull request at the specified commit
into master. This ensures that we are both testing and setting status on the exact commit that was requested in
Expand All @@ -80,14 +86,13 @@ requested version and the metadata emitted by `get` are available to your tasks
- `.git/resource/changed_files` (if enabled by `list_changed_files`)

The information in `metadata.json` is also available as individual files in the `.git/resource` directory, e.g. the `base_sha`
is available as `.git/resource/base_sha`. For a complete list of available (individual) metadata files, please check the code
is available as `.git/resource/base_sha`. For a complete list of available (individual) metadata files, please check the code
[here](https://github.com/telia-oss/github-pr-resource/blob/master/in.go#L66).

When specifying `skip_download` the pull request volume mounted to subsequent tasks will be empty, which is a problem
when you set e.g. the pending status before running the actual tests. The workaround for this is to use an alias for
the `put` (see https://github.com/telia-oss/github-pr-resource/issues/32 for more details).

git-crypt encrypted repositories will automatically be decrypted when the `git_crypt_key` is set in the source configuration.
Example here:

```yaml
put: update-status <-- Use an alias for the pull-request resource
Expand All @@ -98,6 +103,8 @@ params:
get_params: {skip_download: true}
```

git-crypt encrypted repositories will automatically be decrypted when the `git_crypt_key` is set in the source configuration.

Note that, should you retrigger a build in the hopes of testing the last commit to a PR against a newer version of
the base, Concourse will reuse the volume (i.e. not trigger a new `get`) if it still exists, which can produce
unexpected results (#5). As such, re-testing a PR against a newer version of the base is best done by *pushing an
Expand Down
3 changes: 0 additions & 3 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
version: '2'

env:
GO111MODULE: on

vars:
BUILD_DIR: build
DOCKER_REPO: teliaoss/github-pr-resource
Expand Down
20 changes: 18 additions & 2 deletions check.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ import (
"regexp"
"sort"
"strings"

"github.com/shurcooL/githubv4"
)

// Check (business logic)
func Check(request CheckRequest, manager Github) (CheckResponse, error) {
var response CheckResponse

pulls, err := manager.ListOpenPullRequests()
// Filter out pull request if it does not have a filtered state
filterStates := []githubv4.PullRequestState{githubv4.PullRequestStateOpen}
if len(request.Source.States) > 0 {
filterStates = request.Source.States
}

pulls, err := manager.ListPullRequests(filterStates)
if err != nil {
return nil, fmt.Errorf("failed to get last commits: %s", err)
}
Expand All @@ -25,16 +33,19 @@ Loop:
if !disableSkipCI && ContainsSkipCI(p.Title) {
continue
}

// [ci skip]/[skip ci] in Commit message
if !disableSkipCI && ContainsSkipCI(p.Tip.Message) {
continue
}

// Filter pull request if the BaseBranch does not match the one specified in source
if request.Source.BaseBranch != "" && p.PullRequestObject.BaseRefName != request.Source.BaseBranch {
continue
}

// Filter out commits that are too old.
if !p.Tip.CommittedDate.Time.After(request.Version.CommittedDate) {
if !p.UpdatedDate().Time.After(request.Version.CommittedDate) {
continue
}

Expand Down Expand Up @@ -62,6 +73,11 @@ Loop:
continue
}

// Filter out drafts.
if request.Source.IgnoreDrafts && p.IsDraft {
continue
}

// Filter pull request if it does not have the required number of approved review(s).
if p.ApprovedReviewCount < request.Source.RequiredReviewApprovals {
continue
Expand Down
112 changes: 101 additions & 11 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, false, githubv4.PullRequestStateOpen),
createTestPR(2, "master", false, false, 0, nil, false, githubv4.PullRequestStateOpen),
createTestPR(3, "master", false, false, 0, nil, true, githubv4.PullRequestStateOpen),
createTestPR(4, "master", false, false, 0, nil, false, githubv4.PullRequestStateOpen),
createTestPR(5, "master", false, true, 0, nil, false, githubv4.PullRequestStateOpen),
createTestPR(6, "master", false, false, 0, nil, false, githubv4.PullRequestStateOpen),
createTestPR(7, "develop", false, false, 0, []string{"enhancement"}, false, githubv4.PullRequestStateOpen),
createTestPR(8, "master", false, false, 1, []string{"wontfix"}, false, githubv4.PullRequestStateOpen),
createTestPR(9, "master", false, false, 0, nil, false, githubv4.PullRequestStateOpen),
createTestPR(10, "master", false, false, 0, nil, false, githubv4.PullRequestStateClosed),
createTestPR(11, "master", false, false, 0, nil, false, githubv4.PullRequestStateMerged),
createTestPR(12, "master", false, false, 0, nil, false, githubv4.PullRequestStateOpen),
}
)

Expand Down Expand Up @@ -126,6 +130,35 @@ func TestCheck(t *testing.T) {
},
},

{
description: "check correctly ignores drafts when drafts are ignored",
source: resource.Source{
Repository: "itsdalmo/test-repository",
AccessToken: "oauthtoken",
IgnoreDrafts: true,
},
version: resource.NewVersion(testPullRequests[3]),
pullRequests: testPullRequests,
expected: resource.CheckResponse{
resource.NewVersion(testPullRequests[1]),
},
},

{
description: "check does not ignore drafts when drafts are not ignored",
source: resource.Source{
Repository: "itsdalmo/test-repository",
AccessToken: "oauthtoken",
IgnoreDrafts: false,
},
version: resource.NewVersion(testPullRequests[3]),
pullRequests: testPullRequests,
expected: resource.CheckResponse{
resource.NewVersion(testPullRequests[2]),
resource.NewVersion(testPullRequests[1]),
},
},

{
description: "check correctly ignores cross repo pull requests",
source: resource.Source{
Expand Down Expand Up @@ -185,12 +218,69 @@ 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[9]),
resource.NewVersion(testPullRequests[10]),
},
},
}

for _, tc := range tests {
t.Run(tc.description, func(t *testing.T) {
github := new(fakes.FakeGithub)
github.ListOpenPullRequestsReturns(tc.pullRequests, nil)
pullRequests := []*resource.PullRequest{}
filterStates := []githubv4.PullRequestState{githubv4.PullRequestStateOpen}
if len(tc.source.States) > 0 {
filterStates = tc.source.States
}
for i := range tc.pullRequests {
for j := range filterStates {
if filterStates[j] == tc.pullRequests[i].PullRequestObject.State {
pullRequests = append(pullRequests, tc.pullRequests[i])
break
}
}
}
github.ListPullRequestsReturns(pullRequests, nil)

for i, file := range tc.files {
github.ListModifiedFilesReturnsOnCall(i, file, nil)
Expand All @@ -202,7 +292,7 @@ func TestCheck(t *testing.T) {
if assert.NoError(t, err) {
assert.Equal(t, tc.expected, output)
}
assert.Equal(t, 1, github.ListOpenPullRequestsCallCount())
assert.Equal(t, 1, github.ListPullRequestsCallCount())
})
}
}
Expand Down
Loading