From 75df9b19d32b8766fc8f217bc349bdccc0dc5603 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 17 Dec 2016 15:34:38 -0700 Subject: [PATCH 001/106] update concourse pipeline to integration test --- .concourse.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.concourse.yml b/.concourse.yml index 3fd8f90..f51b59b 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -26,14 +26,13 @@ resources: type: pull-request source: access_token: {{github-access-token}} - every: true private_key: {{github-private-key}} repo: jtarchie/pullrequest-resource + base: master - name: merge-pull-requests type: pull-request-test source: access_token: {{github-access-token}} - every: true private_key: {{github-private-key}} base: test-merge repo: jtarchie/pullrequest-resource @@ -41,7 +40,11 @@ resources: jobs: - name: test-pr-merge plan: + - get: git-pr + passed: [ 'tests' ] + trigger: true - get: merge-pull-requests + trigger: true - put: merge-pull-requests params: path: merge-pull-requests @@ -123,7 +126,7 @@ jobs: - name: release plan: - get: git-pr - passed: [ tests ] + passed: [ 'test-pr-merge' ] - task: next-tag config: image: /var/vcap/packages/git_resource/rootfs From a7f4affc65882005b7ff55cbe670ffbf02784897 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 8 Jan 2017 00:30:37 -0700 Subject: [PATCH 002/106] fix markdown formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41ab40c..bb90cfe 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Set the status message for `concourse-ci` context on specified pull request. * `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. -* EXPERIMENTAL * +** EXPERIMENTAL ** These are experimental features according to [Github documentation](https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button). From d3eee494b1be16fc00cf7e3e73d7a3f9132e43dd Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 9 Jan 2017 17:01:29 -0700 Subject: [PATCH 003/106] link to updated example --- README.md | 52 +--------------------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/README.md b/README.md index bb90cfe..958ea9c 100644 --- a/README.md +++ b/README.md @@ -141,57 +141,7 @@ These are experimental features according to [Github documentation](https://deve ## Example pipeline -This is what I am currently using to test this resource on Concourse. - -```yaml -resource_types: -- name: pull-request - type: docker-image - source: - repository: jtarchie/pr -resources: -- name: repo - type: pull-request - source: - access_token: access_token - private_key: | - -----BEGIN RSA PRIVATE KEY----- - My private key. - -----END RSA PRIVATE KEY----- - repo: jtarchie/pullrequest-resource -jobs: -- name: test pull request - plan: - - get: repo - version: every - trigger: true - - put: repo - params: - path: repo - status: pending - - task: do something with git - config: - platform: linux - image: docker:///concourse/git-resource - run: - path: sh - args: - - -c - - cd repo && git --no-pager show - inputs: - - name: repo - path: "" - on_success: - put: repo - params: - path: repo - status: success - on_failure: - put: repo - params: - path: repo - status: failure -``` +Please see this repo's [pipeline](https://github.com/jtarchie/pullrequest-resource/blob/master/.concourse.yml) for a perfect example. ## Tests From 89a74393539b7fccfff59ba0ef0167a1b2982e68 Mon Sep 17 00:00:00 2001 From: Fabian Ruff Date: Fri, 24 Feb 2017 14:24:59 +0100 Subject: [PATCH 004/106] set the faraday client before requiring octokit. --- assets/lib/commands/base.rb | 8 +++++--- assets/lib/commands/in.rb | 1 - assets/lib/commands/out.rb | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index cf5c52e..135b8bc 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -1,11 +1,13 @@ require 'faraday' -require 'octokit' -require_relative '../input' - # httpclient and excon are the only Faraday adpater which support # the no_proxy environment variable atm +# NOTE: this has to be set before require octokit ::Faraday.default_adapter = :httpclient +require 'octokit' +require_relative '../input' + + module Commands class Base attr_reader :input diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 54d579a..61d7b40 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -1,6 +1,5 @@ #!/usr/bin/env ruby -require 'octokit' require 'English' require 'json' require_relative 'base' diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index 0ab3f54..ae32c69 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require 'json' -require 'octokit' require_relative 'base' require_relative '../repository' require_relative '../status' From f9f2787455fa21918e277468ee82dc829ca32096 Mon Sep 17 00:00:00 2001 From: Tony Rizko Date: Sun, 26 Feb 2017 20:10:25 -0800 Subject: [PATCH 005/106] Fix typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 958ea9c..ce6cc0b 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Set the status message for `concourse-ci` context on specified pull request. * `path`: *Required.* The path of the repository to reference the pull request. * `status`: *Required.* The status of success, failure, error, or pending. - * [`on_success`](https://concourse.ci/on-success-step.html) and [`on_falure`](https://concourse.ci/on-failure-step.html) triggers may be useful for you when you wanted to reflect build result to the PR (see the example below). + * [`on_success`](https://concourse.ci/on-success-step.html) and [`on_failure`](https://concourse.ci/on-failure-step.html) triggers may be useful for you when you wanted to reflect build result to the PR (see the example below). * `context`: *Optional.* The context on the specified pull request (defaults to `status`). Any context will be prepended with `concourse-ci`, so From a00e1a75a2f6b60238921fdc0ee5136acdbc7ded Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 27 Feb 2017 18:19:26 -0700 Subject: [PATCH 006/106] support git submodules and depth from `in` --- README.md | 8 ++++++ assets/lib/commands/base.rb | 1 - assets/lib/commands/in.rb | 22 ++++++++++++--- assets/lib/input.rb | 4 +++ spec/commands/in_spec.rb | 53 +++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ce6cc0b..11afab5 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,14 @@ git config --get pullrequest.basebranch # returns the base branch used for the p #### Parameters +* `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the + repository using the `--depth` option. + +* `git.submodules`: *Optional.* If `none`, submodules will not be + fetched. If specified as a list of paths, only the given paths will be + fetched. If not specified, or if `all` is explicitly specified, all + submodules are fetched. + * `fetch_merge`: *Optional*. If set to `true`, it will fetch what the result of PR would be otherwise it will fetch the origin branch. Defaults to `false`. diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index 135b8bc..c6e8fe6 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -7,7 +7,6 @@ require 'octokit' require_relative '../input' - module Commands class Base attr_reader :input diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 61d7b40..ccdc8ac 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -15,12 +15,12 @@ def initialize(destination:, input: Input.instance) end def output - id = pr['number'] + id = pr['number'] branch_ref = "pr-#{pr['head']['ref']}" raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - system("git clone --depth 1 #{uri} #{destination} 1>&2") + system("git clone #{depth_flag} #{uri} #{destination} 1>&2") raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? @@ -29,12 +29,20 @@ def output system <<-BASH git checkout #{branch_ref} 1>&2 - git submodule update --init --recursive 1>&2 git config --add pullrequest.url #{pr['html_url']} 1>&2 git config --add pullrequest.id #{pr['number']} 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 BASH + + case input.params.git.submodules + when 'all', nil + system("git submodule update --init --recursive #{depth_flag} 1>&2") + when Array + input.params.git.submodules.each do |path| + system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") + end + end end { @@ -64,6 +72,14 @@ def remote_ref def fetch_merge input.params.fetch_merge end + + def depth_flag + if depth = input.params.git.depth + "--depth #{depth}" + else + '--depth 1' + end + end end end diff --git a/assets/lib/input.rb b/assets/lib/input.rb index 85f0d2b..70b8ae9 100644 --- a/assets/lib/input.rb +++ b/assets/lib/input.rb @@ -12,6 +12,10 @@ def method def merge Merge.new(self['merge'] || {}) end + + def git + OpenStruct.new(self['git'] || {}) + end end def self.instance(payload: nil) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 4894dd6..7db3bd0 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -156,4 +156,57 @@ def dest_dir end end end + + fcontext 'with specific `git` params' do + before do + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', + html_url: 'http://example.com', number: 1, + head: { ref: 'foo' }, + base: { ref: 'master' }) + end + + def expect_arg(*args) + allow_any_instance_of(Commands::In).to receive(:system).and_call_original + expect_any_instance_of(Commands::In).to receive(:system).with(*args).and_call_original + end + + def dont_expect_arg(*args) + allow_any_instance_of(Commands::In).to receive(:system).and_call_original + expect_any_instance_of(Commands::In).not_to receive(:system).with(*args).and_call_original + end + + it 'gets all the submodules' do + expect_arg /git submodule update --init --recursive/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => {}) + end + + it 'gets all the submodules explicitly' do + expect_arg /git submodule update --init --recursive/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => 'all' } }) + end + + it 'gets no submodules' do + dont_expect_arg /git submodule update --init --recursive/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => 'none' } }) + end + + it 'get submodules with paths' do + expect_arg /git submodule update --init --recursive --depth 1 path1/ + expect_arg /git submodule update --init --recursive --depth 1 path2/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => %w(path1 path2) } }) + end + + it 'checkouts everything by depth' do + expect_arg /git submodule update --init --recursive --depth 100 path1/ + expect_arg /git clone --depth 100/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, + 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, + 'params' => { + 'git' => { + 'submodules' => %w(path1 path2), + 'depth' => 100 + } + }) + end + end end From 2ca4b6a226e7e82159e039e13e1a4bfb8451e49e Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 27 Feb 2017 18:29:23 -0700 Subject: [PATCH 007/106] support multiple contextes for batch `put` -- undocumented --- assets/lib/commands/out.rb | 21 ++++++++++++--------- spec/commands/out_spec.rb | 9 +++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index ae32c69..889ea5c 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -45,15 +45,18 @@ def output end atc_url = input.source.base_url || ENV['ATC_EXTERNAL_URL'] - context = params.context || 'status' - - Status.new( - state: params.status, - atc_url: atc_url, - sha: sha, - repo: repo, - context: context - ).create! + contextes = params.context || ['status'] + contextes = [contextes] unless contextes.is_a?(Array) + + contextes.each do |context| + Status.new( + state: params.status, + atc_url: atc_url, + sha: sha, + repo: repo, + context: context + ).create! + end if params.comment comment_path = File.join(destination, params.comment) diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 4c9d012..6584da5 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -234,6 +234,15 @@ def stub_json(method, uri, body) put('params' => { 'status' => 'success', 'path' => 'resource', 'context' => 'my-custom-context' }, 'source' => { 'repo' => 'jtarchie/test' }) end end + + context 'with setting multiple contextes' do + it 'sets the context for each' do + stub_status_post.with(body: hash_including('context' => 'concourse-ci/my-custom-context1')) + stub_status_post.with(body: hash_including('context' => 'concourse-ci/my-custom-context2')) + + put('params' => { 'status' => 'success', 'path' => 'resource', 'context' => ['my-custom-context1', 'my-custom-context2'] }, 'source' => { 'repo' => 'jtarchie/test' }) + end + end end context 'and the build failed' do From d6422b9f5e31ee88b18535458654540ce4b389f6 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 27 Feb 2017 18:40:26 -0700 Subject: [PATCH 008/106] add changelog for v21 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e58333e..3f1c4f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v21 @ 2/27/2017 + +* support multiple `contextes` in a single `put` +* specify `depth` and `submodule` on a `git clone` +* fix typo in README [Thanks @trizko](https://github.com/jtarchie/pullrequest-resource/pull/57) +* fix issue with Github API proxying [Thanks @databus](https://github.com/jtarchie/pullrequest-resource/pull/56) + # v20 @ 12/17/2016 * disable PRs that were made from forks with `disable_forks` [Thanks @henrytk](https://github.com/jtarchie/pullrequest-resource/issues/43) From 698106d7b91cb186451fe50c732f0dfff9471a1b Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 1 Mar 2017 21:25:16 -0700 Subject: [PATCH 009/106] remove default depth --- assets/lib/commands/in.rb | 2 +- spec/commands/in_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index ccdc8ac..816152b 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -77,7 +77,7 @@ def depth_flag if depth = input.params.git.depth "--depth #{depth}" else - '--depth 1' + '' end end end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 7db3bd0..e0eaf53 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -191,8 +191,8 @@ def dont_expect_arg(*args) end it 'get submodules with paths' do - expect_arg /git submodule update --init --recursive --depth 1 path1/ - expect_arg /git submodule update --init --recursive --depth 1 path2/ + expect_arg /git submodule update --init --recursive path1/ + expect_arg /git submodule update --init --recursive path2/ get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => %w(path1 path2) } }) end From f41a8a157c45bad61c0d413e6fd1a92b166e670c Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 4 Mar 2017 14:12:20 -0700 Subject: [PATCH 010/106] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 44a519f..60ea382 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 JT Archie +Copyright (c) 2017 JT Archie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e48e45f1d6fa54d143f78d67d284fb1aebed7fe5 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 9 Mar 2017 07:50:17 -0700 Subject: [PATCH 011/106] support label filtering --- README.md | 3 +++ assets/lib/filters/label.rb | 20 +++++++++++++++++ assets/lib/repository.rb | 3 ++- spec/filters/label_spec.rb | 43 +++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 assets/lib/filters/label.rb create mode 100644 spec/filters/label_spec.rb diff --git a/README.md b/README.md index 11afab5..bdd8189 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ resource_types: * `disable_forks`: *Optional.* If set to `true`, it will filter out pull requests that were created via users that forked from your repo. +* `label`: *Optional.* If set to a string it will only return pull requests that have been +marked with that specific label. It is case insensitive. + * `username`: *Optional.* Username for HTTP(S) auth when pulling/pushing. This is needed when only HTTP/HTTPS protocol for git is available (which does not support private key auth) and auth is required. diff --git a/assets/lib/filters/label.rb b/assets/lib/filters/label.rb new file mode 100644 index 0000000..4f2e2db --- /dev/null +++ b/assets/lib/filters/label.rb @@ -0,0 +1,20 @@ +module Filters + class Label + def initialize(pull_requests:, input: Input.instance) + @pull_requests = pull_requests + @input = input + end + + def pull_requests + if @input.source.label + @memoized ||= @pull_requests.select do |pr| + issue = Octokit.issue(@input.source.repo, pr.id) + labels = issue[:labels] || [] + labels.find { |l| l['name'].to_s.casecmp(@input.source.label.to_s.downcase).zero? } + end + else + @pull_requests + end + end + end +end diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index b9bcd43..a8ad96f 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -1,11 +1,12 @@ require_relative 'filters/all' require_relative 'filters/fork' +require_relative 'filters/label' require_relative 'filters/path' class Repository attr_reader :name - def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork]) + def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label]) @filters = filters @name = name @input = input diff --git a/spec/filters/label_spec.rb b/spec/filters/label_spec.rb new file mode 100644 index 0000000..65dd0aa --- /dev/null +++ b/spec/filters/label_spec.rb @@ -0,0 +1,43 @@ +require_relative '../../assets/lib/filters/label' +require_relative '../../assets/lib/pull_request' +require 'webmock/rspec' + +describe Filters::Label do + let(:ignore_pr) do + PullRequest.new(pr: { 'number' => 1 }) + end + + let(:pr) do + PullRequest.new(pr: { 'number' => 2 }) + end + + let(:pull_requests) { [ignore_pr, pr] } + + def stub_json(uri, body) + stub_request(:get, uri) + .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) + end + + context 'when no label is specified' do + it 'does not filter' do + payload = { 'source' => { 'repo' => 'user/repo' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + end + + context 'when the label for filtering is provided' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/issues/1}, 'labels' => [{ 'name' => 'feature' }]) + stub_json(%r{https://api.github.com/repos/user/repo/issues/2}, 'labels' => [{ 'name' => 'bug' }]) + end + + it 'only returns PRs with that label' do + payload = { 'source' => { 'repo' => 'user/repo', 'label' => 'bug' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end +end From 3794ed2439ee33888d6ae5d5a20834bf7aafde5d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 13 Apr 2017 07:05:35 -0600 Subject: [PATCH 012/106] Use docker-image resource --- .concourse.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.concourse.yml b/.concourse.yml index f51b59b..7c77508 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -129,7 +129,10 @@ jobs: passed: [ 'test-pr-merge' ] - task: next-tag config: - image: /var/vcap/packages/git_resource/rootfs + image_resource: + type: docker-image + source: + repository: concourse/git-resource platform: linux inputs: - name: git-pr From 0bbf3c7a5f9c80fee4c40373aec52bf7db5d03fd Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 13 Apr 2017 07:06:25 -0600 Subject: [PATCH 013/106] remove secrets --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2dcb1c7..9fc544b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ example/ .bundle bin +.secrets.yml From 3d07b54c8443c5a11b1f294898dce1b120ab315a Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 13 Apr 2017 07:25:16 -0600 Subject: [PATCH 014/106] support parameter to skip git clone on `put` --- README.md | 3 +++ assets/lib/commands/in.rb | 28 +++++++++++++++------------- spec/commands/in_spec.rb | 25 ++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bdd8189..2c56113 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,9 @@ git config --get pullrequest.basebranch # returns the base branch used for the p would be otherwise it will fetch the origin branch. Defaults to `false`. +* `skip`: *Optional*. If set to `true`, it will skip checking out and setting up + meta information. Only use with `get_params` to make it `put` happen *faster*. + ### `out`: Update the status of a pull request Set the status message for `concourse-ci` context on specified pull request. diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 816152b..3a3f451 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -20,27 +20,29 @@ def output raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - system("git clone #{depth_flag} #{uri} #{destination} 1>&2") + unless input.params.skip + system("git clone #{depth_flag} #{uri} #{destination} 1>&2") - raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? + raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? - Dir.chdir(destination) do - raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") + Dir.chdir(destination) do + raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") - system <<-BASH + system <<-BASH git checkout #{branch_ref} 1>&2 git config --add pullrequest.url #{pr['html_url']} 1>&2 git config --add pullrequest.id #{pr['number']} 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 - BASH - - case input.params.git.submodules - when 'all', nil - system("git submodule update --init --recursive #{depth_flag} 1>&2") - when Array - input.params.git.submodules.each do |path| - system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") + BASH + + case input.params.git.submodules + when 'all', nil + system("git submodule update --init --recursive #{depth_flag} 1>&2") + when Array + input.params.git.submodules.each do |path| + system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") + end end end end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index e0eaf53..309a01b 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -98,6 +98,29 @@ def dest_dir end.to raise_error('git clone failed') end end + + context 'disabling `git` operations' do + def dest_dir + @dest_dir ||= Dir.mktmpdir + end + + before(:all) do + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) + @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'skip' => true }) + end + + it 'can be disabled so' do + expect(git('log', dest_dir)).to eq '' + end + + it 'returns the correct JSON metadata' do + expect(@output).to eq('version' => { 'ref' => @ref, 'pr' => '1' }, + 'metadata' => [{ + 'name' => 'url', + 'value' => 'http://example.com' + }]) + end + end end context 'when the PR is meregable' do @@ -157,7 +180,7 @@ def dest_dir end end - fcontext 'with specific `git` params' do + context 'with specific `git` params' do before do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, From b6001d8fd6b78c856f5a9cbd5a3edf57018bf61d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 16 Apr 2017 14:45:41 -0600 Subject: [PATCH 015/106] Revert "support parameter to skip git clone on `put`" This reverts commit 3d07b54c8443c5a11b1f294898dce1b120ab315a. --- README.md | 3 --- assets/lib/commands/in.rb | 28 +++++++++++++--------------- spec/commands/in_spec.rb | 25 +------------------------ 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 2c56113..bdd8189 100644 --- a/README.md +++ b/README.md @@ -125,9 +125,6 @@ git config --get pullrequest.basebranch # returns the base branch used for the p would be otherwise it will fetch the origin branch. Defaults to `false`. -* `skip`: *Optional*. If set to `true`, it will skip checking out and setting up - meta information. Only use with `get_params` to make it `put` happen *faster*. - ### `out`: Update the status of a pull request Set the status message for `concourse-ci` context on specified pull request. diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 3a3f451..816152b 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -20,29 +20,27 @@ def output raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - unless input.params.skip - system("git clone #{depth_flag} #{uri} #{destination} 1>&2") + system("git clone #{depth_flag} #{uri} #{destination} 1>&2") - raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? + raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? - Dir.chdir(destination) do - raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") + Dir.chdir(destination) do + raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") - system <<-BASH + system <<-BASH git checkout #{branch_ref} 1>&2 git config --add pullrequest.url #{pr['html_url']} 1>&2 git config --add pullrequest.id #{pr['number']} 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 - BASH - - case input.params.git.submodules - when 'all', nil - system("git submodule update --init --recursive #{depth_flag} 1>&2") - when Array - input.params.git.submodules.each do |path| - system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") - end + BASH + + case input.params.git.submodules + when 'all', nil + system("git submodule update --init --recursive #{depth_flag} 1>&2") + when Array + input.params.git.submodules.each do |path| + system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") end end end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 309a01b..e0eaf53 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -98,29 +98,6 @@ def dest_dir end.to raise_error('git clone failed') end end - - context 'disabling `git` operations' do - def dest_dir - @dest_dir ||= Dir.mktmpdir - end - - before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) - @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'skip' => true }) - end - - it 'can be disabled so' do - expect(git('log', dest_dir)).to eq '' - end - - it 'returns the correct JSON metadata' do - expect(@output).to eq('version' => { 'ref' => @ref, 'pr' => '1' }, - 'metadata' => [{ - 'name' => 'url', - 'value' => 'http://example.com' - }]) - end - end end context 'when the PR is meregable' do @@ -180,7 +157,7 @@ def dest_dir end end - context 'with specific `git` params' do + fcontext 'with specific `git` params' do before do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, From a3bf0871adce6b853a899a6e440543b4434abb36 Mon Sep 17 00:00:00 2001 From: "C.J. Jameson" Date: Thu, 8 Jun 2017 18:35:32 -0700 Subject: [PATCH 016/106] readme: Tighten up default specification TODO: edit dockerhub readme to match --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bdd8189..8ab628e 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ resource_types: * `api_endpoint`: *Optional.* If the repository is located on a GitHub Enterprise instance you need to specify the base api endpoint (e.g. "https://\/api/v3/"). -* `disable_forks`: *Optional.* If set to `true`, it will filter out pull requests that - were created via users that forked from your repo. +* `disable_forks`: *Optional*, default false. If set to `true`, it will filter + out pull requests that were created via users that forked from your repo. * `label`: *Optional.* If set to a string it will only return pull requests that have been marked with that specific label. It is case insensitive. @@ -116,14 +116,12 @@ git config --get pullrequest.basebranch # returns the base branch used for the p * `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the repository using the `--depth` option. -* `git.submodules`: *Optional.* If `none`, submodules will not be +* `git.submodules`: *Optional*, default `all`. If `none`, submodules will not be fetched. If specified as a list of paths, only the given paths will be - fetched. If not specified, or if `all` is explicitly specified, all - submodules are fetched. + fetched. If `all`, all submodules are fetched. -* `fetch_merge`: *Optional*. If set to `true`, it will fetch what the result of PR - would be otherwise it will fetch the origin branch. - Defaults to `false`. +* `fetch_merge`: *Optional*, default `false`. If set to `true`, it will fetch + what the result of PR would be otherwise it will fetch the origin branch. ### `out`: Update the status of a pull request From d20285c973c22849d4d03569ea5aa45816e31b3e Mon Sep 17 00:00:00 2001 From: Richard Downer Date: Thu, 15 Jun 2017 13:14:55 +1200 Subject: [PATCH 017/106] typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ab628e..c0683a6 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ resource_types: Example: `jtarchie/pullrequest-resource` * `access_token`: *Required.* An access token with `repo:status` access is - required for *public* repos. An access tocken with `repo` access is required for + required for *public* repos. An access token with `repo` access is required for *private* repos. * `uri`: *Optional.* The URI to the github repo. By default, it assumes From 8874cc8ffc1ba13ed27e9453b4c92fbeac11790a Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 25 Jun 2017 10:47:24 -0600 Subject: [PATCH 018/106] add support for git-lfs #81 --- Dockerfile | 18 ++++++++++-------- README.md | 3 +++ assets/lib/commands/in.rb | 5 +++++ scripts/install_git_lfs.sh | 19 +++++++++++++++++++ spec/commands/in_spec.rb | 12 ++++++++++++ 5 files changed, 49 insertions(+), 8 deletions(-) create mode 100755 scripts/install_git_lfs.sh diff --git a/Dockerfile b/Dockerfile index 2ec1e18..fc2cffa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,16 @@ FROM alpine -RUN apk add --update \ - ruby \ - perl \ - jq \ - git \ - openssh-client \ - ruby-json \ - ca-certificates +RUN apk add --update ca-certificates +RUN apk add --update curl +RUN apk add --update git +RUN apk add --update jq +RUN apk add --update openssh-client +RUN apk add --update perl +RUN apk add --update ruby +RUN apk add --update ruby-json RUN gem install octokit httpclient --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* +ADD scripts/install_git_lfs.sh install_git_lfs.sh +RUN ./install_git_lfs.sh diff --git a/README.md b/README.md index c0683a6..d2cc845 100644 --- a/README.md +++ b/README.md @@ -120,9 +120,12 @@ git config --get pullrequest.basebranch # returns the base branch used for the p fetched. If specified as a list of paths, only the given paths will be fetched. If `all`, all submodules are fetched. +* `git.disable_lfs`: *Optional.* If `true`, will not fetch Git LFS files. + * `fetch_merge`: *Optional*, default `false`. If set to `true`, it will fetch what the result of PR would be otherwise it will fetch the origin branch. + ### `out`: Update the status of a pull request Set the status message for `concourse-ci` context on specified pull request. diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 816152b..eb95c7b 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -43,6 +43,11 @@ def output system("git submodule update --init --recursive #{depth_flag} #{path} 1>&2") end end + + unless input.params.git.disable_lfs + system('git lfs fetch 1>&2') + system('git lfs checkout 1>&2') + end end { diff --git a/scripts/install_git_lfs.sh b/scripts/install_git_lfs.sh new file mode 100755 index 0000000..e8ee9f3 --- /dev/null +++ b/scripts/install_git_lfs.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -eu + +_main() { + local tmpdir + tmpdir="$(mktemp -d git_lfs_install.XXXXXX)" + + cd "$tmpdir" + curl -Lo git.tar.gz https://github.com/github/git-lfs/releases/download/v2.1.1/git-lfs-linux-amd64-2.1.1.tar.gz + gunzip git.tar.gz + tar xf git.tar + mv git-lfs-2.1.1/git-lfs /usr/bin + cd .. + rm -rf "$tmpdir" + git lfs install --skip-smudge +} + +_main "$@" diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index e0eaf53..cd7c7b1 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -175,6 +175,18 @@ def dont_expect_arg(*args) expect_any_instance_of(Commands::In).not_to receive(:system).with(*args).and_call_original end + it 'gets lfs' do + expect_arg /git lfs fetch/ + expect_arg /git lfs checkout/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => {}) + end + + it 'disables lfs' do + dont_expect_arg /git lfs fetch/ + dont_expect_arg /git lfs checkout/ + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => {'git' => {'disable_lfs' => true}}) + end + it 'gets all the submodules' do expect_arg /git submodule update --init --recursive/ get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => {}) From 2815e41eb11fa393229bb46e9121844721b9b5dd Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 25 Jun 2017 10:53:33 -0600 Subject: [PATCH 019/106] add correct Dockerfile for testing --- Dockerfile.test | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Dockerfile.test b/Dockerfile.test index 30d6015..f231171 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,17 +1,19 @@ FROM alpine -RUN apk add --update \ - ruby \ - perl \ - jq \ - git \ - openssh-client \ - ruby-json \ - ca-certificates +RUN apk add --update ca-certificates +RUN apk add --update curl +RUN apk add --update git +RUN apk add --update jq +RUN apk add --update openssh-client +RUN apk add --update perl +RUN apk add --update ruby +RUN apk add --update ruby-json RUN gem install octokit httpclient --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* +ADD scripts/install_git_lfs.sh install_git_lfs.sh +RUN ./install_git_lfs.sh RUN apk add --update \ ruby-bundler \ From c590649ec48da5c358da170ce5cff3693edd04db Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 26 Jun 2017 19:27:43 -0600 Subject: [PATCH 020/106] backfill CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f1c4f8..f44d4e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# v24 @ 6/26/2017 + +* `README.md` updates from @cjcjameson and @richarddowner +* Add support for `git-lfs` + +# v23 @ 3/9/2017 + +* update LICENSE file +* support filtering PRs with a specific `label` + +# v22 @ 3/1/2017 + +* remove default `--depth 1` when none is specified + # v21 @ 2/27/2017 * support multiple `contextes` in a single `put` From 0a8fac172d8542ef40f05ae3d7bafbbf57974c43 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Fri, 21 Jul 2017 13:23:25 -0600 Subject: [PATCH 021/106] no longer experimental from Github docs --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index d2cc845..4050e88 100644 --- a/README.md +++ b/README.md @@ -141,11 +141,7 @@ Set the status message for `concourse-ci` context on specified pull request. (defaults to `status`). Any context will be prepended with `concourse-ci`, so a context of `unit-tests` will appear as `concourse-ci/unit-tests` on Github. -* `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. - -** EXPERIMENTAL ** - -These are experimental features according to [Github documentation](https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button). +* `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. * `merge.method`: *Optional.* Use this to merge the PR into the target branch of the PR. There are three available merge methods -- `merge`, `squash`, or `rebase`. Please this [doc](https://developer.github.com/changes/2016-09-26-pull-request-merge-api-update/) for more information. From 6e910a315e3bccbbcdabff663f28a9b31cb60bb0 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 28 Jun 2017 21:49:56 -0600 Subject: [PATCH 022/106] use caching for HTTP requests --- Dockerfile | 2 +- Dockerfile.test | 2 +- Gemfile | 1 + Gemfile.lock | 5 ++++- assets/lib/commands/base.rb | 16 +++++++++++----- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index fc2cffa..1b9b6df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN apk add --update openssh-client RUN apk add --update perl RUN apk add --update ruby RUN apk add --update ruby-json -RUN gem install octokit httpclient --no-rdoc --no-ri +RUN gem install octokit httpclient faraday-http-cache --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* diff --git a/Dockerfile.test b/Dockerfile.test index f231171..435ea57 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -8,7 +8,7 @@ RUN apk add --update openssh-client RUN apk add --update perl RUN apk add --update ruby RUN apk add --update ruby-json -RUN gem install octokit httpclient --no-rdoc --no-ri +RUN gem install octokit httpclient faraday-http-cache --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* diff --git a/Gemfile b/Gemfile index 418a11b..4b333f0 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' gem 'octokit' gem 'httpclient' +gem 'faraday-http-cache' group :development do gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock index af19433..8ca4baa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,6 +23,8 @@ GEM eventmachine_httpserver (0.2.1) faraday (0.9.2) multipart-post (>= 1.2, < 3) + faraday-http-cache (2.0.0) + faraday (~> 0.8) hashdiff (0.3.0) http_parser.rb (0.6.0) httpclient (2.8.2.4) @@ -85,6 +87,7 @@ PLATFORMS ruby DEPENDENCIES + faraday-http-cache httpclient octokit pry @@ -95,4 +98,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.13.6 + 1.14.6 diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index c6e8fe6..679ba2e 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -1,10 +1,16 @@ require 'faraday' -# httpclient and excon are the only Faraday adpater which support -# the no_proxy environment variable atm -# NOTE: this has to be set before require octokit -::Faraday.default_adapter = :httpclient - require 'octokit' +require 'faraday-http-cache' + +stack = Faraday::RackBuilder.new do |builder| + builder.use Faraday::HttpCache, serializer: Marshal, shared_cache: false + builder.use Octokit::Response::RaiseError + # httpclient and excon are the only Faraday adpater which support + # the no_proxy environment variable atm + builder.adapter :httpclient +end +Octokit.middleware = stack + require_relative '../input' module Commands From cbd2794d69d5467acf36e836e805a93408257071 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 20 Jul 2017 17:45:07 -0600 Subject: [PATCH 023/106] set file storer for caching --- Dockerfile | 2 +- Dockerfile.test | 2 +- Gemfile | 1 + Gemfile.lock | 14 +++++++++++++- assets/lib/commands/base.rb | 5 ++++- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1b9b6df..40e9e43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN apk add --update openssh-client RUN apk add --update perl RUN apk add --update ruby RUN apk add --update ruby-json -RUN gem install octokit httpclient faraday-http-cache --no-rdoc --no-ri +RUN gem install octokit activesupport httpclient faraday-http-cache --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* diff --git a/Dockerfile.test b/Dockerfile.test index 435ea57..f01bffb 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -8,7 +8,7 @@ RUN apk add --update openssh-client RUN apk add --update perl RUN apk add --update ruby RUN apk add --update ruby-json -RUN gem install octokit httpclient faraday-http-cache --no-rdoc --no-ri +RUN gem install octokit activesupport httpclient faraday-http-cache --no-rdoc --no-ri ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* diff --git a/Gemfile b/Gemfile index 4b333f0..f7e0b4c 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source 'https://rubygems.org' gem 'octokit' gem 'httpclient' gem 'faraday-http-cache' +gem 'activesupport' group :development do gem 'pry' diff --git a/Gemfile.lock b/Gemfile.lock index 8ca4baa..8b70355 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,16 @@ GEM remote: https://rubygems.org/ specs: + activesupport (5.1.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) addressable (2.5.0) public_suffix (~> 2.0, >= 2.0.2) ast (2.3.0) coderay (1.1.1) + concurrent-ruby (1.0.5) cookiejar (0.3.3) crack (0.4.3) safe_yaml (~> 1.0.0) @@ -28,7 +34,9 @@ GEM hashdiff (0.3.0) http_parser.rb (0.6.0) httpclient (2.8.2.4) + i18n (0.8.6) method_source (0.8.2) + minitest (5.10.2) multi_json (1.12.1) multipart-post (2.0.0) octokit (4.6.0) @@ -77,6 +85,9 @@ GEM addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 0.10) slop (3.6.0) + thread_safe (0.3.6) + tzinfo (1.2.3) + thread_safe (~> 0.1) unicode-display_width (1.1.1) webmock (2.1.0) addressable (>= 2.3.6) @@ -87,6 +98,7 @@ PLATFORMS ruby DEPENDENCIES + activesupport faraday-http-cache httpclient octokit @@ -98,4 +110,4 @@ DEPENDENCIES webmock BUNDLED WITH - 1.14.6 + 1.15.1 diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index 679ba2e..66873e8 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -1,9 +1,12 @@ require 'faraday' require 'octokit' require 'faraday-http-cache' +require 'active_support/cache' +require 'active_support/cache/file_store' stack = Faraday::RackBuilder.new do |builder| - builder.use Faraday::HttpCache, serializer: Marshal, shared_cache: false + storer = ActiveSupport::Cache::FileStore.new('/tmp', namespace: 'pullrequest') + builder.use Faraday::HttpCache, store: storer, serializer: Marshal, shared_cache: true builder.use Octokit::Response::RaiseError # httpclient and excon are the only Faraday adpater which support # the no_proxy environment variable atm From 22c00c9cfa27ec6e18bbc71438e4ad13e8aa464a Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 20 Jul 2017 18:19:05 -0600 Subject: [PATCH 024/106] add test for pagination caching --- spec/commands/check_spec.rb | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 96e785c..52104cd 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -85,4 +85,40 @@ def stub_json(uri, body) end end end + + context 'when paginating through many PRs' do + def stub_body_json(uri, body, headers={}) + stub_request(:get, uri) + .to_return(headers: { + 'Content-Type' => 'application/json', + 'ETag' => Digest::MD5.hexdigest(body.to_json), + }.merge(headers), body: body.to_json) + end + + def stub_cache_json(uri) + stub_request(:get, uri) + .to_return(status: 304, body: '[]') + end + + it 'uses the cache that already exists' do + pull_requests = (1..100).map do |i| + { number: i, head: { sha: "abcdef-#{i}", repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } } + end + stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], { + 'Link' => "; rel=\"next\"" + }) + stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) + + first_prs = check('source' => { 'repo' => 'jtarchie/test' } ) + expect(first_prs.length).to eq 100 + Billy.proxy.reset + + stub_cache_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open') + stub_cache_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2') + second_prs = check('source' => { 'repo' => 'jtarchie/test' } ) + + expect(first_prs).to eq second_prs + # expect A == B + end + end end From d2347925dbcd573292d56f8eef97f1e2db31453d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 31 Jul 2017 20:52:53 -0600 Subject: [PATCH 025/106] do not share the cache --- assets/lib/commands/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index 66873e8..3affe17 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -6,7 +6,7 @@ stack = Faraday::RackBuilder.new do |builder| storer = ActiveSupport::Cache::FileStore.new('/tmp', namespace: 'pullrequest') - builder.use Faraday::HttpCache, store: storer, serializer: Marshal, shared_cache: true + builder.use Faraday::HttpCache, store: storer, serializer: Marshal, shared_cache: false builder.use Octokit::Response::RaiseError # httpclient and excon are the only Faraday adpater which support # the no_proxy environment variable atm From b031a883bd477ee5c6dc4a59fc8dab099471771f Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 1 Aug 2017 17:55:05 -0600 Subject: [PATCH 026/106] add CHANGELOG v25 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f44d4e2..d69ca0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v25 @ 8/1/2017 + +* support caching of API requests to Github. This decreases hitting the +rate limit per hour. It does not reduce the number of request, though. + # v24 @ 6/26/2017 * `README.md` updates from @cjcjameson and @richarddowner From aac5801eece73ddfa7f7732708e56e9226824dee Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 1 Aug 2017 18:33:39 -0600 Subject: [PATCH 027/106] rubocop -a --- spec/commands/check_spec.rb | 14 ++++++-------- spec/commands/in_spec.rb | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 52104cd..7a4c888 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -87,12 +87,12 @@ def stub_json(uri, body) end context 'when paginating through many PRs' do - def stub_body_json(uri, body, headers={}) + def stub_body_json(uri, body, headers = {}) stub_request(:get, uri) .to_return(headers: { 'Content-Type' => 'application/json', - 'ETag' => Digest::MD5.hexdigest(body.to_json), - }.merge(headers), body: body.to_json) + 'ETag' => Digest::MD5.hexdigest(body.to_json) + }.merge(headers), body: body.to_json) end def stub_cache_json(uri) @@ -104,18 +104,16 @@ def stub_cache_json(uri) pull_requests = (1..100).map do |i| { number: i, head: { sha: "abcdef-#{i}", repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } } end - stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], { - 'Link' => "; rel=\"next\"" - }) + stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], 'Link' => '; rel="next"') stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) - first_prs = check('source' => { 'repo' => 'jtarchie/test' } ) + first_prs = check('source' => { 'repo' => 'jtarchie/test' }) expect(first_prs.length).to eq 100 Billy.proxy.reset stub_cache_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open') stub_cache_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2') - second_prs = check('source' => { 'repo' => 'jtarchie/test' } ) + second_prs = check('source' => { 'repo' => 'jtarchie/test' }) expect(first_prs).to eq second_prs # expect A == B diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index cd7c7b1..3f20fb2 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -184,7 +184,7 @@ def dont_expect_arg(*args) it 'disables lfs' do dont_expect_arg /git lfs fetch/ dont_expect_arg /git lfs checkout/ - get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => {'git' => {'disable_lfs' => true}}) + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'disable_lfs' => true } }) end it 'gets all the submodules' do From b60fece2a67c1231d06547f6a038e9b8ed80a1e3 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 10 Aug 2017 10:47:03 -0600 Subject: [PATCH 028/106] link to @drnic example --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4050e88..7177bff 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,8 @@ Set the status message for `concourse-ci` context on specified pull request. Please see this repo's [pipeline](https://github.com/jtarchie/pullrequest-resource/blob/master/.concourse.yml) for a perfect example. +There's also an [example](https://github.com/starkandwayne/concourse-pullrequest-playtime) by @starkandwayne. + ## Tests Requires `ruby` to be installed. From 7c82a926e657eed1e29e437b72d41d6bf4f90a49 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 13 Aug 2017 20:44:57 -0600 Subject: [PATCH 029/106] whitelist build envs for context --- assets/lib/commands/out.rb | 9 ++++++++- spec/commands/out_spec.rb | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index 889ea5c..7972d6e 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -54,7 +54,7 @@ def output atc_url: atc_url, sha: sha, repo: repo, - context: context + context: whitelist(context: context) ).create! end @@ -85,6 +85,13 @@ def output private + def whitelist(context:) + %w(BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL).each do |name| + context.gsub!("$#{name}", ENV[name] || '') + end + context + end + def params input.params end diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 6584da5..9f20123 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -233,6 +233,18 @@ def stub_json(method, uri, body) put('params' => { 'status' => 'success', 'path' => 'resource', 'context' => 'my-custom-context' }, 'source' => { 'repo' => 'jtarchie/test' }) end + + context 'with build specific environment variables' do + %w(BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL).each do |env_var| + it "evaluates #{env_var} for a context" do + ENV[env_var] = 'build-env-var' + stub_status_post.with(body: hash_including('context' => 'concourse-ci/build-env-var')) + + put('params' => { 'status' => 'success', 'path' => 'resource', 'context' => "$#{env_var}" }, 'source' => { 'repo' => 'jtarchie/test' }) + ENV[env_var] = nil + end + end + end end context 'with setting multiple contextes' do From 6553477d5cb9372766cdcf473093551e252b3a93 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 13 Aug 2017 20:53:45 -0600 Subject: [PATCH 030/106] update gems --- Gemfile.lock | 68 ++++++++++++++++++++++--------------------- spec/support/proxy.rb | 11 ------- 2 files changed, 35 insertions(+), 44 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8b70355..daf23d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,20 +1,19 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.1.2) + activesupport (5.1.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.0) - public_suffix (~> 2.0, >= 2.0.2) + addressable (2.4.0) ast (2.3.0) coderay (1.1.1) concurrent-ruby (1.0.5) cookiejar (0.3.3) crack (0.4.3) safe_yaml (~> 1.0.0) - diff-lcs (1.2.5) + diff-lcs (1.3) em-http-request (1.1.5) addressable (>= 2.3.4) cookiejar (!= 0.3.1) @@ -23,73 +22,76 @@ GEM http_parser.rb (>= 0.6.0) em-socksify (0.3.1) eventmachine (>= 1.0.0.beta.4) - em-synchrony (1.0.5) + em-synchrony (1.0.6) eventmachine (>= 1.0.0.beta.1) eventmachine (1.0.9.1) eventmachine_httpserver (0.2.1) - faraday (0.9.2) + faraday (0.12.2) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) - hashdiff (0.3.0) + hashdiff (0.3.5) http_parser.rb (0.6.0) - httpclient (2.8.2.4) + httpclient (2.8.3) i18n (0.8.6) method_source (0.8.2) - minitest (5.10.2) + minitest (5.10.3) multi_json (1.12.1) multipart-post (2.0.0) - octokit (4.6.0) + octokit (4.7.0) sawyer (~> 0.8.0, >= 0.5.3) - parser (2.3.1.4) + parallel (1.12.0) + parser (2.4.0.0) ast (~> 2.2) powerpack (0.1.1) pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - public_suffix (2.0.4) - puffing-billy (0.9.1) - addressable + puffing-billy (0.10.0) + addressable (~> 2.4.0) em-http-request (~> 1.1.0) em-synchrony eventmachine (~> 1.0.4) eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json - rainbow (2.1.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + rainbow (2.2.2) + rake + rake (12.0.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-support (3.5.0) - rubocop (0.45.0) - parser (>= 2.3.1.1, < 3.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rubocop (0.49.1) + parallel (~> 1.10) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.8.0) + rubocop-rspec (1.15.1) rubocop (>= 0.42.0) ruby-progressbar (1.8.1) safe_yaml (1.0.4) - sawyer (0.8.0) + sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) - faraday (~> 0.8, < 0.10) + faraday (~> 0.8, < 1.0) slop (3.6.0) thread_safe (0.3.6) tzinfo (1.2.3) thread_safe (~> 0.1) - unicode-display_width (1.1.1) - webmock (2.1.0) + unicode-display_width (1.3.0) + webmock (3.0.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff diff --git a/spec/support/proxy.rb b/spec/support/proxy.rb index 7b334c4..3890d2b 100644 --- a/spec/support/proxy.rb +++ b/spec/support/proxy.rb @@ -6,14 +6,3 @@ c.non_successful_error_level = :error c.non_whitelisted_requests_disabled = true end - -module StubCacheHandler - def handle_request(method, url, headers, body) - if response = super - Billy::Cache.instance.store(method.downcase, url, headers, body, response[:headers], response[:status], response[:content]) - response - end - end -end - -Billy::StubHandler.prepend(StubCacheHandler) From 7591feaf44f9222a1e20edebc27ec49f82014900 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 21 Aug 2017 21:03:14 -0600 Subject: [PATCH 031/106] changelog for v26 --- CHANGELOG.md | 4 ++++ README.md | 3 +++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d69ca0b..0f5f81c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v26 @ 8/21/2017 + +* Support evaluating the concourse BUILD environment variables in a context. + # v25 @ 8/1/2017 * support caching of API requests to Github. This decreases hitting the diff --git a/README.md b/README.md index 7177bff..8586f05 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,9 @@ Set the status message for `concourse-ci` context on specified pull request. (defaults to `status`). Any context will be prepended with `concourse-ci`, so a context of `unit-tests` will appear as `concourse-ci/unit-tests` on Github. + This supports the [build environment](http://concourse.ci/implementing-resources.html#resource-metadata) + variables provided by concourse. For example, `context: $BUILD_JOB_NAME` will set the context to the job name. + * `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. * `merge.method`: *Optional.* Use this to merge the PR into the target branch of the PR. There are three available merge methods -- `merge`, `squash`, or `rebase`. Please this [doc](https://developer.github.com/changes/2016-09-26-pull-request-merge-api-update/) for more information. From 0c911f35c961cedef7f91de6b53a745f5e899295 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 21 Aug 2017 21:55:00 -0600 Subject: [PATCH 032/106] create PR for tests --- .concourse.yml | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/.concourse.yml b/.concourse.yml index 7c77508..eda08a4 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -38,11 +38,62 @@ resources: repo: jtarchie/pullrequest-resource jobs: - - name: test-pr-merge + - name: create-pr plan: - get: git-pr passed: [ 'tests' ] trigger: true + - task: create + config: + platform: linux + params: + GITHUB_ACCESS_TOKEN: {{github-access-token}} + image_resource: + type: docker-image + source: + repository: jtarchie/pr + tag: test + run: + path: ruby + args: + - -e + - | + require 'octokit' + + Octokit.access_token = ENV['GITHUB_ACCESS_TOKEN'] + + repo_name = ENV['REPO_NAME'] || 'jtarchie/pullrequest-resource' + base_branch = ENV['BASE_BRANCH'] || 'test-merge' + test_branch = "test-merge-#{Time.now.to_i}" + + sha = Octokit.ref(repo_name, "heads/#{base_branch}").object.sha + Octokit.create_ref(repo_name, "heads/#{test_branch}", sha) + blob_sha = Octokit.contents( + repo_name, + path: 'README.md', + ref: test_branch + ).sha + Octokit.update_contents( + repo_name, + 'README.md', + 'Updating content', + blob_sha, + "File content #{Time.now.to_s}", + branch: test_branch + ) + Octokit.create_pull_request( + repo_name, + base_branch, + test_branch, + 'testing the latest build', + 'testing the latest build' + ) + + - name: test-pr-merge + plan: + - get: git-pr + passed: [ 'create-pr' ] + trigger: true - get: merge-pull-requests trigger: true - put: merge-pull-requests From 95898b9a9cd7719040215d16749f0be48bcb6eb1 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 23 Aug 2017 07:16:56 -0600 Subject: [PATCH 033/106] rubocop -a --- Gemfile | 8 ++++---- assets/lib/commands/check.rb | 2 +- assets/lib/commands/in.rb | 2 +- assets/lib/commands/out.rb | 8 ++++---- assets/lib/filters/path.rb | 4 ++-- spec/commands/in_spec.rb | 4 ++-- spec/commands/out_spec.rb | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index f7e0b4c..2c21dd3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,9 +1,9 @@ source 'https://rubygems.org' -gem 'octokit' -gem 'httpclient' -gem 'faraday-http-cache' gem 'activesupport' +gem 'faraday-http-cache' +gem 'httpclient' +gem 'octokit' group :development do gem 'pry' @@ -12,7 +12,7 @@ group :development do end group :test do - gem 'rspec' gem 'puffing-billy' + gem 'rspec' gem 'webmock' end diff --git a/assets/lib/commands/check.rb b/assets/lib/commands/check.rb index 17f1571..9faea01 100755 --- a/assets/lib/commands/check.rb +++ b/assets/lib/commands/check.rb @@ -18,7 +18,7 @@ def repo end end -if __FILE__ == $PROGRAM_NAME +if $PROGRAM_NAME == __FILE__ command = Commands::Check.new puts JSON.generate(command.output) end diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index eb95c7b..8be8924 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -88,7 +88,7 @@ def depth_flag end end -if __FILE__ == $PROGRAM_NAME +if $PROGRAM_NAME == __FILE__ destination = ARGV.shift command = Commands::In.new(destination: destination) puts JSON.generate(command.output) diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index 7972d6e..41b1fb6 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -86,7 +86,7 @@ def output private def whitelist(context:) - %w(BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL).each do |name| + %w[BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL].each do |name| context.gsub!("$#{name}", ENV[name] || '') end context @@ -97,14 +97,14 @@ def params end def check_defaults! - raise %(`status` "#{params.status}" is not supported -- only success, failure, error, or pending) unless %w(success failure error pending).include?(params.status) - raise %(`merge.method` "#{params.merge.method}" is not supported -- only merge, squash, or rebase) if params.merge.method && !%w(merge squash rebase).include?(params.merge.method) + raise %(`status` "#{params.status}" is not supported -- only success, failure, error, or pending) unless %w[success failure error pending].include?(params.status) + raise %(`merge.method` "#{params.merge.method}" is not supported -- only merge, squash, or rebase) if params.merge.method && !%w[merge squash rebase].include?(params.merge.method) raise '`path` required in `params`' unless params.path end end end -if __FILE__ == $PROGRAM_NAME +if $PROGRAM_NAME == __FILE__ destination = ARGV.shift command = Commands::Out.new(destination: destination) puts JSON.generate(command.output) diff --git a/assets/lib/filters/path.rb b/assets/lib/filters/path.rb index 545dc13..5afedb4 100644 --- a/assets/lib/filters/path.rb +++ b/assets/lib/filters/path.rb @@ -13,7 +13,7 @@ def pull_requests return @pull_requests if paths.empty? && ignore_paths.empty? - @memoized ||= @pull_requests.select do |pr| + @memoized ||= @pull_requests.reject do |pr| files = Octokit.pull_request_files(@input.source.repo, pr.id) unless paths.empty? files.select! do |file| @@ -29,7 +29,7 @@ def pull_requests end end end - !files.empty? + files.empty? end end end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 3f20fb2..5c01e82 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -205,7 +205,7 @@ def dont_expect_arg(*args) it 'get submodules with paths' do expect_arg /git submodule update --init --recursive path1/ expect_arg /git submodule update --init --recursive path2/ - get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => %w(path1 path2) } }) + get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { 'submodules' => %w[path1 path2] } }) end it 'checkouts everything by depth' do @@ -215,7 +215,7 @@ def dont_expect_arg(*args) 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'git' => { - 'submodules' => %w(path1 path2), + 'submodules' => %w[path1 path2], 'depth' => 100 } }) diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 9f20123..cf13f62 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -235,7 +235,7 @@ def stub_json(method, uri, body) end context 'with build specific environment variables' do - %w(BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL).each do |env_var| + %w[BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL].each do |env_var| it "evaluates #{env_var} for a context" do ENV[env_var] = 'build-env-var' stub_status_post.with(body: hash_including('context' => 'concourse-ci/build-env-var')) From cae449470def63025a08b01298fedcf9c09f5405 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 24 Aug 2017 22:47:59 -0600 Subject: [PATCH 034/106] update things --- .rubocop.yml | 13 ++----------- Gemfile | 4 ++++ Gemfile.lock | 9 ++++++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a6eef75..077ce8f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,18 +1,9 @@ # This is the configuration used to check the rubocop source code. -Style/Encoding: - Enabled: true - -Metrics/LineLength: - Enabled: false - require: rubocop-rspec -RSpec/FilePath: - Enabled: false - -Performance/RedundantMatch: +Style/FrozenStringLiteralComment: Enabled: false AllCops: - TargetRubyVersion: 2.2 + TargetRubyVersion: 2.4 diff --git a/Gemfile b/Gemfile index 2c21dd3..a6f7ee4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,9 @@ +# frozen_string_literal: true + source 'https://rubygems.org' +ruby '~> 2.4' + gem 'activesupport' gem 'faraday-http-cache' gem 'httpclient' diff --git a/Gemfile.lock b/Gemfile.lock index daf23d7..7ff890e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,11 +26,11 @@ GEM eventmachine (>= 1.0.0.beta.1) eventmachine (1.0.9.1) eventmachine_httpserver (0.2.1) - faraday (0.12.2) + faraday (0.13.1) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) - hashdiff (0.3.5) + hashdiff (0.3.6) http_parser.rb (0.6.0) httpclient (2.8.3) i18n (0.8.6) @@ -111,5 +111,8 @@ DEPENDENCIES rubocop-rspec webmock +RUBY VERSION + ruby 2.4.0p0 + BUNDLED WITH - 1.15.1 + 1.15.4 From f2c206aa68ae0d10be17d1e64bdad4aebcfd529d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 29 Aug 2017 08:01:53 -0600 Subject: [PATCH 035/106] Github! --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8586f05..e1a3f01 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ # Github Pull Request Resource -Tracks pull requests made to a particular github repo. In the spirit of [Travis +Tracks Github pull requests made to a particular Github repo. In the spirit of [Travis CI](https://travis-ci.org/), a status of pending, success, or failure will be set on the pull request, which must be explicitly defined in your pipeline. +NOTE: Pull requests are implemented differently between the git repo providers. This +resource only support *GITHUB*. + ## Deploying to Concourse You can use the docker image by defining the [resource type](http://concourse.ci/configuring-resource-types.html) in your pipeline YAML. From af05528326dcbf7ac3c812b87e4154d374db882c Mon Sep 17 00:00:00 2001 From: Manuel Zubieta Date: Thu, 31 Aug 2017 16:44:26 -0500 Subject: [PATCH 036/106] push repository source down into `/src` directory, and supply `url`, `id`, `branch`, and `base_branch` files that include respective metadata --- assets/lib/commands/in.rb | 14 ++++++++++++-- spec/commands/in_spec.rb | 21 +++++++++++++-------- spec/integration/in_spec.rb | 5 +++-- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 8be8924..0498bce 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -10,6 +10,7 @@ class In < Commands::Base def initialize(destination:, input: Input.instance) @destination = destination + @src_destination = "#{@destination}/src" super(input: input) end @@ -20,11 +21,20 @@ def output raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - system("git clone #{depth_flag} #{uri} #{destination} 1>&2") + system("git clone #{depth_flag} #{uri} #{@src_destination} 1>&2") raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? - Dir.chdir(destination) do + Dir.chdir(@destination) do + system <<-BASH + echo "#{pr['html_url']}" > url + echo "#{pr['number']}" > id + echo "#{pr['head']['ref']}" > branch + echo "#{pr['base']['ref']}" > base_branch + BASH + end + + Dir.chdir(@src_destination) do raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") system <<-BASH diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 5c01e82..111622a 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -13,6 +13,7 @@ def git_uri end let(:dest_dir) { Dir.mktmpdir } + let(:src_dest_dir) { "#{dest_dir}/src" } def get(payload) payload['source']['no_ssl_verify'] = true @@ -51,13 +52,17 @@ def dest_dir @dest_dir ||= Dir.mktmpdir end + def src_dest_dir + @src_dest_dir ||= "#{dest_dir}/src" + end + before(:all) do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end - it 'checks out the pull request to dest_dir' do - expect(@ref).to eq git('log --format=format:%H HEAD', dest_dir) + it 'checks out the pull request to src_dest_dir' do + expect(@ref).to eq git('log --format=format:%H HEAD', src_dest_dir) end it 'returns the correct JSON metadata' do @@ -69,22 +74,22 @@ def dest_dir end it 'adds metadata to `git config`' do - value = git('config --get pullrequest.url', dest_dir) + value = git('config --get pullrequest.url', src_dest_dir) expect(value).to eq 'http://example.com' end it 'checks out as a branch with a `pr-` prefix' do - value = git('rev-parse --abbrev-ref HEAD', dest_dir) + value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) expect(value).to eq 'pr-foo' end it 'sets config variable to branch name' do - value = git('config pullrequest.branch', dest_dir) + value = git('config pullrequest.branch', src_dest_dir) expect(value).to eq 'foo' end it 'sets config variable to base_branch name' do - value = git('config pullrequest.basebranch', dest_dir) + value = git('config pullrequest.basebranch', src_dest_dir) expect(value).to eq 'master' end end @@ -108,7 +113,7 @@ def dest_dir get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) - value = git('rev-parse --abbrev-ref HEAD', dest_dir) + value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) expect(value).to eq 'pr-foo' end @@ -129,7 +134,7 @@ def dest_dir get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params:' => { 'fetch_merge' => true }) - value = git('rev-parse --abbrev-ref HEAD', dest_dir) + value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) expect(value).to eq 'pr-foo' end diff --git a/spec/integration/in_spec.rb b/spec/integration/in_spec.rb index f627d45..e3c0e10 100644 --- a/spec/integration/in_spec.rb +++ b/spec/integration/in_spec.rb @@ -7,6 +7,7 @@ let(:proxy) { Billy::Proxy.new } let(:dest_dir) { Dir.mktmpdir } + let(:src_dest_dir) { "#{dest_dir}/src" } let(:git_dir) { Dir.mktmpdir } let(:git_uri) { "file://#{git_dir}" } @@ -38,9 +39,9 @@ def commit(msg) .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' } }) end - it 'checks out the pull request to dest_dir' do + it 'checks out the pull request to src_dest_dir' do get(version: { ref: @ref, pr: '1' }, source: { access_token: 'abc', uri: git_uri, repo: 'jtarchie/test' }) - expect(@ref).to eq git('log --format=format:%H HEAD', dest_dir) + expect(@ref).to eq git('log --format=format:%H HEAD', src_dest_dir) end end end From fc84506f556c041c8a87d3ceb0c4d0bc26796cc9 Mon Sep 17 00:00:00 2001 From: Manuel Zubieta Date: Thu, 31 Aug 2017 17:35:53 -0500 Subject: [PATCH 037/106] move pull request source back to top level directory --- assets/lib/commands/in.rb | 7 +++---- spec/commands/in_spec.rb | 21 ++++++++------------- spec/integration/in_spec.rb | 5 ++--- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 0498bce..f561652 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -10,7 +10,6 @@ class In < Commands::Base def initialize(destination:, input: Input.instance) @destination = destination - @src_destination = "#{@destination}/src" super(input: input) end @@ -21,11 +20,11 @@ def output raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - system("git clone #{depth_flag} #{uri} #{@src_destination} 1>&2") + system("git clone #{depth_flag} #{uri} #{destination} 1>&2") raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? - Dir.chdir(@destination) do + Dir.chdir(File.join(destination,'.git')) do system <<-BASH echo "#{pr['html_url']}" > url echo "#{pr['number']}" > id @@ -34,7 +33,7 @@ def output BASH end - Dir.chdir(@src_destination) do + Dir.chdir(destination) do raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") system <<-BASH diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 111622a..5c01e82 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -13,7 +13,6 @@ def git_uri end let(:dest_dir) { Dir.mktmpdir } - let(:src_dest_dir) { "#{dest_dir}/src" } def get(payload) payload['source']['no_ssl_verify'] = true @@ -52,17 +51,13 @@ def dest_dir @dest_dir ||= Dir.mktmpdir end - def src_dest_dir - @src_dest_dir ||= "#{dest_dir}/src" - end - before(:all) do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end - it 'checks out the pull request to src_dest_dir' do - expect(@ref).to eq git('log --format=format:%H HEAD', src_dest_dir) + it 'checks out the pull request to dest_dir' do + expect(@ref).to eq git('log --format=format:%H HEAD', dest_dir) end it 'returns the correct JSON metadata' do @@ -74,22 +69,22 @@ def src_dest_dir end it 'adds metadata to `git config`' do - value = git('config --get pullrequest.url', src_dest_dir) + value = git('config --get pullrequest.url', dest_dir) expect(value).to eq 'http://example.com' end it 'checks out as a branch with a `pr-` prefix' do - value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) + value = git('rev-parse --abbrev-ref HEAD', dest_dir) expect(value).to eq 'pr-foo' end it 'sets config variable to branch name' do - value = git('config pullrequest.branch', src_dest_dir) + value = git('config pullrequest.branch', dest_dir) expect(value).to eq 'foo' end it 'sets config variable to base_branch name' do - value = git('config pullrequest.basebranch', src_dest_dir) + value = git('config pullrequest.basebranch', dest_dir) expect(value).to eq 'master' end end @@ -113,7 +108,7 @@ def src_dest_dir get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) - value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) + value = git('rev-parse --abbrev-ref HEAD', dest_dir) expect(value).to eq 'pr-foo' end @@ -134,7 +129,7 @@ def src_dest_dir get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params:' => { 'fetch_merge' => true }) - value = git('rev-parse --abbrev-ref HEAD', src_dest_dir) + value = git('rev-parse --abbrev-ref HEAD', dest_dir) expect(value).to eq 'pr-foo' end diff --git a/spec/integration/in_spec.rb b/spec/integration/in_spec.rb index e3c0e10..f627d45 100644 --- a/spec/integration/in_spec.rb +++ b/spec/integration/in_spec.rb @@ -7,7 +7,6 @@ let(:proxy) { Billy::Proxy.new } let(:dest_dir) { Dir.mktmpdir } - let(:src_dest_dir) { "#{dest_dir}/src" } let(:git_dir) { Dir.mktmpdir } let(:git_uri) { "file://#{git_dir}" } @@ -39,9 +38,9 @@ def commit(msg) .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' } }) end - it 'checks out the pull request to src_dest_dir' do + it 'checks out the pull request to dest_dir' do get(version: { ref: @ref, pr: '1' }, source: { access_token: 'abc', uri: git_uri, repo: 'jtarchie/test' }) - expect(@ref).to eq git('log --format=format:%H HEAD', src_dest_dir) + expect(@ref).to eq git('log --format=format:%H HEAD', dest_dir) end end end From a7a9393118a2f559289f78ad3a890abcc7622145 Mon Sep 17 00:00:00 2001 From: Manuel Zubieta Date: Thu, 31 Aug 2017 17:37:07 -0500 Subject: [PATCH 038/106] add tests for new metadata output files --- spec/commands/in_spec.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 5c01e82..990a1c1 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -87,6 +87,27 @@ def dest_dir value = git('config pullrequest.basebranch', dest_dir) expect(value).to eq 'master' end + + it 'creates a file that icludes the id in the .git folder' do + value = File.read(File.join(dest_dir,'.git','id')).strip() + expect(value).to eq '1' + end + + it 'creates a file that icludes the url in the .git folder' do + value = File.read(File.join(dest_dir,'.git','url')).strip() + expect(value).to eq 'http://example.com' + end + + it 'creates a file that icludes ahe branch in the .git folder' do + value = File.read(File.join(dest_dir,'.git','branch')).strip() + expect(value).to eq 'foo' + end + + it 'creates a file that icludes the base_branch in the .git folder' do + value = File.read(File.join(dest_dir,'.git','base_branch')).strip() + expect(value).to eq 'master' + end + end context 'when the git clone fails' do From ad37d2e17f47699ac1bd292713a41cb848fa569a Mon Sep 17 00:00:00 2001 From: Manuel Zubieta Date: Thu, 31 Aug 2017 17:37:30 -0500 Subject: [PATCH 039/106] update readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index e1a3f01..56b8179 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,17 @@ git config --get pullrequest.id # returns the ID number of the PR git config --get pullrequest.basebranch # returns the base branch used for the pull request ``` + +#### Additional files populated + + * `.git/id`: the pull request id + + * `.git/url`: the URL for the pull request + + * `.git/branch`: the branch associated with the pull request + + * `.git/base_branch`: the base branch of the pull request + #### Parameters * `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the From 355f9011ad90ce95275069c210728daf0c07ae23 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 31 Aug 2017 19:56:49 -0600 Subject: [PATCH 040/106] update repo nam --- .concourse.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.concourse.yml b/.concourse.yml index eda08a4..9e79c57 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -27,7 +27,7 @@ resources: source: access_token: {{github-access-token}} private_key: {{github-private-key}} - repo: jtarchie/pullrequest-resource + repo: jtarchie/github-pullrequest-resource base: master - name: merge-pull-requests type: pull-request-test @@ -35,7 +35,7 @@ resources: access_token: {{github-access-token}} private_key: {{github-private-key}} base: test-merge - repo: jtarchie/pullrequest-resource + repo: jtarchie/github-pullrequest-resource jobs: - name: create-pr From b0f31f84a7b08cadafc0bb2429678fa45169c18b Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 31 Aug 2017 20:03:16 -0600 Subject: [PATCH 041/106] only test on latest test PR --- .concourse.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.concourse.yml b/.concourse.yml index 9e79c57..e196a6b 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -93,7 +93,6 @@ jobs: plan: - get: git-pr passed: [ 'create-pr' ] - trigger: true - get: merge-pull-requests trigger: true - put: merge-pull-requests From bd51f6fc821438397f994a06d9b926959966fd1c Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 31 Aug 2017 20:07:25 -0600 Subject: [PATCH 042/106] v27 Release notes --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f5f81c..a6a8cd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v27 @ 8/31/2017 + +* Output the `git config` meta values into files in the `.git/` directory. Thanks @mazubieta + # v26 @ 8/21/2017 * Support evaluating the concourse BUILD environment variables in a context. @@ -5,7 +9,7 @@ # v25 @ 8/1/2017 * support caching of API requests to Github. This decreases hitting the -rate limit per hour. It does not reduce the number of request, though. +rate limit per hour. It does not reduce the number of requests, though. # v24 @ 6/26/2017 From 6a5b6dfc9afb2312fee28b4660be44f27f3039da Mon Sep 17 00:00:00 2001 From: Dr Nic Williams Date: Tue, 5 Sep 2017 10:03:02 +1000 Subject: [PATCH 043/106] include PR author user_login in metadata --- README.md | 8 +++++--- assets/lib/commands/in.rb | 2 ++ spec/commands/in_spec.rb | 21 +++++++++++++-------- spec/integration/in_spec.rb | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 56b8179..33842a9 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ git config --get pullrequest.url # returns the URL to the pull request git config --get pullrequest.branch # returns the branch name used for the pull request git config --get pullrequest.id # returns the ID number of the PR git config --get pullrequest.basebranch # returns the base branch used for the pull request +git config --get pullrequest.userlogin # returns the github user login for the pull request author ``` @@ -125,10 +126,12 @@ git config --get pullrequest.basebranch # returns the base branch used for the p * `.git/base_branch`: the base branch of the pull request + * `.git/user_login`: the user login of the pull request author + #### Parameters * `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the - repository using the `--depth` option. + repository using the `--depth` option. * `git.submodules`: *Optional*, default `all`. If `none`, submodules will not be fetched. If specified as a list of paths, only the given paths will be @@ -158,7 +161,7 @@ Set the status message for `concourse-ci` context on specified pull request. This supports the [build environment](http://concourse.ci/implementing-resources.html#resource-metadata) variables provided by concourse. For example, `context: $BUILD_JOB_NAME` will set the context to the job name. -* `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. +* `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. * `merge.method`: *Optional.* Use this to merge the PR into the target branch of the PR. There are three available merge methods -- `merge`, `squash`, or `rebase`. Please this [doc](https://developer.github.com/changes/2016-09-26-pull-request-merge-api-update/) for more information. @@ -179,4 +182,3 @@ Requires `ruby` to be installed. bundle install bundle exec rspec ``` - diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index f561652..26eadab 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -30,6 +30,7 @@ def output echo "#{pr['number']}" > id echo "#{pr['head']['ref']}" > branch echo "#{pr['base']['ref']}" > base_branch + echo "#{pr['base']['user']['login']}" > userlogin BASH end @@ -42,6 +43,7 @@ def output git config --add pullrequest.id #{pr['number']} 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 + git config --add pullrequest.userlogin #{pr['base']['user']['login']} 1>&2 BASH case input.params.git.submodules diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 990a1c1..314993d 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -52,7 +52,7 @@ def dest_dir end before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end @@ -88,6 +88,11 @@ def dest_dir expect(value).to eq 'master' end + it 'sets config variable to user_login name' do + value = git('config pullrequest.userlogin', dest_dir) + expect(value).to eq 'jtarchie' + end + it 'creates a file that icludes the id in the .git folder' do value = File.read(File.join(dest_dir,'.git','id')).strip() expect(value).to eq '1' @@ -112,7 +117,7 @@ def dest_dir context 'when the git clone fails' do it 'provides a helpful erorr message' do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => 'invalid_git_uri', 'repo' => 'jtarchie/test' }) @@ -125,7 +130,7 @@ def dest_dir context 'and fetch_merge is false' do it 'checks out as a branch named in the PR' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) @@ -135,7 +140,7 @@ def dest_dir it 'does not fail cloning' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) @@ -146,7 +151,7 @@ def dest_dir context 'and fetch_merge is true' do it 'checks out the branch the PR would be merged into' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params:' => { 'fetch_merge' => true }) @@ -156,7 +161,7 @@ def dest_dir it 'does not fail cloning' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => true }) @@ -169,7 +174,7 @@ def dest_dir context 'and fetch_merge is true' do it 'raises a helpful error message' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' }, mergeable: false) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: false) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => true }) @@ -183,7 +188,7 @@ def dest_dir stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, - base: { ref: 'master' }) + base: { ref: 'master', user: { login: 'jtarchie' } }) end def expect_arg(*args) diff --git a/spec/integration/in_spec.rb b/spec/integration/in_spec.rb index f627d45..2f7a144 100644 --- a/spec/integration/in_spec.rb +++ b/spec/integration/in_spec.rb @@ -35,7 +35,7 @@ def commit(msg) context 'for every PR that is checked out' do before do proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls/1') - .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master' } }) + .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } } }) end it 'checks out the pull request to dest_dir' do From 75f409a5ca76e3c4f692c901437e896e4620325d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 5 Sep 2017 22:40:16 -0600 Subject: [PATCH 044/106] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a8cd7..e814532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v28 @ 9/5/2017 + +* Output user of the PR to the meta data Thanks @drnic + # v27 @ 8/31/2017 * Output the `git config` meta values into files in the `.git/` directory. Thanks @mazubieta From dbd4c0e20db9d9698030dfc62e5a322cc021bcb7 Mon Sep 17 00:00:00 2001 From: NuclearNic Date: Wed, 13 Sep 2017 11:34:36 +0200 Subject: [PATCH 045/106] populate file with latest commit hash of PR branch --- README.md | 2 ++ assets/lib/commands/in.rb | 1 + spec/commands/in_spec.rb | 7 ++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 33842a9..8e1c6ff 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,8 @@ git config --get pullrequest.userlogin # returns the github user login for the * `.git/user_login`: the user login of the pull request author + * `.git/branch_sha`: the latest commit hash of the branch associated with the pull request + #### Parameters * `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 26eadab..b066a39 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -31,6 +31,7 @@ def output echo "#{pr['head']['ref']}" > branch echo "#{pr['base']['ref']}" > base_branch echo "#{pr['base']['user']['login']}" > userlogin + echo "#{pr['head']['sha']}" > branch_sha BASH end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 314993d..5cd535b 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -52,7 +52,7 @@ def dest_dir end before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end @@ -113,6 +113,11 @@ def dest_dir expect(value).to eq 'master' end + it 'creates a file that includes the hash of the branch in the .git folder' do + value = File.read(File.join(dest_dir,'.git','branch_sha')).strip() + expect(value).to eq 'hash' + end + end context 'when the git clone fails' do From 37d1cd779bceca85bdeaf1b33bf55797ef23058c Mon Sep 17 00:00:00 2001 From: NuclearNic Date: Fri, 15 Sep 2017 09:27:54 +0200 Subject: [PATCH 046/106] populate file head_sha instead of branch_sha --- README.md | 2 +- assets/lib/commands/in.rb | 2 +- spec/commands/in_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8e1c6ff..6f8bbfa 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ git config --get pullrequest.userlogin # returns the github user login for the * `.git/user_login`: the user login of the pull request author - * `.git/branch_sha`: the latest commit hash of the branch associated with the pull request + * `.git/head_sha`: the latest commit hash of the branch associated with the pull request #### Parameters diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index b066a39..ac8ffea 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -31,7 +31,7 @@ def output echo "#{pr['head']['ref']}" > branch echo "#{pr['base']['ref']}" > base_branch echo "#{pr['base']['user']['login']}" > userlogin - echo "#{pr['head']['sha']}" > branch_sha + echo "#{pr['head']['sha']}" > head_sha BASH end diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 5cd535b..960c999 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -114,7 +114,7 @@ def dest_dir end it 'creates a file that includes the hash of the branch in the .git folder' do - value = File.read(File.join(dest_dir,'.git','branch_sha')).strip() + value = File.read(File.join(dest_dir,'.git','head_sha')).strip() expect(value).to eq 'hash' end From 6c905ff4ec2cf51f6130f5c5b879ccbcb03d7506 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sun, 17 Sep 2017 18:36:41 -0600 Subject: [PATCH 047/106] rubocop -a --- assets/lib/commands/in.rb | 2 +- spec/commands/in_spec.rb | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index ac8ffea..56094bd 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -24,7 +24,7 @@ def output raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? - Dir.chdir(File.join(destination,'.git')) do + Dir.chdir(File.join(destination, '.git')) do system <<-BASH echo "#{pr['html_url']}" > url echo "#{pr['number']}" > id diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 960c999..ab9efbc 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -94,30 +94,29 @@ def dest_dir end it 'creates a file that icludes the id in the .git folder' do - value = File.read(File.join(dest_dir,'.git','id')).strip() + value = File.read(File.join(dest_dir, '.git', 'id')).strip expect(value).to eq '1' end it 'creates a file that icludes the url in the .git folder' do - value = File.read(File.join(dest_dir,'.git','url')).strip() + value = File.read(File.join(dest_dir, '.git', 'url')).strip expect(value).to eq 'http://example.com' end it 'creates a file that icludes ahe branch in the .git folder' do - value = File.read(File.join(dest_dir,'.git','branch')).strip() + value = File.read(File.join(dest_dir, '.git', 'branch')).strip expect(value).to eq 'foo' end it 'creates a file that icludes the base_branch in the .git folder' do - value = File.read(File.join(dest_dir,'.git','base_branch')).strip() + value = File.read(File.join(dest_dir, '.git', 'base_branch')).strip expect(value).to eq 'master' end it 'creates a file that includes the hash of the branch in the .git folder' do - value = File.read(File.join(dest_dir,'.git','head_sha')).strip() + value = File.read(File.join(dest_dir, '.git', 'head_sha')).strip expect(value).to eq 'hash' end - end context 'when the git clone fails' do From 197ea3d086177c0ef802ab83e024f034f285bc59 Mon Sep 17 00:00:00 2001 From: Victor Unegbu Date: Thu, 21 Sep 2017 22:06:04 -0500 Subject: [PATCH 048/106] fix reference to PR author properly references the PR author instead of the base author --- assets/lib/commands/in.rb | 4 ++-- spec/commands/in_spec.rb | 19 ++++++++++--------- spec/integration/in_spec.rb | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 56094bd..b141e71 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -30,7 +30,7 @@ def output echo "#{pr['number']}" > id echo "#{pr['head']['ref']}" > branch echo "#{pr['base']['ref']}" > base_branch - echo "#{pr['base']['user']['login']}" > userlogin + echo "#{pr['user']['login']}" > userlogin echo "#{pr['head']['sha']}" > head_sha BASH end @@ -44,7 +44,7 @@ def output git config --add pullrequest.id #{pr['number']} 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 - git config --add pullrequest.userlogin #{pr['base']['user']['login']} 1>&2 + git config --add pullrequest.userlogin #{pr['user']['login']} 1>&2 BASH case input.params.git.submodules diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index ab9efbc..ef980ea 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -52,7 +52,7 @@ def dest_dir end before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end @@ -90,7 +90,7 @@ def dest_dir it 'sets config variable to user_login name' do value = git('config pullrequest.userlogin', dest_dir) - expect(value).to eq 'jtarchie' + expect(value).to eq 'jtarchie-contributor' end it 'creates a file that icludes the id in the .git folder' do @@ -121,7 +121,7 @@ def dest_dir context 'when the git clone fails' do it 'provides a helpful erorr message' do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor'}) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => 'invalid_git_uri', 'repo' => 'jtarchie/test' }) @@ -134,7 +134,7 @@ def dest_dir context 'and fetch_merge is false' do it 'checks out as a branch named in the PR' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }, mergeable: true) get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) @@ -144,7 +144,7 @@ def dest_dir it 'does not fail cloning' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }, mergeable: true) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => false }) @@ -155,7 +155,7 @@ def dest_dir context 'and fetch_merge is true' do it 'checks out the branch the PR would be merged into' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }, mergeable: true) get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params:' => { 'fetch_merge' => true }) @@ -165,7 +165,7 @@ def dest_dir it 'does not fail cloning' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: true) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }, mergeable: true) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => true }) @@ -178,7 +178,7 @@ def dest_dir context 'and fetch_merge is true' do it 'raises a helpful error message' do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, mergeable: false) + html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }, mergeable: false) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { 'fetch_merge' => true }) @@ -192,7 +192,8 @@ def dest_dir stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, - base: { ref: 'master', user: { login: 'jtarchie' } }) + base: { ref: 'master', user: { login: 'jtarchie' } }, + user: { login: 'jtarchie-contributor' }) end def expect_arg(*args) diff --git a/spec/integration/in_spec.rb b/spec/integration/in_spec.rb index 2f7a144..be0a79a 100644 --- a/spec/integration/in_spec.rb +++ b/spec/integration/in_spec.rb @@ -35,7 +35,7 @@ def commit(msg) context 'for every PR that is checked out' do before do proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls/1') - .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } } }) + .and_return(json: { html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' } }) end it 'checks out the pull request to dest_dir' do From cbff880c248a5f30bddadfc1f5dc71d82f1c877e Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 1 Nov 2017 15:28:40 -0600 Subject: [PATCH 049/106] update the PR check information --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f8bbfa..cf08560 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,8 @@ marked with that specific label. It is case insensitive. ### `check`: Check for new pull requests Concourse resources always iterate over the latest version. This maps well to -semver and git, but not with pull requests. To find the latests pull -requests, `check` queries for all PRs, selects only PRs without `concourse-ci` -status messages, and then only returns the oldest one from list. +semver and git, but not with pull requests. This filters all open PRs +sorted by most recently updated. To ensure that `check` can iterate over all PRs, you must explicitly define an `out` for the PR. From 257e221e12aa9819660dcc8e19b47a352712b86e Mon Sep 17 00:00:00 2001 From: JT Archie Date: Fri, 3 Nov 2017 08:27:18 -0600 Subject: [PATCH 050/106] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e814532..3831866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v30 + +* Use correct user for PR author in the git meta data Thanks @victoru + +# v29 + +* populate file with latest commit hash of PR branch + # v28 @ 9/5/2017 * Output user of the PR to the meta data Thanks @drnic From fe6dd1a875c1689b737eaa704520d18840aa080b Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 7 Nov 2017 10:22:16 -0800 Subject: [PATCH 051/106] Apply the depth flag to the branch fetch operation and not just the initial clone. --- assets/lib/commands/in.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index b141e71..2231e69 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -36,7 +36,7 @@ def output end Dir.chdir(destination) do - raise 'git clone failed' unless system("git fetch -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") + raise 'git clone failed' unless system("git fetch #{depth_flag} -q origin pull/#{id}/#{remote_ref}:#{branch_ref} 1>&2") system <<-BASH git checkout #{branch_ref} 1>&2 From 9a885a6055100d3684544446367da77545b4eb3e Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 7 Nov 2017 10:31:01 -0800 Subject: [PATCH 052/106] clone base branch instead of remote default branch Clone the base branch instead of the default remote branch. This is mostly useful when the base branch is not the default remote branch, especially when the depth filter is used; it ensures that the base branch's ref is available so that it can be diffed with the branch ref. --- assets/lib/commands/in.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 56094bd..9153eb1 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -20,7 +20,7 @@ def output raise 'PR has merge conflicts' if pr['mergeable'] == false && fetch_merge - system("git clone #{depth_flag} #{uri} #{destination} 1>&2") + system("git clone #{depth_flag} --branch #{pr['base']['ref']} #{uri} #{destination} 1>&2") raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? From 43735e3762bd940b9b1621cc1c5626ff5985dbe6 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 7 Nov 2017 14:07:11 -0700 Subject: [PATCH 053/106] backfill depth test --- spec/commands/in_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index ef980ea..c4be56c 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -242,6 +242,7 @@ def dont_expect_arg(*args) it 'checkouts everything by depth' do expect_arg /git submodule update --init --recursive --depth 100 path1/ expect_arg /git clone --depth 100/ + expect_arg /git fetch --depth 100/ get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, 'params' => { From add85a8d56d81cc4a889116d3fd81a89f270538b Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 7 Nov 2017 14:20:37 -0700 Subject: [PATCH 054/106] backfill base ref branch checkout --- spec/commands/in_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index c4be56c..9fe48c5 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -241,7 +241,7 @@ def dont_expect_arg(*args) it 'checkouts everything by depth' do expect_arg /git submodule update --init --recursive --depth 100 path1/ - expect_arg /git clone --depth 100/ + expect_arg /git clone --depth 100 --branch master/ expect_arg /git fetch --depth 100/ get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }, From 087222c0a6578d6c3337d9505668d75d4eaafaf6 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 7 Nov 2017 14:23:02 -0700 Subject: [PATCH 055/106] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3831866..2a62700 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v31 @ 11/7/2017 + +* apply `depth` to the `git fetch` of the PR (thanks @bhcleek) +* checkout the original branch the PR was made against (thanks @bhcleek) + # v30 * Use correct user for PR author in the git meta data Thanks @victoru From ec97e0bbf74b48611b7f5f60d6ea92747cb0ba5a Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 29 Nov 2017 20:42:51 -0700 Subject: [PATCH 056/106] update gems --- Gemfile.lock | 75 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7ff890e..4bb0512 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,15 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.1.3) + activesupport (5.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.4.0) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) ast (2.3.0) - coderay (1.1.1) + coderay (1.1.2) concurrent-ruby (1.0.5) cookiejar (0.3.3) crack (0.4.3) @@ -24,74 +25,74 @@ GEM eventmachine (>= 1.0.0.beta.4) em-synchrony (1.0.6) eventmachine (>= 1.0.0.beta.1) - eventmachine (1.0.9.1) + eventmachine (1.2.5) eventmachine_httpserver (0.2.1) faraday (0.13.1) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) - hashdiff (0.3.6) + hashdiff (0.3.7) http_parser.rb (0.6.0) httpclient (2.8.3) - i18n (0.8.6) - method_source (0.8.2) + i18n (0.9.1) + concurrent-ruby (~> 1.0) + method_source (0.9.0) minitest (5.10.3) - multi_json (1.12.1) + multi_json (1.12.2) multipart-post (2.0.0) octokit (4.7.0) sawyer (~> 0.8.0, >= 0.5.3) parallel (1.12.0) - parser (2.4.0.0) - ast (~> 2.2) + parser (2.4.0.2) + ast (~> 2.3) powerpack (0.1.1) - pry (0.10.4) + pry (0.11.3) coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - puffing-billy (0.10.0) - addressable (~> 2.4.0) - em-http-request (~> 1.1.0) + method_source (~> 0.9.0) + public_suffix (3.0.1) + puffing-billy (0.11.0) + addressable (~> 2.4, >= 2.4.0) + em-http-request (~> 1.1, >= 1.1.0) em-synchrony - eventmachine (~> 1.0.4) + eventmachine (~> 1.0, >= 1.0.4) eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json rainbow (2.2.2) rake - rake (12.0.0) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + rake (12.3.0) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.0) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-mocks (3.6.0) + rspec-support (~> 3.7.0) + rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) - rubocop (0.49.1) + rspec-support (~> 3.7.0) + rspec-support (3.7.0) + rubocop (0.51.0) parallel (~> 1.10) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) - rainbow (>= 1.99.1, < 3.0) + rainbow (>= 2.2.2, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.15.1) - rubocop (>= 0.42.0) - ruby-progressbar (1.8.1) + rubocop-rspec (1.20.1) + rubocop (>= 0.51.0) + ruby-progressbar (1.9.0) safe_yaml (1.0.4) sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) - slop (3.6.0) thread_safe (0.3.6) - tzinfo (1.2.3) + tzinfo (1.2.4) thread_safe (~> 0.1) unicode-display_width (1.3.0) - webmock (3.0.1) + webmock (3.1.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff From e90a2cd328c5c1e5e9e27d6a606172e977446299 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 29 Nov 2017 20:43:19 -0700 Subject: [PATCH 057/106] rubocop -a --- spec/commands/in_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 9fe48c5..3ba83c2 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -121,7 +121,7 @@ def dest_dir context 'when the git clone fails' do it 'provides a helpful erorr message' do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor'}) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }) expect do get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => 'invalid_git_uri', 'repo' => 'jtarchie/test' }) From 61539afcd6baaabcd39a1a9d51b701d41927d5b1 Mon Sep 17 00:00:00 2001 From: Charlie O'Leary Date: Mon, 15 Jan 2018 15:29:54 -0800 Subject: [PATCH 058/106] Fixes minor typo with populated filename. `./git/user_login` -> `./git/userlogin` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf08560..3879183 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ git config --get pullrequest.userlogin # returns the github user login for the * `.git/base_branch`: the base branch of the pull request - * `.git/user_login`: the user login of the pull request author + * `.git/userlogin`: the user login of the pull request author * `.git/head_sha`: the latest commit hash of the branch associated with the pull request From 366375511510bf65142d95e9c1dedf45486f523d Mon Sep 17 00:00:00 2001 From: Aditya Anchuri Date: Tue, 16 Jan 2018 17:31:00 -0800 Subject: [PATCH 059/106] Add support for [ci skip] on outstanding PRs --- .gitignore | 1 + assets/lib/commands/check.rb | 4 +++- assets/lib/filters/all.rb | 2 +- assets/lib/pull_request.rb | 10 ++++++++-- spec/commands/check_spec.rb | 20 ++++++++++++++++++++ spec/commands/out_spec.rb | 2 ++ spec/filters/label_spec.rb | 5 +++-- spec/filters/path_spec.rb | 4 ++-- 8 files changed, 40 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 9fc544b..90fa6fe 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ example/ .bundle bin .secrets.yml +test_pipeline.yml diff --git a/assets/lib/commands/check.rb b/assets/lib/commands/check.rb index 9faea01..8c6354e 100755 --- a/assets/lib/commands/check.rb +++ b/assets/lib/commands/check.rb @@ -7,7 +7,9 @@ module Commands class Check < Commands::Base def output - repo.pull_requests + repo.pull_requests.reject do |pr| + pr.latest_commit_message.include? '[ci skip]' + end end private diff --git a/assets/lib/filters/all.rb b/assets/lib/filters/all.rb index 04606e5..503b0e8 100644 --- a/assets/lib/filters/all.rb +++ b/assets/lib/filters/all.rb @@ -9,7 +9,7 @@ def initialize(pull_requests: [], input: Input.instance) def pull_requests @pull_requests ||= Octokit.pulls(input.source.repo, pull_options).map do |pr| - PullRequest.new(pr: pr) + PullRequest.new(pr: pr, top_commit: Octokit.commit(input.source.repo, pr['head']['sha'])) end end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index e79a3e1..ea37a61 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -3,11 +3,13 @@ class PullRequest def self.from_github(repo:, id:) pr = Octokit.pull_request(repo.name, id) - PullRequest.new(pr: pr) + tc = Octokit.commit(repo.name, pr['head']['sha']) + PullRequest.new(pr: pr, top_commit: tc) end - def initialize(pr:) + def initialize(pr:, top_commit:) @pr = pr + @top_commit = top_commit end def from_fork? @@ -34,6 +36,10 @@ def sha @pr['head']['sha'] end + def latest_commit_message + @top_commit['commit']['message'] + end + def url @pr['html_url'] end diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 7a4c888..8133b5d 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -19,6 +19,7 @@ def stub_json(uri, body) before do stub_json('https://api.github.com/repos/jtarchie/test/statuses/abcdef', []) stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: {message: 'foo bar'}}) end it 'retrieves pull requests for the specified base branch' do @@ -47,6 +48,7 @@ def stub_json(uri, body) context 'when there is an open pull request' do before do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: { message: 'foo bar'} }) end it 'returns SHA of the pull request' do @@ -62,6 +64,17 @@ def stub_json(uri, body) ] end end + + context 'and the top commit has [ci skip] in its message' do + before do + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: {message: 'foo [ci skip] bar'}}) + end + + it 'returns no versions' do + expect(check('source' => { 'repo' => 'jtarchie/test' }, 'version' => {})).to eq [] + end + end end context 'when there is more than one open pull request' do @@ -70,6 +83,8 @@ def stub_json(uri, body) { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } ]) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: { message: 'foo bar' }}) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/zyxwvu', {sha: 'abcdef', commit: { message: 'foo bar'}}) end it 'returns all PRs oldest to newest last' do @@ -104,6 +119,11 @@ def stub_cache_json(uri) pull_requests = (1..100).map do |i| { number: i, head: { sha: "abcdef-#{i}", repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } } end + + (1..100).each do |j| + stub_json("https://api.github.com:443/repos/jtarchie/test/commits/abcdef-#{j}", {sha: "abcdef-#{j}", commit: {message: 'foo bar'}}) + end + stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], 'Link' => '; rel="next"') stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index cf13f62..3bdd0ae 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -127,6 +127,8 @@ def stub_json(method, uri, body) html_url: 'http://example.com', number: 1, head: { sha: 'abcdef' }) + stub_json(:get, 'https://api.github.com:443/repos/jtarchie/test/commits/abcdef', + sha: "abcdef-#{j}", commit: { message: 'foo bar' }) end context 'when setting a status with a comment' do diff --git a/spec/filters/label_spec.rb b/spec/filters/label_spec.rb index 65dd0aa..493d480 100644 --- a/spec/filters/label_spec.rb +++ b/spec/filters/label_spec.rb @@ -1,14 +1,15 @@ require_relative '../../assets/lib/filters/label' require_relative '../../assets/lib/pull_request' +require_relative '../../assets/lib/input' require 'webmock/rspec' describe Filters::Label do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1 }) + PullRequest.new(pr: { 'number' => 1 }, top_commit: {}) end let(:pr) do - PullRequest.new(pr: { 'number' => 2 }) + PullRequest.new(pr: { 'number' => 2 }, top_commit: {}) end let(:pull_requests) { [ignore_pr, pr] } diff --git a/spec/filters/path_spec.rb b/spec/filters/path_spec.rb index 36d393b..3d206aa 100644 --- a/spec/filters/path_spec.rb +++ b/spec/filters/path_spec.rb @@ -4,11 +4,11 @@ describe Filters::Path do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1 }) + PullRequest.new(pr: { 'number' => 1 }, top_commit: {}) end let(:pr) do - PullRequest.new(pr: { 'number' => 2 }) + PullRequest.new(pr: { 'number' => 2 }, top_commit: {}) end let(:pull_requests) { [ignore_pr, pr] } From a22381695e9c03af0e8e13f93a2d51f348baa6d9 Mon Sep 17 00:00:00 2001 From: Aditya Anchuri Date: Wed, 17 Jan 2018 11:47:44 -0800 Subject: [PATCH 060/106] Use Filters to filter out PRs with ci skip in their top commit --- assets/lib/commands/check.rb | 4 +--- assets/lib/filters/ci_skip.rb | 16 ++++++++++++++++ assets/lib/repository.rb | 3 ++- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 assets/lib/filters/ci_skip.rb diff --git a/assets/lib/commands/check.rb b/assets/lib/commands/check.rb index 8c6354e..9faea01 100755 --- a/assets/lib/commands/check.rb +++ b/assets/lib/commands/check.rb @@ -7,9 +7,7 @@ module Commands class Check < Commands::Base def output - repo.pull_requests.reject do |pr| - pr.latest_commit_message.include? '[ci skip]' - end + repo.pull_requests end private diff --git a/assets/lib/filters/ci_skip.rb b/assets/lib/filters/ci_skip.rb new file mode 100644 index 0000000..15ccbd6 --- /dev/null +++ b/assets/lib/filters/ci_skip.rb @@ -0,0 +1,16 @@ +module Filters + class CISkip + def initialize(pull_requests:, input: Input.instance) + @pull_requests = pull_requests + @input = input + end + + def pull_requests + unless @input.source.disable_ci_skip + @memoized ||= @pull_requests.delete_if { |pr| pr.latest_commit_message =~ /\[(ci skip|skip ci)\]/ } + else + @pull_requests + end + end + end +end \ No newline at end of file diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index a8ad96f..f9c758e 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -2,11 +2,12 @@ require_relative 'filters/fork' require_relative 'filters/label' require_relative 'filters/path' +require_relative 'filters/ci_skip' class Repository attr_reader :name - def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label]) + def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label, Filters::CISkip]) @filters = filters @name = name @input = input From 6691dd1802f87556fc1c27c9bb18ce643fb547dd Mon Sep 17 00:00:00 2001 From: JT Archie Date: Tue, 23 Jan 2018 07:58:09 -0700 Subject: [PATCH 061/106] refactor ci skip option --- assets/lib/filters/all.rb | 2 +- assets/lib/filters/ci_skip.rb | 11 +++++--- assets/lib/pull_request.rb | 10 ++----- spec/commands/check_spec.rb | 12 ++------- spec/commands/out_spec.rb | 2 -- spec/filters/ci_skip_spec.rb | 51 +++++++++++++++++++++++++++++++++++ spec/filters/label_spec.rb | 4 +-- spec/filters/path_spec.rb | 4 +-- 8 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 spec/filters/ci_skip_spec.rb diff --git a/assets/lib/filters/all.rb b/assets/lib/filters/all.rb index 503b0e8..04606e5 100644 --- a/assets/lib/filters/all.rb +++ b/assets/lib/filters/all.rb @@ -9,7 +9,7 @@ def initialize(pull_requests: [], input: Input.instance) def pull_requests @pull_requests ||= Octokit.pulls(input.source.repo, pull_options).map do |pr| - PullRequest.new(pr: pr, top_commit: Octokit.commit(input.source.repo, pr['head']['sha'])) + PullRequest.new(pr: pr) end end diff --git a/assets/lib/filters/ci_skip.rb b/assets/lib/filters/ci_skip.rb index 15ccbd6..73987c1 100644 --- a/assets/lib/filters/ci_skip.rb +++ b/assets/lib/filters/ci_skip.rb @@ -6,11 +6,14 @@ def initialize(pull_requests:, input: Input.instance) end def pull_requests - unless @input.source.disable_ci_skip - @memoized ||= @pull_requests.delete_if { |pr| pr.latest_commit_message =~ /\[(ci skip|skip ci)\]/ } - else + if !@input.source.ci_skip @pull_requests + else + @memoized ||= @pull_requests.delete_if do |pr| + latest_commit = Octokit.commit(@input.source.repo, pr.sha) + latest_commit['commit']['message'] =~ /\[(ci skip|skip ci)\]/ + end end end end -end \ No newline at end of file +end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index ea37a61..e79a3e1 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -3,13 +3,11 @@ class PullRequest def self.from_github(repo:, id:) pr = Octokit.pull_request(repo.name, id) - tc = Octokit.commit(repo.name, pr['head']['sha']) - PullRequest.new(pr: pr, top_commit: tc) + PullRequest.new(pr: pr) end - def initialize(pr:, top_commit:) + def initialize(pr:) @pr = pr - @top_commit = top_commit end def from_fork? @@ -36,10 +34,6 @@ def sha @pr['head']['sha'] end - def latest_commit_message - @top_commit['commit']['message'] - end - def url @pr['html_url'] end diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 8133b5d..0eaf419 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -19,7 +19,6 @@ def stub_json(uri, body) before do stub_json('https://api.github.com/repos/jtarchie/test/statuses/abcdef', []) stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) - stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: {message: 'foo bar'}}) end it 'retrieves pull requests for the specified base branch' do @@ -48,7 +47,6 @@ def stub_json(uri, body) context 'when there is an open pull request' do before do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) - stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: { message: 'foo bar'} }) end it 'returns SHA of the pull request' do @@ -68,11 +66,11 @@ def stub_json(uri, body) context 'and the top commit has [ci skip] in its message' do before do stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) - stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: {message: 'foo [ci skip] bar'}}) + stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', sha: 'abcdef', commit: { message: 'foo [ci skip] bar' }) end it 'returns no versions' do - expect(check('source' => { 'repo' => 'jtarchie/test' }, 'version' => {})).to eq [] + expect(check('source' => { 'repo' => 'jtarchie/test', 'ci_skip' => true }, 'version' => {})).to eq [] end end end @@ -83,8 +81,6 @@ def stub_json(uri, body) { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } ]) - stub_json('https://api.github.com:443/repos/jtarchie/test/commits/abcdef', {sha: 'abcdef', commit: { message: 'foo bar' }}) - stub_json('https://api.github.com:443/repos/jtarchie/test/commits/zyxwvu', {sha: 'abcdef', commit: { message: 'foo bar'}}) end it 'returns all PRs oldest to newest last' do @@ -120,10 +116,6 @@ def stub_cache_json(uri) { number: i, head: { sha: "abcdef-#{i}", repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } } end - (1..100).each do |j| - stub_json("https://api.github.com:443/repos/jtarchie/test/commits/abcdef-#{j}", {sha: "abcdef-#{j}", commit: {message: 'foo bar'}}) - end - stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], 'Link' => '; rel="next"') stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 3bdd0ae..cf13f62 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -127,8 +127,6 @@ def stub_json(method, uri, body) html_url: 'http://example.com', number: 1, head: { sha: 'abcdef' }) - stub_json(:get, 'https://api.github.com:443/repos/jtarchie/test/commits/abcdef', - sha: "abcdef-#{j}", commit: { message: 'foo bar' }) end context 'when setting a status with a comment' do diff --git a/spec/filters/ci_skip_spec.rb b/spec/filters/ci_skip_spec.rb new file mode 100644 index 0000000..474d295 --- /dev/null +++ b/spec/filters/ci_skip_spec.rb @@ -0,0 +1,51 @@ +require_relative '../../assets/lib/filters/ci_skip' +require_relative '../../assets/lib/pull_request' +require_relative '../../assets/lib/input' +require 'webmock/rspec' + +describe Filters::CISkip do + let(:ignore_pr) do + PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' } }) + end + + let(:pr) do + PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' } }) + end + + let(:pull_requests) { [ignore_pr, pr] } + + def stub_json(uri, body) + stub_request(:get, uri) + .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) + end + + context 'when ci skip is disabled' do + it 'does not filter' do + payload = { 'source' => { 'repo' => 'user/repo' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + + it 'does not filter when explictly disabled' do + payload = { 'source' => { 'repo' => 'user/repo', 'ci_skip' => false } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + end + + context 'when the ci skip filterings is enabled' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/commits/abc}, 'commit' => { 'message' => '[ci skip]' }) + stub_json(%r{https://api.github.com/repos/user/repo/commits/def}, 'commit' => { 'message' => 'do not skip' }) + end + + it 'only returns PRs with that label' do + payload = { 'source' => { 'repo' => 'user/repo', 'ci_skip' => true } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end +end diff --git a/spec/filters/label_spec.rb b/spec/filters/label_spec.rb index 493d480..d34e82b 100644 --- a/spec/filters/label_spec.rb +++ b/spec/filters/label_spec.rb @@ -5,11 +5,11 @@ describe Filters::Label do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1 }, top_commit: {}) + PullRequest.new(pr: { 'number' => 1 }) end let(:pr) do - PullRequest.new(pr: { 'number' => 2 }, top_commit: {}) + PullRequest.new(pr: { 'number' => 2 }) end let(:pull_requests) { [ignore_pr, pr] } diff --git a/spec/filters/path_spec.rb b/spec/filters/path_spec.rb index 3d206aa..36d393b 100644 --- a/spec/filters/path_spec.rb +++ b/spec/filters/path_spec.rb @@ -4,11 +4,11 @@ describe Filters::Path do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1 }, top_commit: {}) + PullRequest.new(pr: { 'number' => 1 }) end let(:pr) do - PullRequest.new(pr: { 'number' => 2 }, top_commit: {}) + PullRequest.new(pr: { 'number' => 2 }) end let(:pull_requests) { [ignore_pr, pr] } From 6aad4b55ebbf3cb46320d25ae1cad6c12991d256 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 27 Jan 2018 11:24:04 -0700 Subject: [PATCH 062/106] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a62700..9c9f239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v32 @ 1/27/2018 + +* enable filtering out PRs that have `ci_skip` messages (thanks @aditya87) + # v31 @ 11/7/2017 * apply `depth` to the `git fetch` of the PR (thanks @bhcleek) From 01e0bae0f38c3d37576b5f3e565998727a92f3f5 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 27 Jan 2018 11:25:24 -0700 Subject: [PATCH 063/106] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3879183..4764850 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,9 @@ marked with that specific label. It is case insensitive. * `ignore_paths`: *Optional.* The inverse of `paths`; changes to the specified files are ignored. + +* `ci_skip`: *Optional.* Filters out PRs that have `[ci skip]` message. Default + is `false`. * `skip_ssl_verification`: *Optional.* Skips git ssl verification by exporting `GIT_SSL_NO_VERIFY=true`. From 4137635d96850fa3870d50b4008cda5b57443da9 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Fri, 16 Feb 2018 21:41:56 -0700 Subject: [PATCH 064/106] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 4764850..ec95666 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,6 @@ To ensure that `check` can iterate over all PRs, you must explicitly define an Clones the repository to the destination, and locks it down to a given ref. It is important to specify `version: every`, otherwise you will only ever get the latest PR. -Submodules are initialized and updated recursively, there is no option to to disable that, currently. - There is `git config` information set on the repo about the PR, which can be consumed within your tasks. For example: From 9728a28e0122030e7cf0b481bf8a603c711cd773 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 19 Feb 2018 14:59:38 -0700 Subject: [PATCH 065/106] bump rubygems and ruby version --- .rubocop.yml | 2 +- Gemfile | 2 +- Gemfile.lock | 56 +++++++++++++++++++-------------------- spec/commands/out_spec.rb | 54 +++++++++++++++++++------------------ spec/support/cli.rb | 4 +-- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 077ce8f..5cf91e8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -6,4 +6,4 @@ Style/FrozenStringLiteralComment: Enabled: false AllCops: - TargetRubyVersion: 2.4 + TargetRubyVersion: 2.5 diff --git a/Gemfile b/Gemfile index a6f7ee4..3017aff 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' -ruby '~> 2.4' +ruby '~> 2.5' gem 'activesupport' gem 'faraday-http-cache' diff --git a/Gemfile.lock b/Gemfile.lock index 4bb0512..82224a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,14 +1,14 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.1.4) + activesupport (5.1.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) - ast (2.3.0) + ast (2.4.0) coderay (1.1.2) concurrent-ruby (1.0.5) cookiejar (0.3.3) @@ -21,51 +21,49 @@ GEM em-socksify (>= 0.3) eventmachine (>= 1.0.3) http_parser.rb (>= 0.6.0) - em-socksify (0.3.1) + em-socksify (0.3.2) eventmachine (>= 1.0.0.beta.4) em-synchrony (1.0.6) eventmachine (>= 1.0.0.beta.1) - eventmachine (1.2.5) + eventmachine (1.2.0.1) eventmachine_httpserver (0.2.1) - faraday (0.13.1) + faraday (0.14.0) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) hashdiff (0.3.7) http_parser.rb (0.6.0) httpclient (2.8.3) - i18n (0.9.1) + i18n (0.9.5) concurrent-ruby (~> 1.0) method_source (0.9.0) - minitest (5.10.3) - multi_json (1.12.2) + minitest (5.11.3) + multi_json (1.13.1) multipart-post (2.0.0) - octokit (4.7.0) + octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) - parallel (1.12.0) - parser (2.4.0.2) - ast (~> 2.3) + parallel (1.12.1) + parser (2.5.0.0) + ast (~> 2.4.0) powerpack (0.1.1) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) - public_suffix (3.0.1) - puffing-billy (0.11.0) + public_suffix (3.0.2) + puffing-billy (0.12.0) addressable (~> 2.4, >= 2.4.0) em-http-request (~> 1.1, >= 1.1.0) em-synchrony - eventmachine (~> 1.0, >= 1.0.4) + eventmachine (= 1.2.0.1) eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json - rainbow (2.2.2) - rake - rake (12.3.0) + rainbow (3.0.0) rspec (3.7.0) rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) rspec-mocks (~> 3.7.0) - rspec-core (3.7.0) + rspec-core (3.7.1) rspec-support (~> 3.7.0) rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) @@ -73,26 +71,26 @@ GEM rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) - rspec-support (3.7.0) - rubocop (0.51.0) + rspec-support (3.7.1) + rubocop (0.52.1) parallel (~> 1.10) - parser (>= 2.3.3.1, < 3.0) + parser (>= 2.4.0.2, < 3.0) powerpack (~> 0.1) - rainbow (>= 2.2.2, < 3.0) + rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.20.1) - rubocop (>= 0.51.0) + rubocop-rspec (1.22.2) + rubocop (>= 0.52.1) ruby-progressbar (1.9.0) safe_yaml (1.0.4) sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) thread_safe (0.3.6) - tzinfo (1.2.4) + tzinfo (1.2.5) thread_safe (~> 0.1) unicode-display_width (1.3.0) - webmock (3.1.1) + webmock (3.3.0) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff @@ -113,7 +111,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 2.4.0p0 + ruby 2.5.0p0 BUNDLED WITH - 1.15.4 + 1.16.1 diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index cf13f62..983cef8 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -45,6 +45,26 @@ def stub_json(method, uri, body) end context 'when the git repo has no pull request meta information' do + it 'sets the status just on the SHA' do + stub_status_post + + output = put('params' => { 'status' => 'pending', 'path' => 'resource' }, 'source' => { 'repo' => 'jtarchie/test' }) + expect(output).to eq('version' => { 'ref' => @sha }, + 'metadata' => [ + { 'name' => 'status', 'value' => 'pending' } + ]) + end + end + + context 'when the git repo has the pull request meta information' do + before do + git('config --add pullrequest.id 1') + stub_json(:get, 'https://api.github.com:443/repos/jtarchie/test/pulls/1', + html_url: 'http://example.com', + number: 1, + head: { sha: 'abcdef' }) + end + context 'when the merge is set' do it 'retuns an error for unsupported merge types' do stub_status_post @@ -56,13 +76,14 @@ def stub_json(method, uri, body) it 'returns metadata on success' do stub_status_post - stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/merge') + stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/1/merge') .with(body: { merge_method: 'merge', commit_message: '' }.to_json) output = put('params' => { 'status' => 'success', 'merge' => { 'method' => 'merge' }, 'path' => 'resource' }, 'source' => { 'repo' => 'jtarchie/test' }) - expect(output).to eq('version' => { 'ref' => @sha }, + expect(output).to eq('version' => { 'pr' => '1', 'ref' => @sha }, 'metadata' => [ { 'name' => 'status', 'value' => 'success' }, + { 'name' => 'url', 'value' => 'http://example.com' }, { 'name' => 'merge', 'value' => 'merge' }, { 'name' => 'merge_commit_msg', 'value' => '' } ]) @@ -71,7 +92,7 @@ def stub_json(method, uri, body) context 'on merge failure' do it 'raises an error' do stub_status_post - stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/merge') + stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/1/merge') .to_return(status: 405) expect do @@ -85,13 +106,14 @@ def stub_json(method, uri, body) File.write(File.join(dest_dir, 'merge_commit_msg'), 'merge commit message') stub_status_post - stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/merge') + stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/1/merge') .with(body: { merge_method: 'merge', commit_message: 'merge commit message' }.to_json) output = put('params' => { 'status' => 'success', 'merge' => { 'method' => 'merge', 'commit_msg' => 'resource/merge_commit_msg' }, 'path' => 'resource' }, 'source' => { 'repo' => 'jtarchie/test' }) - expect(output).to eq('version' => { 'ref' => @sha }, + expect(output).to eq('version' => { 'pr' => '1', 'ref' => @sha }, 'metadata' => [ { 'name' => 'status', 'value' => 'success' }, + { 'name' => 'url', 'value' => 'http://example.com' }, { 'name' => 'merge', 'value' => 'merge' }, { 'name' => 'merge_commit_msg', 'value' => 'merge commit message' } ]) @@ -99,7 +121,7 @@ def stub_json(method, uri, body) it 'returns an error if the file does not exist' do stub_status_post - stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/merge') + stub_request(:put, 'https://api.github.com/repos/jtarchie/test/pulls/123/merge') .with(body: { merge_method: 'merge', commit_message: 'merge commit message' }.to_json) expect do @@ -109,26 +131,6 @@ def stub_json(method, uri, body) end end - it 'sets the status just on the SHA' do - stub_status_post - - output = put('params' => { 'status' => 'pending', 'path' => 'resource' }, 'source' => { 'repo' => 'jtarchie/test' }) - expect(output).to eq('version' => { 'ref' => @sha }, - 'metadata' => [ - { 'name' => 'status', 'value' => 'pending' } - ]) - end - end - - context 'when the git repo has the pull request meta information' do - before do - git('config --add pullrequest.id 1') - stub_json(:get, 'https://api.github.com:443/repos/jtarchie/test/pulls/1', - html_url: 'http://example.com', - number: 1, - head: { sha: 'abcdef' }) - end - context 'when setting a status with a comment' do before do File.write(File.join(dest_dir, 'comment'), 'comment message') diff --git a/spec/support/cli.rb b/spec/support/cli.rb index cda74c7..d2c9e81 100644 --- a/spec/support/cli.rb +++ b/spec/support/cli.rb @@ -17,7 +17,7 @@ def get(payload = {}) response = begin JSON.parse(output) - rescue + rescue StandardError nil end [response, error] @@ -34,7 +34,7 @@ def put(payload = {}) response = begin JSON.parse(output) - rescue + rescue StandardError nil end [response, error] From 8bfefee20ba9eee3212a8d26d39e388df3dc41ec Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 19 Feb 2018 15:09:02 -0700 Subject: [PATCH 066/106] replace no_ssl_verify with skip_ssl_verification --- assets/lib/commands/base.rb | 2 +- spec/commands/check_spec.rb | 2 +- spec/commands/in_spec.rb | 2 +- spec/commands/out_spec.rb | 2 +- spec/integration/check_spec.rb | 2 +- spec/support/cli.rb | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index 3affe17..6112b2f 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -29,7 +29,7 @@ def initialize(input: Input.instance) def setup_octokit Octokit.auto_paginate = true - Octokit.connection_options[:ssl] = { verify: false } if input.source.no_ssl_verify + Octokit.connection_options[:ssl] = { verify: false } if input.source.skip_ssl_verification Octokit.configure do |c| c.api_endpoint = input.source.api_endpoint if input.source.api_endpoint c.access_token = input.source.access_token diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 0eaf419..548bb2e 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -4,7 +4,7 @@ describe Commands::Check do def check(payload) - payload['source']['no_ssl_verify'] = true + payload['source']['skip_ssl_verification'] = true Input.instance(payload: payload) Commands::Check.new.output.map &:as_json diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 3ba83c2..d604cfb 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -15,7 +15,7 @@ def git_uri let(:dest_dir) { Dir.mktmpdir } def get(payload) - payload['source']['no_ssl_verify'] = true + payload['source']['skip_ssl_verification'] = true Input.instance(payload: payload) command = Commands::In.new(destination: dest_dir) command.output diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 983cef8..2b05ff6 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -16,7 +16,7 @@ def commit(msg) end def put(payload) - payload['source']['no_ssl_verify'] = true + payload['source']['skip_ssl_verification'] = true Input.instance(payload: payload) resource_dir = Dir.mktmpdir diff --git a/spec/integration/check_spec.rb b/spec/integration/check_spec.rb index 100e111..28117f3 100644 --- a/spec/integration/check_spec.rb +++ b/spec/integration/check_spec.rb @@ -4,7 +4,7 @@ describe 'check' do def check(payload) path = ['./assets/check', '/opt/resource/check'].find { |p| File.exist? p } - payload[:source][:no_ssl_verify] = true + payload[:source][:skip_ssl_verification] = true output = `echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path}` JSON.parse(output) diff --git a/spec/support/cli.rb b/spec/support/cli.rb index d2c9e81..d994ef2 100644 --- a/spec/support/cli.rb +++ b/spec/support/cli.rb @@ -3,7 +3,7 @@ module CliIntegration def check(payload) path = ['./assets/check', '/opt/resource/check'].find { |p| File.exist? p } - payload[:source][:no_ssl_verify] = true + payload[:source][:skip_ssl_verification] = true output = `echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path}` JSON.parse(output) @@ -11,7 +11,7 @@ def check(payload) def get(payload = {}) path = ['./assets/in', '/opt/resource/in'].find { |p| File.exist? p } - payload[:source][:no_ssl_verify] = true + payload[:source][:skip_ssl_verification] = true output, error, = Open3.capture3("echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path} #{dest_dir}") @@ -25,7 +25,7 @@ def get(payload = {}) def put(payload = {}) path = ['./assets/out', '/opt/resource/out'].find { |p| File.exist? p } - payload[:source][:no_ssl_verify] = true + payload[:source][:skip_ssl_verification] = true resource_dir = Dir.mktmpdir FileUtils.cp_r(dest_dir, File.join(resource_dir, 'resource')) From 1f8cdef5e26acada4f5380cde311f8f07ff12025 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Mon, 19 Feb 2018 15:10:44 -0700 Subject: [PATCH 067/106] update documentation --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ec95666..7517c3d 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ marked with that specific label. It is case insensitive. is `false`. * `skip_ssl_verification`: *Optional.* Skips git ssl verification by exporting - `GIT_SSL_NO_VERIFY=true`. + `GIT_SSL_NO_VERIFY=true` and applying it to the Github API client. * `git_config`: *Optional*. If specified as (list of pairs `name` and `value`) it will configure git global options, setting each name with each value. @@ -100,8 +100,9 @@ To ensure that `check` can iterate over all PRs, you must explicitly define an ### `in`: Clone the repository, at the given pull request ref -Clones the repository to the destination, and locks it down to a given ref. It is important -to specify `version: every`, otherwise you will only ever get the latest PR. +Clones the repository to the destination, and locks it down to a given ref. It +is important to specify `version: every`, otherwise you will only ever get the +latest PR. There is `git config` information set on the repo about the PR, which can be consumed within your tasks. From 8007216327b6bc3efef035219dc7b71f88b69f2f Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Thu, 22 Feb 2018 01:59:53 +0000 Subject: [PATCH 068/106] Store pull request body. --- README.md | 2 ++ assets/lib/commands/in.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index 7517c3d..3170d87 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,8 @@ git config --get pullrequest.userlogin # returns the github user login for the * `.git/head_sha`: the latest commit hash of the branch associated with the pull request + * `.git/body`: the body of the pull request. + #### Parameters * `git.depth`: *Optional.* If a positive integer is given, *shallow* clone the diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 561d5b5..c908724 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -28,6 +28,7 @@ def output system <<-BASH echo "#{pr['html_url']}" > url echo "#{pr['number']}" > id + echo "#{pr['body']}" > body echo "#{pr['head']['ref']}" > branch echo "#{pr['base']['ref']}" > base_branch echo "#{pr['user']['login']}" > userlogin From aca89639fd5d27221f255a1f8ab9736e4b769575 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Thu, 22 Feb 2018 19:19:32 +0000 Subject: [PATCH 069/106] add test for PR body. --- spec/commands/in_spec.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index d604cfb..5cc0798 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -52,7 +52,7 @@ def dest_dir end before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }, user: { login: 'jtarchie-contributor' }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }, body: 'PR Body', user: { login: 'jtarchie-contributor' }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end @@ -117,6 +117,11 @@ def dest_dir value = File.read(File.join(dest_dir, '.git', 'head_sha')).strip expect(value).to eq 'hash' end + + it 'creates a file that contains the PR body in the .git folder' do + value = File.read(File.join(dest_dir, '.git', 'body')).strip + expect(value).to eq 'PR Body' + end end context 'when the git clone fails' do From 745ffc4e3844b41ccb0193cece389cbb6e89231c Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 24 Feb 2018 09:56:50 -0700 Subject: [PATCH 070/106] add config for pullrequest body --- README.md | 1 + assets/lib/commands/in.rb | 1 + spec/commands/in_spec.rb | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 3170d87..ceaf9db 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ For example: git config --get pullrequest.url # returns the URL to the pull request git config --get pullrequest.branch # returns the branch name used for the pull request git config --get pullrequest.id # returns the ID number of the PR +git config --get pullrequest.body # returns the PR body git config --get pullrequest.basebranch # returns the base branch used for the pull request git config --get pullrequest.userlogin # returns the github user login for the pull request author ``` diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index c908724..3092900 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -43,6 +43,7 @@ def output git checkout #{branch_ref} 1>&2 git config --add pullrequest.url #{pr['html_url']} 1>&2 git config --add pullrequest.id #{pr['number']} 1>&2 + git config --add pullrequest.body '#{pr['body']}' 1>&2 git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 git config --add pullrequest.userlogin #{pr['user']['login']} 1>&2 diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 5cc0798..e810c31 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -78,6 +78,11 @@ def dest_dir expect(value).to eq 'pr-foo' end + it 'sets config of the PR body' do + value = git('config --get pullrequest.body', dest_dir) + expect(value).to eq 'PR Body' + end + it 'sets config variable to branch name' do value = git('config pullrequest.branch', dest_dir) expect(value).to eq 'foo' From a4470212cf565bc34285ef483871a8143ff0ffa2 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 24 Feb 2018 10:08:36 -0700 Subject: [PATCH 071/106] set ruby version to alpine supported --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3017aff..a6f7ee4 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' -ruby '~> 2.5' +ruby '~> 2.4' gem 'activesupport' gem 'faraday-http-cache' From 786877fa4641b69005cded28fe2562a572c2862c Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 24 Feb 2018 10:17:54 -0700 Subject: [PATCH 072/106] dockerfile runs tests now --- Dockerfile | 15 ++++++++++++++- Dockerfile.test | 23 ----------------------- README.md | 6 ++++++ 3 files changed, 20 insertions(+), 24 deletions(-) delete mode 100644 Dockerfile.test diff --git a/Dockerfile b/Dockerfile index 40e9e43..e32b57d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine as resource RUN apk add --update ca-certificates RUN apk add --update curl @@ -14,3 +14,16 @@ ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* ADD scripts/install_git_lfs.sh install_git_lfs.sh RUN ./install_git_lfs.sh + +FROM resource as tests +COPY . /resource + +RUN apk add --update \ + ruby-bundler \ + ruby-io-console \ + ruby-dev \ + openssl-dev \ + alpine-sdk +RUN cd /resource && bundle install && bundle exec rspec + +FROM resource diff --git a/Dockerfile.test b/Dockerfile.test deleted file mode 100644 index f01bffb..0000000 --- a/Dockerfile.test +++ /dev/null @@ -1,23 +0,0 @@ -FROM alpine - -RUN apk add --update ca-certificates -RUN apk add --update curl -RUN apk add --update git -RUN apk add --update jq -RUN apk add --update openssh-client -RUN apk add --update perl -RUN apk add --update ruby -RUN apk add --update ruby-json -RUN gem install octokit activesupport httpclient faraday-http-cache --no-rdoc --no-ri - -ADD assets/ /opt/resource/ -RUN chmod +x /opt/resource/* -ADD scripts/install_git_lfs.sh install_git_lfs.sh -RUN ./install_git_lfs.sh - -RUN apk add --update \ - ruby-bundler \ - ruby-io-console \ - ruby-dev \ - openssl-dev \ - alpine-sdk diff --git a/README.md b/README.md index ceaf9db..8b4d977 100644 --- a/README.md +++ b/README.md @@ -188,3 +188,9 @@ Requires `ruby` to be installed. bundle install bundle exec rspec ``` + +Or with the `Dockerfile`, which runs the tests to see if it can successfully build: + + ``` + docker build . + ``` From 813021a927064dfc35d39c81b8f52a87e271fe49 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Sat, 24 Feb 2018 10:20:13 -0700 Subject: [PATCH 073/106] remove tests as they are run on Dockerfile now --- .concourse.yml | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/.concourse.yml b/.concourse.yml index e196a6b..4ff405c 100644 --- a/.concourse.yml +++ b/.concourse.yml @@ -41,7 +41,7 @@ jobs: - name: create-pr plan: - get: git-pr - passed: [ 'tests' ] + passed: [ 'docker' ] trigger: true - task: create config: @@ -150,29 +150,10 @@ jobs: - put: docker-pr params: build: git-pr - dockerfile: git-pr/Dockerfile.test + dockerfile: git-pr/Dockerfile tag: tag/name get_params: skip_download: true - - name: tests - plan: - - get: git-pr - passed: [ docker ] - trigger: true - - task: rspec - privileged: true - config: - image_resource: - type: docker-image - source: - repository: jtarchie/pr - tag: test - inputs: - - name: git-pr - platform: linux - run: - path: sh - args: ['-c', 'cd git-pr && bundle install && bundle exec rspec'] - name: release plan: - get: git-pr From aa6ca9a0a97881d52b81cc82a903212291a1eab9 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 28 Feb 2018 07:21:39 -0700 Subject: [PATCH 074/106] fix escaping shell commands --- assets/lib/commands/in.rb | 29 ++++++++++++++--------------- spec/commands/in_spec.rb | 22 +++++++++++++++++++--- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 3092900..5cb3b41 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -2,6 +2,7 @@ require 'English' require 'json' +require 'shellwords' require_relative 'base' module Commands @@ -25,15 +26,13 @@ def output raise 'git clone failed' unless $CHILD_STATUS.exitstatus.zero? Dir.chdir(File.join(destination, '.git')) do - system <<-BASH - echo "#{pr['html_url']}" > url - echo "#{pr['number']}" > id - echo "#{pr['body']}" > body - echo "#{pr['head']['ref']}" > branch - echo "#{pr['base']['ref']}" > base_branch - echo "#{pr['user']['login']}" > userlogin - echo "#{pr['head']['sha']}" > head_sha - BASH + File.write('url', pr['html_url']) + File.write('id', pr['number']) + File.write('body', pr['body']) + File.write('branch', pr['head']['ref']) + File.write('base_branch', pr['base']['ref']) + File.write('userlogin', pr['user']['login']) + File.write('head_sha', pr['head']['sha']) end Dir.chdir(destination) do @@ -41,12 +40,12 @@ def output system <<-BASH git checkout #{branch_ref} 1>&2 - git config --add pullrequest.url #{pr['html_url']} 1>&2 - git config --add pullrequest.id #{pr['number']} 1>&2 - git config --add pullrequest.body '#{pr['body']}' 1>&2 - git config --add pullrequest.branch #{pr['head']['ref']} 1>&2 - git config --add pullrequest.basebranch #{pr['base']['ref']} 1>&2 - git config --add pullrequest.userlogin #{pr['user']['login']} 1>&2 + git config --add pullrequest.url #{pr['html_url'].to_s.shellescape} 1>&2 + git config --add pullrequest.id #{pr['number'].to_s.shellescape} 1>&2 + git config --add pullrequest.body #{pr['body'].to_s.shellescape} 1>&2 + git config --add pullrequest.branch #{pr['head']['ref'].to_s.shellescape} 1>&2 + git config --add pullrequest.basebranch #{pr['base']['ref'].to_s.shellescape} 1>&2 + git config --add pullrequest.userlogin #{pr['user']['login'].to_s.shellescape} 1>&2 BASH case input.params.git.submodules diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index e810c31..d6cabe1 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -52,7 +52,23 @@ def dest_dir end before(:all) do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', html_url: 'http://example.com', number: 1, head: { ref: 'foo', sha: 'hash' }, base: { ref: 'master', user: { login: 'jtarchie' } }, body: 'PR Body', user: { login: 'jtarchie-contributor' }) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls/1', + html_url: 'http://example.com', + number: 1, + head: { + ref: 'foo', + sha: 'hash' + }, + base: { + ref: 'master', + user: { + login: 'jtarchie' + } + }, + body: %(A comment with shell stuff var='\'`rm -rf ./*`\''), + user: { + login: 'jtarchie-contributor' + }) @output = get('version' => { 'ref' => @ref, 'pr' => '1' }, 'source' => { 'uri' => git_uri, 'repo' => 'jtarchie/test' }) end @@ -80,7 +96,7 @@ def dest_dir it 'sets config of the PR body' do value = git('config --get pullrequest.body', dest_dir) - expect(value).to eq 'PR Body' + expect(value).to eq "A comment with shell stuff var=''`rm -rf ./*`''" end it 'sets config variable to branch name' do @@ -125,7 +141,7 @@ def dest_dir it 'creates a file that contains the PR body in the .git folder' do value = File.read(File.join(dest_dir, '.git', 'body')).strip - expect(value).to eq 'PR Body' + expect(value).to eq "A comment with shell stuff var=''`rm -rf ./*`''" end end From 2832ac6b2d2f0a86954cb310fd7b73062d712586 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 28 Feb 2018 14:54:19 -0700 Subject: [PATCH 075/106] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b4d977..1c32ce7 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ Please see this repo's [pipeline](https://github.com/jtarchie/pullrequest-resour There's also an [example](https://github.com/starkandwayne/concourse-pullrequest-playtime) by @starkandwayne. -## Tests +## Running the tests Requires `ruby` to be installed. From 4e8a64a7f0a5c8448727396740a603f31e351129 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 28 Feb 2018 21:46:38 -0700 Subject: [PATCH 076/106] freeze the strings --- .rubocop.yml | 2 +- Gemfile.lock | 4 ++-- assets/lib/commands/base.rb | 2 ++ assets/lib/commands/check.rb | 1 + assets/lib/commands/in.rb | 1 + assets/lib/commands/out.rb | 6 ++++-- assets/lib/filters/all.rb | 2 ++ assets/lib/filters/ci_skip.rb | 2 ++ assets/lib/filters/fork.rb | 2 ++ assets/lib/filters/label.rb | 2 ++ assets/lib/filters/path.rb | 2 ++ assets/lib/input.rb | 2 ++ assets/lib/pull_request.rb | 2 ++ assets/lib/repository.rb | 2 ++ assets/lib/status.rb | 2 ++ spec/commands/check_spec.rb | 2 ++ spec/commands/in_spec.rb | 2 ++ spec/commands/out_spec.rb | 2 ++ spec/filters/ci_skip_spec.rb | 2 ++ spec/filters/label_spec.rb | 2 ++ spec/filters/path_spec.rb | 2 ++ spec/integration/check_spec.rb | 2 ++ spec/integration/in_spec.rb | 2 ++ spec/integration/out_spec.rb | 2 ++ spec/spec_helper.rb | 2 ++ spec/support/cli.rb | 2 ++ spec/support/proxy.rb | 2 ++ 27 files changed, 53 insertions(+), 5 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 5cf91e8..59228f1 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,7 +3,7 @@ require: rubocop-rspec Style/FrozenStringLiteralComment: - Enabled: false + Enabled: always AllCops: TargetRubyVersion: 2.5 diff --git a/Gemfile.lock b/Gemfile.lock index 82224a0..561bab0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -43,7 +43,7 @@ GEM octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) parallel (1.12.1) - parser (2.5.0.0) + parser (2.5.0.2) ast (~> 2.4.0) powerpack (0.1.1) pry (0.11.3) @@ -79,7 +79,7 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.22.2) + rubocop-rspec (1.23.0) rubocop (>= 0.52.1) ruby-progressbar (1.9.0) safe_yaml (1.0.4) diff --git a/assets/lib/commands/base.rb b/assets/lib/commands/base.rb index 6112b2f..4af37ec 100644 --- a/assets/lib/commands/base.rb +++ b/assets/lib/commands/base.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'faraday' require 'octokit' require 'faraday-http-cache' diff --git a/assets/lib/commands/check.rb b/assets/lib/commands/check.rb index 9faea01..792e211 100755 --- a/assets/lib/commands/check.rb +++ b/assets/lib/commands/check.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'json' require_relative 'base' diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 5cb3b41..0d4a65e 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'English' require 'json' diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index 41b1fb6..4a21cf6 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'json' require_relative 'base' @@ -86,10 +87,11 @@ def output private def whitelist(context:) + c = context.dup %w[BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL].each do |name| - context.gsub!("$#{name}", ENV[name] || '') + c.gsub!("$#{name}", ENV[name] || '') end - context + c end def params diff --git a/assets/lib/filters/all.rb b/assets/lib/filters/all.rb index 04606e5..7a1c2e2 100644 --- a/assets/lib/filters/all.rb +++ b/assets/lib/filters/all.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'octokit' require_relative '../pull_request' diff --git a/assets/lib/filters/ci_skip.rb b/assets/lib/filters/ci_skip.rb index 73987c1..65f45ab 100644 --- a/assets/lib/filters/ci_skip.rb +++ b/assets/lib/filters/ci_skip.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Filters class CISkip def initialize(pull_requests:, input: Input.instance) diff --git a/assets/lib/filters/fork.rb b/assets/lib/filters/fork.rb index 6bc139a..f06c923 100644 --- a/assets/lib/filters/fork.rb +++ b/assets/lib/filters/fork.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Filters class Fork def initialize(pull_requests:, input: Input.instance) diff --git a/assets/lib/filters/label.rb b/assets/lib/filters/label.rb index 4f2e2db..56255ef 100644 --- a/assets/lib/filters/label.rb +++ b/assets/lib/filters/label.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Filters class Label def initialize(pull_requests:, input: Input.instance) diff --git a/assets/lib/filters/path.rb b/assets/lib/filters/path.rb index 5afedb4..2126c4e 100644 --- a/assets/lib/filters/path.rb +++ b/assets/lib/filters/path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../input' module Filters diff --git a/assets/lib/input.rb b/assets/lib/input.rb index 70b8ae9..78d1d4c 100644 --- a/assets/lib/input.rb +++ b/assets/lib/input.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'json' require 'ostruct' diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index e79a3e1..c9efa2f 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'octokit' class PullRequest diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index f9c758e..30318a8 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'filters/all' require_relative 'filters/fork' require_relative 'filters/label' diff --git a/assets/lib/status.rb b/assets/lib/status.rb index 28d0773..6fdd982 100644 --- a/assets/lib/status.rb +++ b/assets/lib/status.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'octokit' class Status diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 548bb2e..d225402 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/commands/check' require 'webmock/rspec' require 'json' diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index d6cabe1..6fa6a0e 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'json' require 'tmpdir' require 'webmock/rspec' diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 2b05ff6..9114a4f 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'json' require 'tmpdir' require 'webmock/rspec' diff --git a/spec/filters/ci_skip_spec.rb b/spec/filters/ci_skip_spec.rb index 474d295..a511d1b 100644 --- a/spec/filters/ci_skip_spec.rb +++ b/spec/filters/ci_skip_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/filters/ci_skip' require_relative '../../assets/lib/pull_request' require_relative '../../assets/lib/input' diff --git a/spec/filters/label_spec.rb b/spec/filters/label_spec.rb index d34e82b..a9fb33b 100644 --- a/spec/filters/label_spec.rb +++ b/spec/filters/label_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/filters/label' require_relative '../../assets/lib/pull_request' require_relative '../../assets/lib/input' diff --git a/spec/filters/path_spec.rb b/spec/filters/path_spec.rb index 36d393b..f79205a 100644 --- a/spec/filters/path_spec.rb +++ b/spec/filters/path_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/filters/path' require_relative '../../assets/lib/pull_request' require 'webmock/rspec' diff --git a/spec/integration/check_spec.rb b/spec/integration/check_spec.rb index 28117f3..109a12b 100644 --- a/spec/integration/check_spec.rb +++ b/spec/integration/check_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'json' diff --git a/spec/integration/in_spec.rb b/spec/integration/in_spec.rb index be0a79a..3d9c1e3 100644 --- a/spec/integration/in_spec.rb +++ b/spec/integration/in_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'json' require 'tmpdir' diff --git a/spec/integration/out_spec.rb b/spec/integration/out_spec.rb index 5fbdcbe..a1b8992 100644 --- a/spec/integration/out_spec.rb +++ b/spec/integration/out_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'fileutils' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index de1a667..c29f10b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'support/proxy' require_relative 'support/cli' diff --git a/spec/support/cli.rb b/spec/support/cli.rb index d994ef2..b71425a 100644 --- a/spec/support/cli.rb +++ b/spec/support/cli.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'open3' module CliIntegration diff --git a/spec/support/proxy.rb b/spec/support/proxy.rb index 3890d2b..e5a875c 100644 --- a/spec/support/proxy.rb +++ b/spec/support/proxy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'billy' Billy.configure do |c| From a70a94ba328a0c30059e2ac00594cb83ed29af8d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 8 Mar 2018 06:58:14 -0700 Subject: [PATCH 077/106] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 1c32ce7..5ab0753 100644 --- a/README.md +++ b/README.md @@ -95,9 +95,6 @@ Concourse resources always iterate over the latest version. This maps well to semver and git, but not with pull requests. This filters all open PRs sorted by most recently updated. -To ensure that `check` can iterate over all PRs, you must explicitly define an -`out` for the PR. - ### `in`: Clone the repository, at the given pull request ref Clones the repository to the destination, and locks it down to a given ref. It From 616e4ddfdd730ee33b4eb6d43ed9148e5a0c666a Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Wed, 31 Jan 2018 23:23:24 +0000 Subject: [PATCH 078/106] Check whether a PR is mergeable. --- README.md | 6 ++++++ assets/lib/filters/mergeable.rb | 16 ++++++++++++++++ assets/lib/pull_request.rb | 6 ++++++ assets/lib/repository.rb | 3 ++- 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 assets/lib/filters/mergeable.rb diff --git a/README.md b/README.md index 5ab0753..a212571 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,12 @@ resource_types: * `disable_forks`: *Optional*, default false. If set to `true`, it will filter out pull requests that were created via users that forked from your repo. +* `only_mergeable`: *Optional*, default false. If set to `true`, it will filter + out pull requests that are not mergeable. A pull request is mergeable if + - It has no merge conflicts. + - The current user has push permissions to the base repository. + - It has at least one review and has been Approved. + * `label`: *Optional.* If set to a string it will only return pull requests that have been marked with that specific label. It is case insensitive. diff --git a/assets/lib/filters/mergeable.rb b/assets/lib/filters/mergeable.rb new file mode 100644 index 0000000..fb9a440 --- /dev/null +++ b/assets/lib/filters/mergeable.rb @@ -0,0 +1,16 @@ +module Filters + class Mergeable + def initialize(pull_requests:, input: Input.instance) + @pull_requests = pull_requests + @input = input + end + + def pull_requests + if @input.source.only_mergeable + @memoized ||= @pull_requests.delete_if {|x| !x.mergeable? } + else + @pull_requests + end + end + end +end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index c9efa2f..15e43d6 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -16,6 +16,12 @@ def from_fork? base_repo != head_repo end + def mergeable? + (@pr['mergeable'] && + @pr['base']['repo']['permissions']['push'] && + Octokit.pull_request_reviews(base_repo, id).any? {|r| r['state'] == 'APPROVED'}) + end + def equals?(id:, sha:) [self.sha, self.id.to_s] == [sha, id.to_s] end diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index 30318a8..fdd470a 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -5,11 +5,12 @@ require_relative 'filters/label' require_relative 'filters/path' require_relative 'filters/ci_skip' +require_relative 'filters/mergeable' class Repository attr_reader :name - def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label, Filters::CISkip]) + def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label, Filters::CISkip, Filters::Mergeable]) @filters = filters @name = name @input = input From 68449af95db62e467e5cca3ff961928577472e5c Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Thu, 1 Feb 2018 00:49:49 +0000 Subject: [PATCH 079/106] Add tests for mergeable feature --- spec/filters/mergeable_spec.rb | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 spec/filters/mergeable_spec.rb diff --git a/spec/filters/mergeable_spec.rb b/spec/filters/mergeable_spec.rb new file mode 100644 index 0000000..434b47f --- /dev/null +++ b/spec/filters/mergeable_spec.rb @@ -0,0 +1,53 @@ +require_relative '../../assets/lib/filters/mergeable' +require_relative '../../assets/lib/pull_request' +require_relative '../../assets/lib/input' +require 'webmock/rspec' + +describe Filters::Mergeable do + let(:ignore_pr) do + PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'mergeable' => false, + 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + end + + let(:pr) do + PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'mergeable' => true , + 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + end + + let(:pull_requests) { [ignore_pr, pr] } + + def stub_json(uri, body) + stub_request(:get, uri) + .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) + end + + context 'when mergeable requirement is disabled' do + it 'does not filter' do + payload = { 'source' => { 'repo' => 'user/repo' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + + it 'does not filter when explictly disabled' do + payload = { 'source' => { 'repo' => 'user/repo', 'only_mergeable' => false } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + end + + context 'when the mergeable filtering is enabled' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/pulls/1/reviews}, [{ 'state' => 'CHANGES_REQUESTED' }]) + stub_json(%r{https://api.github.com/repos/user/repo/pulls/2/reviews}, [{ 'state' => 'APPROVED' }]) + end + + it 'only returns PRs with that label' do + payload = { 'source' => { 'repo' => 'user/repo', 'only_mergeable' => true } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end +end From 1c9e05425734e5f6bf25f10434266498f76b0272 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Fri, 2 Feb 2018 23:28:09 +0000 Subject: [PATCH 080/106] Must fetch entire PR using get-one-PR API The result is smaller when you fetch all the PRs as a list instead of fetching them one at a time. We need some of the fields which are in the single-PR view but not the list-PR view. --- assets/lib/filters/all.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lib/filters/all.rb b/assets/lib/filters/all.rb index 7a1c2e2..7abd221 100644 --- a/assets/lib/filters/all.rb +++ b/assets/lib/filters/all.rb @@ -11,7 +11,7 @@ def initialize(pull_requests: [], input: Input.instance) def pull_requests @pull_requests ||= Octokit.pulls(input.source.repo, pull_options).map do |pr| - PullRequest.new(pr: pr) + PullRequest.new(pr: Octokit.pull_request(input.source.repo, pr['number'], pull_options)) end end From 1ebf0791d37a18488c13a837a5f4cadc2919c6c9 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Tue, 6 Feb 2018 22:35:53 +0000 Subject: [PATCH 081/106] Split into several filters. --- assets/lib/filters/approval.rb | 22 ++++++++++++++++++++++ assets/lib/pull_request.rb | 20 +++++++++++++++++--- assets/lib/repository.rb | 3 ++- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 assets/lib/filters/approval.rb diff --git a/assets/lib/filters/approval.rb b/assets/lib/filters/approval.rb new file mode 100644 index 0000000..c31ac38 --- /dev/null +++ b/assets/lib/filters/approval.rb @@ -0,0 +1,22 @@ +module Filters + class Approval + def initialize(pull_requests:, input: Input.instance) + @pull_requests = pull_requests + @input = input + end + + def pull_requests + if @input.source.require_review_approval + @pull_requests.delete_if {|x| !x.review_approved? } + end + if @input.source.require_manual_approval + @pull_requests.delete_if {|x| !x.approved_by_collaborator? } + end + if @input.source.authorship_restriction + @pull_requests.delete_if {|x| !x.author_associated? } + end + + @pull_requests + end + end +end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index 15e43d6..fdff18f 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -17,9 +17,23 @@ def from_fork? end def mergeable? - (@pr['mergeable'] && - @pr['base']['repo']['permissions']['push'] && - Octokit.pull_request_reviews(base_repo, id).any? {|r| r['state'] == 'APPROVED'}) + @pr['mergeable'] + end + + def review_approved? + Octokit.pull_request_reviews(base_repo, id).any? {|r| r['state'] == 'APPROVED'} + end + + def author_associated? + # Checks whether the author is associated with the repo that the PR is against: + # either the owner of that repo, someone invited to collaborate, or a member + # of the organization who owns that repository. + %w(OWNER COLLABORATOR MEMBER).include? @pr['author_association'] + end + + def approved_by_collaborator? + Octokit.pull_comments(base_repo, id).any? {|c| (%w(OWNER COLLABORATOR MEMBER).include?(c['author_association']) && + c['body'].downcase.include?('ci ok')) } end def equals?(id:, sha:) diff --git a/assets/lib/repository.rb b/assets/lib/repository.rb index fdd470a..1ae03ed 100644 --- a/assets/lib/repository.rb +++ b/assets/lib/repository.rb @@ -6,11 +6,12 @@ require_relative 'filters/path' require_relative 'filters/ci_skip' require_relative 'filters/mergeable' +require_relative 'filters/approval' class Repository attr_reader :name - def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label, Filters::CISkip, Filters::Mergeable]) + def initialize(name:, input: Input.instance, filters: [Filters::All, Filters::Path, Filters::Fork, Filters::Label, Filters::CISkip, Filters::Mergeable, Filters::Approval]) @filters = filters @name = name @input = input From b8ebec38a3bef6bd772858cf494ac43aa58ea857 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Tue, 6 Feb 2018 22:36:11 +0000 Subject: [PATCH 082/106] Add tests for filters. --- spec/commands/check_spec.rb | 15 +++++-- spec/filters/approval_spec.rb | 79 ++++++++++++++++++++++++++++++++++ spec/filters/mergeable_spec.rb | 6 +-- 3 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 spec/filters/approval_spec.rb diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index d225402..c5ab363 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -17,10 +17,17 @@ def stub_json(uri, body) .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) end + def stub_prs(uri, body) + stub_json(uri, body) + body.each do |pr| + stub_json(uri.sub('pulls', 'pulls/' + pr[:number].to_s).sub('&per_page=100', ''), pr) + end + end + context 'when targetting a base branch other than master' do before do stub_json('https://api.github.com/repos/jtarchie/test/statuses/abcdef', []) - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_prs('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) end it 'retrieves pull requests for the specified base branch' do @@ -48,7 +55,7 @@ def stub_json(uri, body) context 'when there is an open pull request' do before do - stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_prs('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) end it 'returns SHA of the pull request' do @@ -79,7 +86,7 @@ def stub_json(uri, body) context 'when there is more than one open pull request' do before do - stub_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [ + stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [ { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } ]) @@ -119,7 +126,9 @@ def stub_cache_json(uri) end stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], 'Link' => '; rel="next"') + stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&sort=updated&state=open', pull_requests[0..49]) stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) + stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&sort=updated&state=open', pull_requests[50..99]) first_prs = check('source' => { 'repo' => 'jtarchie/test' }) expect(first_prs.length).to eq 100 diff --git a/spec/filters/approval_spec.rb b/spec/filters/approval_spec.rb new file mode 100644 index 0000000..68a2006 --- /dev/null +++ b/spec/filters/approval_spec.rb @@ -0,0 +1,79 @@ +require_relative '../../assets/lib/filters/approval' +require_relative '../../assets/lib/pull_request' +require_relative '../../assets/lib/input' +require 'webmock/rspec' + +describe Filters::Approval do + let(:ignore_pr) do + PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'author_association' => 'NONE', + 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + end + + let(:pr) do + PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'author_association' => 'OWNER', + 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + end + + let(:pull_requests) { [ignore_pr, pr] } + + def stub_json(uri, body) + stub_request(:get, uri) + .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) + end + + context 'when all approval requirements are disabled' do + it 'does not filter' do + payload = { 'source' => { 'repo' => 'user/repo' } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + + it 'does not filter when explictly disabled' do + payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => false, 'require_review_approval' => false, 'authorship_restriction' => false } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq pull_requests + end + end + + context 'when owner filtering is enabled' do + it 'only returns PRs that are repo-owners' do + payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => false, 'require_review_approval' => false, 'authorship_restriction' => true } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end + + context 'when approval filtering is enabled' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/pulls/1/reviews}, [{ 'state' => 'CHANGES_REQUESTED' }]) + stub_json(%r{https://api.github.com/repos/user/repo/pulls/2/reviews}, [{ 'state' => 'APPROVED' }]) + end + + it 'only returns PRs that are approved' do + payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => false, 'require_review_approval' => true, 'authorship_restriction' => false } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end + + context 'when manual approval filtering is enabled' do + before do + stub_json(%r{https://api.github.com/repos/user/repo/pulls/1/comments}, [{ 'author_association' => 'OWNER', 'body' => 'other comment' }, + { 'author_association' => 'NONE', 'body' => 'ci ok' }]) + stub_json(%r{https://api.github.com/repos/user/repo/pulls/2/comments}, [{ 'author_association' => 'OWNER', 'body' => 'ci ok' }]) + end + + it 'only returns PRs that are approved' do + payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => true, 'require_review_approval' => false, 'authorship_restriction' => false } } + filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) + + expect(filter.pull_requests).to eq [pr] + end + end + + +end diff --git a/spec/filters/mergeable_spec.rb b/spec/filters/mergeable_spec.rb index 434b47f..c425f70 100644 --- a/spec/filters/mergeable_spec.rb +++ b/spec/filters/mergeable_spec.rb @@ -5,13 +5,11 @@ describe Filters::Mergeable do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'mergeable' => false, - 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'mergeable' => false}) end let(:pr) do - PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'mergeable' => true , - 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'mergeable' => true}) end let(:pull_requests) { [ignore_pr, pr] } From ced0ab820178239624f5826c3bdfde3cfab48428 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Tue, 6 Feb 2018 22:42:51 +0000 Subject: [PATCH 083/106] Update docs for 4-filter model --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a212571..9ecd58d 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,17 @@ resource_types: out pull requests that were created via users that forked from your repo. * `only_mergeable`: *Optional*, default false. If set to `true`, it will filter - out pull requests that are not mergeable. A pull request is mergeable if - - It has no merge conflicts. - - The current user has push permissions to the base repository. - - It has at least one review and has been Approved. + out pull requests that are not mergeable. A pull request is mergeable if it has no merge conflicts. + +* `require_review_approval`: *Optional*, default false. If set to `true`, it will + filter out pull requests that do not have an Approved review. + +* `require_manual_approval`: *Optional*, default false. If set to `true`, it will + filter out pull requests, unless there is a comment on the PR containing the string + `ci ok`, from a collaborator, repo owner, or organization member. + +* `authorship_restriction`: *Optional*, default false. If set to `true`, will only + return PRs created by someone who is a collaborator, repo owner, or organization member. * `label`: *Optional.* If set to a string it will only return pull requests that have been marked with that specific label. It is case insensitive. From 28c1f170870dec5c69d78edf618f5560715346cf Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Tue, 20 Feb 2018 20:25:32 +0000 Subject: [PATCH 084/106] Remove 'manual approval' feature. --- README.md | 4 ---- assets/lib/filters/approval.rb | 3 --- assets/lib/pull_request.rb | 5 ----- spec/filters/approval_spec.rb | 16 ---------------- 4 files changed, 28 deletions(-) diff --git a/README.md b/README.md index 9ecd58d..5786eaa 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,6 @@ resource_types: * `require_review_approval`: *Optional*, default false. If set to `true`, it will filter out pull requests that do not have an Approved review. -* `require_manual_approval`: *Optional*, default false. If set to `true`, it will - filter out pull requests, unless there is a comment on the PR containing the string - `ci ok`, from a collaborator, repo owner, or organization member. - * `authorship_restriction`: *Optional*, default false. If set to `true`, will only return PRs created by someone who is a collaborator, repo owner, or organization member. diff --git a/assets/lib/filters/approval.rb b/assets/lib/filters/approval.rb index c31ac38..be74984 100644 --- a/assets/lib/filters/approval.rb +++ b/assets/lib/filters/approval.rb @@ -9,9 +9,6 @@ def pull_requests if @input.source.require_review_approval @pull_requests.delete_if {|x| !x.review_approved? } end - if @input.source.require_manual_approval - @pull_requests.delete_if {|x| !x.approved_by_collaborator? } - end if @input.source.authorship_restriction @pull_requests.delete_if {|x| !x.author_associated? } end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index fdff18f..5471b33 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -31,11 +31,6 @@ def author_associated? %w(OWNER COLLABORATOR MEMBER).include? @pr['author_association'] end - def approved_by_collaborator? - Octokit.pull_comments(base_repo, id).any? {|c| (%w(OWNER COLLABORATOR MEMBER).include?(c['author_association']) && - c['body'].downcase.include?('ci ok')) } - end - def equals?(id:, sha:) [self.sha, self.id.to_s] == [sha, id.to_s] end diff --git a/spec/filters/approval_spec.rb b/spec/filters/approval_spec.rb index 68a2006..5f435d3 100644 --- a/spec/filters/approval_spec.rb +++ b/spec/filters/approval_spec.rb @@ -60,20 +60,4 @@ def stub_json(uri, body) end end - context 'when manual approval filtering is enabled' do - before do - stub_json(%r{https://api.github.com/repos/user/repo/pulls/1/comments}, [{ 'author_association' => 'OWNER', 'body' => 'other comment' }, - { 'author_association' => 'NONE', 'body' => 'ci ok' }]) - stub_json(%r{https://api.github.com/repos/user/repo/pulls/2/comments}, [{ 'author_association' => 'OWNER', 'body' => 'ci ok' }]) - end - - it 'only returns PRs that are approved' do - payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => true, 'require_review_approval' => false, 'authorship_restriction' => false } } - filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) - - expect(filter.pull_requests).to eq [pr] - end - end - - end From a59f3a630b90ab9168b4f53c349bb99e5570a56c Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Tue, 20 Feb 2018 20:39:36 +0000 Subject: [PATCH 085/106] Rubocop formatting changes --- assets/lib/filters/approval.rb | 4 ++-- assets/lib/filters/mergeable.rb | 4 ++-- assets/lib/pull_request.rb | 4 ++-- spec/commands/check_spec.rb | 6 +++--- spec/filters/approval_spec.rb | 7 +++---- spec/filters/mergeable_spec.rb | 4 ++-- 6 files changed, 14 insertions(+), 15 deletions(-) diff --git a/assets/lib/filters/approval.rb b/assets/lib/filters/approval.rb index be74984..a3d4dfe 100644 --- a/assets/lib/filters/approval.rb +++ b/assets/lib/filters/approval.rb @@ -7,10 +7,10 @@ def initialize(pull_requests:, input: Input.instance) def pull_requests if @input.source.require_review_approval - @pull_requests.delete_if {|x| !x.review_approved? } + @pull_requests.delete_if { |x| !x.review_approved? } end if @input.source.authorship_restriction - @pull_requests.delete_if {|x| !x.author_associated? } + @pull_requests.delete_if { |x| !x.author_associated? } end @pull_requests diff --git a/assets/lib/filters/mergeable.rb b/assets/lib/filters/mergeable.rb index fb9a440..27bb5b5 100644 --- a/assets/lib/filters/mergeable.rb +++ b/assets/lib/filters/mergeable.rb @@ -1,5 +1,5 @@ module Filters - class Mergeable + class Mergeable def initialize(pull_requests:, input: Input.instance) @pull_requests = pull_requests @input = input @@ -7,7 +7,7 @@ def initialize(pull_requests:, input: Input.instance) def pull_requests if @input.source.only_mergeable - @memoized ||= @pull_requests.delete_if {|x| !x.mergeable? } + @memoized ||= @pull_requests.delete_if { |x| !x.mergeable? } else @pull_requests end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index 5471b33..e5f2f35 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -21,14 +21,14 @@ def mergeable? end def review_approved? - Octokit.pull_request_reviews(base_repo, id).any? {|r| r['state'] == 'APPROVED'} + Octokit.pull_request_reviews(base_repo, id).any? { |r| r['state'] == 'APPROVED' } end def author_associated? # Checks whether the author is associated with the repo that the PR is against: # either the owner of that repo, someone invited to collaborate, or a member # of the organization who owns that repository. - %w(OWNER COLLABORATOR MEMBER).include? @pr['author_association'] + %w[OWNER COLLABORATOR MEMBER].include? @pr['author_association'] end def equals?(id:, sha:) diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index c5ab363..983d732 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -87,9 +87,9 @@ def stub_prs(uri, body) context 'when there is more than one open pull request' do before do stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [ - { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, - { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } - ]) + { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, + { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } + ]) end it 'returns all PRs oldest to newest last' do diff --git a/spec/filters/approval_spec.rb b/spec/filters/approval_spec.rb index 5f435d3..24403fd 100644 --- a/spec/filters/approval_spec.rb +++ b/spec/filters/approval_spec.rb @@ -6,12 +6,12 @@ describe Filters::Approval do let(:ignore_pr) do PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'author_association' => 'NONE', - 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + 'base' => { 'repo' => { 'full_name' => 'user/repo', 'permissions' => { 'push' => true } } } }) end let(:pr) do PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'author_association' => 'OWNER', - 'base' => { 'repo' => {'full_name' => 'user/repo', 'permissions' => {'push' => true} } } }) + 'base' => { 'repo' => { 'full_name' => 'user/repo', 'permissions' => { 'push' => true } } } }) end let(:pull_requests) { [ignore_pr, pr] } @@ -36,7 +36,7 @@ def stub_json(uri, body) expect(filter.pull_requests).to eq pull_requests end end - + context 'when owner filtering is enabled' do it 'only returns PRs that are repo-owners' do payload = { 'source' => { 'repo' => 'user/repo', 'require_manual_approval' => false, 'require_review_approval' => false, 'authorship_restriction' => true } } @@ -59,5 +59,4 @@ def stub_json(uri, body) expect(filter.pull_requests).to eq [pr] end end - end diff --git a/spec/filters/mergeable_spec.rb b/spec/filters/mergeable_spec.rb index c425f70..ef99989 100644 --- a/spec/filters/mergeable_spec.rb +++ b/spec/filters/mergeable_spec.rb @@ -5,11 +5,11 @@ describe Filters::Mergeable do let(:ignore_pr) do - PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'mergeable' => false}) + PullRequest.new(pr: { 'number' => 1, 'head' => { 'sha' => 'abc' }, 'mergeable' => false }) end let(:pr) do - PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'mergeable' => true}) + PullRequest.new(pr: { 'number' => 2, 'head' => { 'sha' => 'def' }, 'mergeable' => true }) end let(:pull_requests) { [ignore_pr, pr] } From 8899c8a89213ef1841fff9efa85c65460432ac0d Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 14 Mar 2018 06:51:53 -0600 Subject: [PATCH 086/106] support mergeable and minimize API calls --- assets/lib/filters/all.rb | 2 +- assets/lib/filters/approval.rb | 2 ++ assets/lib/filters/mergeable.rb | 8 +++++++- assets/lib/pull_request.rb | 4 ---- spec/commands/check_spec.rb | 21 ++++++--------------- spec/filters/approval_spec.rb | 2 ++ spec/filters/mergeable_spec.rb | 8 +++++--- 7 files changed, 23 insertions(+), 24 deletions(-) diff --git a/assets/lib/filters/all.rb b/assets/lib/filters/all.rb index 7abd221..91afce3 100644 --- a/assets/lib/filters/all.rb +++ b/assets/lib/filters/all.rb @@ -11,7 +11,7 @@ def initialize(pull_requests: [], input: Input.instance) def pull_requests @pull_requests ||= Octokit.pulls(input.source.repo, pull_options).map do |pr| - PullRequest.new(pr: Octokit.pull_request(input.source.repo, pr['number'], pull_options)) + PullRequest.new(pr: pr) # keep this lazy, specific filters should pull data if they need to end end diff --git a/assets/lib/filters/approval.rb b/assets/lib/filters/approval.rb index a3d4dfe..a1ce168 100644 --- a/assets/lib/filters/approval.rb +++ b/assets/lib/filters/approval.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Filters class Approval def initialize(pull_requests:, input: Input.instance) diff --git a/assets/lib/filters/mergeable.rb b/assets/lib/filters/mergeable.rb index 27bb5b5..b3ceb5d 100644 --- a/assets/lib/filters/mergeable.rb +++ b/assets/lib/filters/mergeable.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Filters class Mergeable def initialize(pull_requests:, input: Input.instance) @@ -7,7 +9,11 @@ def initialize(pull_requests:, input: Input.instance) def pull_requests if @input.source.only_mergeable - @memoized ||= @pull_requests.delete_if { |x| !x.mergeable? } + + @memoized ||= @pull_requests.delete_if do |pr| + response = Octokit.pull_request(@input.source.repo, pr.id) + !response['mergeable'] + end else @pull_requests end diff --git a/assets/lib/pull_request.rb b/assets/lib/pull_request.rb index e5f2f35..6c329ea 100644 --- a/assets/lib/pull_request.rb +++ b/assets/lib/pull_request.rb @@ -16,10 +16,6 @@ def from_fork? base_repo != head_repo end - def mergeable? - @pr['mergeable'] - end - def review_approved? Octokit.pull_request_reviews(base_repo, id).any? { |r| r['state'] == 'APPROVED' } end diff --git a/spec/commands/check_spec.rb b/spec/commands/check_spec.rb index 983d732..d225402 100644 --- a/spec/commands/check_spec.rb +++ b/spec/commands/check_spec.rb @@ -17,17 +17,10 @@ def stub_json(uri, body) .to_return(headers: { 'Content-Type' => 'application/json' }, body: body.to_json) end - def stub_prs(uri, body) - stub_json(uri, body) - body.each do |pr| - stub_json(uri.sub('pulls', 'pulls/' + pr[:number].to_s).sub('&per_page=100', ''), pr) - end - end - context 'when targetting a base branch other than master' do before do stub_json('https://api.github.com/repos/jtarchie/test/statuses/abcdef', []) - stub_prs('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?base=my-base-branch&direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) end it 'retrieves pull requests for the specified base branch' do @@ -55,7 +48,7 @@ def stub_prs(uri, body) context 'when there is an open pull request' do before do - stub_prs('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) + stub_json('https://api.github.com:443/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [{ number: 1, head: { sha: 'abcdef' } }]) end it 'returns SHA of the pull request' do @@ -86,10 +79,10 @@ def stub_prs(uri, body) context 'when there is more than one open pull request' do before do - stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [ - { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, - { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } - ]) + stub_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', [ + { number: 1, head: { sha: 'abcdef', repo: { full_name: 'jtarchie/test' } }, base: { repo: { full_name: 'jtarchie/test' } } }, + { number: 2, head: { sha: 'zyxwvu', repo: { full_name: 'someotherowner/repo' } }, base: { repo: { full_name: 'jtarchie/test' } } } + ]) end it 'returns all PRs oldest to newest last' do @@ -126,9 +119,7 @@ def stub_cache_json(uri) end stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open', pull_requests[0..49], 'Link' => '; rel="next"') - stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&sort=updated&state=open', pull_requests[0..49]) stub_body_json('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&per_page=100&sort=updated&state=open&page=2', pull_requests[50..99]) - stub_prs('https://api.github.com/repos/jtarchie/test/pulls?direction=asc&sort=updated&state=open', pull_requests[50..99]) first_prs = check('source' => { 'repo' => 'jtarchie/test' }) expect(first_prs.length).to eq 100 diff --git a/spec/filters/approval_spec.rb b/spec/filters/approval_spec.rb index 24403fd..ff9caae 100644 --- a/spec/filters/approval_spec.rb +++ b/spec/filters/approval_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/filters/approval' require_relative '../../assets/lib/pull_request' require_relative '../../assets/lib/input' diff --git a/spec/filters/mergeable_spec.rb b/spec/filters/mergeable_spec.rb index ef99989..ba8857f 100644 --- a/spec/filters/mergeable_spec.rb +++ b/spec/filters/mergeable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../assets/lib/filters/mergeable' require_relative '../../assets/lib/pull_request' require_relative '../../assets/lib/input' @@ -37,11 +39,11 @@ def stub_json(uri, body) context 'when the mergeable filtering is enabled' do before do - stub_json(%r{https://api.github.com/repos/user/repo/pulls/1/reviews}, [{ 'state' => 'CHANGES_REQUESTED' }]) - stub_json(%r{https://api.github.com/repos/user/repo/pulls/2/reviews}, [{ 'state' => 'APPROVED' }]) + stub_json(%r{https://api.github.com/repos/user/repo/pulls/1}, 'mergeable' => false) + stub_json(%r{https://api.github.com/repos/user/repo/pulls/2}, 'mergeable' => true) end - it 'only returns PRs with that label' do + it 'only returns PRs with that are mergeable' do payload = { 'source' => { 'repo' => 'user/repo', 'only_mergeable' => true } } filter = described_class.new(pull_requests: pull_requests, input: Input.instance(payload: payload)) From 4741483cf71722a223c82346a5eef59b84cebbf5 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 14 Mar 2018 06:53:39 -0600 Subject: [PATCH 087/106] bump --- Gemfile.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 561bab0..8aefa9d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -25,7 +25,7 @@ GEM eventmachine (>= 1.0.0.beta.4) em-synchrony (1.0.6) eventmachine (>= 1.0.0.beta.1) - eventmachine (1.2.0.1) + eventmachine (1.0.9.1) eventmachine_httpserver (0.2.1) faraday (0.14.0) multipart-post (>= 1.2, < 3) @@ -43,18 +43,18 @@ GEM octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) parallel (1.12.1) - parser (2.5.0.2) + parser (2.5.0.4) ast (~> 2.4.0) powerpack (0.1.1) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) public_suffix (3.0.2) - puffing-billy (0.12.0) - addressable (~> 2.4, >= 2.4.0) + puffing-billy (1.0.0) + addressable (~> 2.5) em-http-request (~> 1.1, >= 1.1.0) em-synchrony - eventmachine (= 1.2.0.1) + eventmachine (~> 1.0.4) eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json @@ -72,15 +72,15 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.1) - rubocop (0.52.1) + rubocop (0.53.0) parallel (~> 1.10) - parser (>= 2.4.0.2, < 3.0) + parser (>= 2.5) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.23.0) - rubocop (>= 0.52.1) + rubocop-rspec (1.24.0) + rubocop (>= 0.53.0) ruby-progressbar (1.9.0) safe_yaml (1.0.4) sawyer (0.8.1) From 4b89fbcd645ce28c40df429e193f02fe20fbe1ad Mon Sep 17 00:00:00 2001 From: Alex Conrad Date: Wed, 28 Feb 2018 14:25:15 -0800 Subject: [PATCH 088/106] Document .git/base_sha in README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5786eaa..0e5e840 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,8 @@ git config --get pullrequest.userlogin # returns the github user login for the * `.git/base_branch`: the base branch of the pull request + * `.git/base_sha`: the commit of the base branch of the pull request + * `.git/userlogin`: the user login of the pull request author * `.git/head_sha`: the latest commit hash of the branch associated with the pull request From 54e1db3531d0e0dbaa03c468ae8b41818daa9669 Mon Sep 17 00:00:00 2001 From: Alexandre Conrad Date: Wed, 28 Feb 2018 13:25:26 -0800 Subject: [PATCH 089/106] Write the base commit to .git/base_sha This is useful for when we need to know the SHA-1 of the base branch when the build ran which isn't necessarily the HEAD of `master` (or whatever the base branch is). --- assets/lib/commands/in.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 0d4a65e..330756c 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -32,6 +32,7 @@ def output File.write('body', pr['body']) File.write('branch', pr['head']['ref']) File.write('base_branch', pr['base']['ref']) + File.write('base_sha', pr['base']['sha']) File.write('userlogin', pr['user']['login']) File.write('head_sha', pr['head']['sha']) end From 0a91478e1dd491cd5a0fd80c5cc6ba5e93651367 Mon Sep 17 00:00:00 2001 From: Alex Conrad Date: Thu, 8 Mar 2018 11:47:22 -0800 Subject: [PATCH 090/106] Add test for base_sha --- spec/commands/in_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 6fa6a0e..1027057 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -63,6 +63,7 @@ def dest_dir }, base: { ref: 'master', + sha: 'basehash', user: { login: 'jtarchie' } @@ -136,6 +137,11 @@ def dest_dir expect(value).to eq 'master' end + it 'creates a file that icludes the base_sha in the .git folder' do + value = File.read(File.join(dest_dir, '.git', 'base_sha')).strip + expect(value).to eq 'basehash' + end + it 'creates a file that includes the hash of the branch in the .git folder' do value = File.read(File.join(dest_dir, '.git', 'head_sha')).strip expect(value).to eq 'hash' From 92dc20d4ba076fc680edc4cbe3e9410b3c56c2f0 Mon Sep 17 00:00:00 2001 From: Alex Conrad Date: Thu, 8 Mar 2018 12:13:09 -0800 Subject: [PATCH 091/106] add pullrequest.basesha --- assets/lib/commands/in.rb | 1 + spec/commands/in_spec.rb | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/assets/lib/commands/in.rb b/assets/lib/commands/in.rb index 330756c..3308c0d 100755 --- a/assets/lib/commands/in.rb +++ b/assets/lib/commands/in.rb @@ -47,6 +47,7 @@ def output git config --add pullrequest.body #{pr['body'].to_s.shellescape} 1>&2 git config --add pullrequest.branch #{pr['head']['ref'].to_s.shellescape} 1>&2 git config --add pullrequest.basebranch #{pr['base']['ref'].to_s.shellescape} 1>&2 + git config --add pullrequest.basesha #{pr['base']['sha'].to_s.shellescape} 1>&2 git config --add pullrequest.userlogin #{pr['user']['login'].to_s.shellescape} 1>&2 BASH diff --git a/spec/commands/in_spec.rb b/spec/commands/in_spec.rb index 1027057..b40b084 100644 --- a/spec/commands/in_spec.rb +++ b/spec/commands/in_spec.rb @@ -112,6 +112,11 @@ def dest_dir expect(value).to eq 'master' end + it 'sets config variable to basesha name' do + value = git('config pullrequest.basesha', dest_dir) + expect(value).to eq 'basehash' + end + it 'sets config variable to user_login name' do value = git('config pullrequest.userlogin', dest_dir) expect(value).to eq 'jtarchie-contributor' From 2dbbb2538671348a7283fc4f794e71ebce69bf0f Mon Sep 17 00:00:00 2001 From: Alex Conrad Date: Thu, 8 Mar 2018 12:15:31 -0800 Subject: [PATCH 092/106] update README for git config --get pullrequest.basesha --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0e5e840..5973cfa 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ git config --get pullrequest.branch # returns the branch name used for the p git config --get pullrequest.id # returns the ID number of the PR git config --get pullrequest.body # returns the PR body git config --get pullrequest.basebranch # returns the base branch used for the pull request +git config --get pullrequest.basesha # returns the commit of the base branch used for the pull request git config --get pullrequest.userlogin # returns the github user login for the pull request author ``` From 15f9f7640c5d98812a31d31766172cef7235cffd Mon Sep 17 00:00:00 2001 From: Alex Conrad Date: Thu, 8 Mar 2018 12:15:49 -0800 Subject: [PATCH 093/106] Clean-up whitespaces in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5973cfa..2b68ee6 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,12 @@ marked with that specific label. It is case insensitive. * `ignore_paths`: *Optional.* The inverse of `paths`; changes to the specified files are ignored. - + * `ci_skip`: *Optional.* Filters out PRs that have `[ci skip]` message. Default is `false`. * `skip_ssl_verification`: *Optional.* Skips git ssl verification by exporting - `GIT_SSL_NO_VERIFY=true` and applying it to the Github API client. + `GIT_SSL_NO_VERIFY=true` and applying it to the Github API client. * `git_config`: *Optional*. If specified as (list of pairs `name` and `value`) it will configure git global options, setting each name with each value. From 4242846835d04fbbed556fb8d237f2112181c97b Mon Sep 17 00:00:00 2001 From: JT Archie Date: Wed, 14 Mar 2018 07:16:58 -0600 Subject: [PATCH 094/106] Update CHANGELOG.md --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c9f239..7db79a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# v35 @ 3/14/2018 + +* filter PRs by the mergeable status (thanks @ndmckinley) +* filter PRs based on the author's association to the repo (thanks @ndmckinley) +* Get the SHA of the base branch (thanks @aconrad) + +# v34 + +* fix shell escaping in pull request meta information so it doesn't break with special characters + +# v33 + +* access the Pull Request message body (thanks @ndmckinley) + # v32 @ 1/27/2018 * enable filtering out PRs that have `ci_skip` messages (thanks @aditya87) From e798739067b798f4fbc6d9cad1863914893fbb4d Mon Sep 17 00:00:00 2001 From: Wes McNamee Date: Tue, 13 Mar 2018 18:17:58 -0700 Subject: [PATCH 095/106] Improve build layer caching --- Dockerfile | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index e32b57d..ed63929 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,29 @@ +# Stage: Base FROM alpine as resource -RUN apk add --update ca-certificates -RUN apk add --update curl -RUN apk add --update git -RUN apk add --update jq -RUN apk add --update openssh-client -RUN apk add --update perl -RUN apk add --update ruby -RUN apk add --update ruby-json -RUN gem install octokit activesupport httpclient faraday-http-cache --no-rdoc --no-ri +RUN set -ex; \ + apk add --update \ + ca-certificates \ + curl \ + git \ + jq \ + openssh-client \ + perl \ + ruby \ + ruby-json \ + ruby-bundler \ + ; \ + rm -rf /var/cache/apk/*; +ADD Gemfile Gemfile.lock /opt/resource/ +RUN cd /opt/resource && bundle install --without test development ADD assets/ /opt/resource/ RUN chmod +x /opt/resource/* ADD scripts/install_git_lfs.sh install_git_lfs.sh RUN ./install_git_lfs.sh +# Stage: Testing FROM resource as tests -COPY . /resource RUN apk add --update \ ruby-bundler \ @@ -24,6 +31,14 @@ RUN apk add --update \ ruby-dev \ openssl-dev \ alpine-sdk -RUN cd /resource && bundle install && bundle exec rspec +COPY Gemfile Gemfile.lock /resource/ + +RUN cd /resource && bundle install + +COPY . /resource + +RUN cd /resource && rspec + +# Stage: Final FROM resource From ec53c86044184048b9c2e706c3fa985f14627d05 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Fri, 9 Mar 2018 23:37:52 +0000 Subject: [PATCH 096/106] Add a label to the PR. --- assets/lib/commands/out.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index 4a21cf6..e498569 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -66,6 +66,10 @@ def output metadata << { 'name' => 'comment', 'value' => comment } end + if params.label + Octokit.add_labels_to_an_issue(input.source.repo, id, [params.label]) + end + if params.merge.method commit_msg = if params.merge.commit_msg commit_path = File.join(destination, params.merge.commit_msg) From a0d3e83fd88fa3bd40c6ec2075b72747196a2b38 Mon Sep 17 00:00:00 2001 From: Cody Stamps Date: Fri, 6 Apr 2018 08:09:25 -0400 Subject: [PATCH 097/106] Update parser gem The version in the gemfile.lock was yanked, so to get it to build on local machines and support future development, bumped the version. https://rubygems.org/gems/parser/versions/2.5.0.4 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8aefa9d..ceadc86 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -43,7 +43,7 @@ GEM octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) parallel (1.12.1) - parser (2.5.0.4) + parser (2.5.0.5) ast (~> 2.4.0) powerpack (0.1.1) pry (0.11.3) From 0d43927c4ab493cc0e1fd86fd77e706f94980d03 Mon Sep 17 00:00:00 2001 From: Cody Stamps Date: Tue, 10 Apr 2018 07:29:37 -0400 Subject: [PATCH 098/106] update deps --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ceadc86..b46d128 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,9 +1,9 @@ GEM remote: https://rubygems.org/ specs: - activesupport (5.1.5) + activesupport (5.2.0) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (~> 0.7) + i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.5.2) @@ -34,7 +34,7 @@ GEM hashdiff (0.3.7) http_parser.rb (0.6.0) httpclient (2.8.3) - i18n (0.9.5) + i18n (1.0.0) concurrent-ruby (~> 1.0) method_source (0.9.0) minitest (5.11.3) @@ -72,14 +72,14 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) rspec-support (3.7.1) - rubocop (0.53.0) + rubocop (0.54.0) parallel (~> 1.10) parser (>= 2.5) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-rspec (1.24.0) + rubocop-rspec (1.25.0) rubocop (>= 0.53.0) ruby-progressbar (1.9.0) safe_yaml (1.0.4) From 520d814fd7b9d3ac101a8f005ae98d41443c8ebb Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Wed, 11 Apr 2018 22:57:08 +0000 Subject: [PATCH 099/106] Add tests and metadata output for adding labels. --- assets/lib/commands/out.rb | 1 + spec/commands/out_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index e498569..ccdef75 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -68,6 +68,7 @@ def output if params.label Octokit.add_labels_to_an_issue(input.source.repo, id, [params.label]) + metadata << { 'name' => 'label', 'value' => params.label } end if params.merge.method diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index 9114a4f..f490200 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -195,6 +195,26 @@ def stub_json(method, uri, body) end end + context 'when setting a status with a label' do + before do + stub_request(:post, "https://api.github.com/repos/jtarchie/test/issues/1/labels").with( + body: "[\"test_label\"]").to_return( + status: 200, body: "", headers: {}) + end + it 'posts a comment to the PR\'s SHA' do + stub_status_post + stub_json(:post, 'https://api.github.com:443/repos/jtarchie/test/issues/1/comments', id: 1) + + output, = put('params' => { 'status' => 'success', 'path' => 'resource', 'label' => 'test_label' }, 'source' => { 'repo' => 'jtarchie/test' }) + expect(output).to eq('version' => { 'ref' => @sha, 'pr' => '1' }, + 'metadata' => [ + { 'name' => 'status', 'value' => 'success' }, + { 'name' => 'url', 'value' => 'http://example.com' }, + { 'name' => 'label', 'value' => 'test_label' }, + ]) + end + end + context 'when the pull request is being release' do context 'and the build passed' do it 'sets into success mode' do From 7505e9fa81a9872aff41e661278d4758d4a1bf6e Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Wed, 11 Apr 2018 23:21:50 +0000 Subject: [PATCH 100/106] Add docs for out.params.label. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2b68ee6..f665a12 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,8 @@ Set the status message for `concourse-ci` context on specified pull request. * `merge.commit_msg`: *Optional.* Used with `merge` to set the commit message for the merge. Specify a file path to the merge commit message. +* `label`: *Optional.* A label to add to the pull request. + ## Example pipeline Please see this repo's [pipeline](https://github.com/jtarchie/pullrequest-resource/blob/master/.concourse.yml) for a perfect example. From f70c0f4dfb0c67f4b3f6662ef02ffb989c75b701 Mon Sep 17 00:00:00 2001 From: Cody Stamps Date: Fri, 20 Apr 2018 12:27:02 -0400 Subject: [PATCH 101/106] ignore vscode files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 90fa6fe..e8f7344 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ example/ bin .secrets.yml test_pipeline.yml +.vscode/ \ No newline at end of file From 710373f9d8ad2f55d5141f85930edefc490840f2 Mon Sep 17 00:00:00 2001 From: gaelL Date: Mon, 23 Apr 2018 10:39:26 +0200 Subject: [PATCH 102/106] Add support of concourse build environment in the base_url This commit add the support of build environment from concourse http://concourse.ci/implementing-resources.html#resource-metadata Using the same function as context. This will allow to generage your own base_url based on concourse build environment : ``` base_url: foo.com/$BUILD_JOB_NAME ``` --- README.md | 3 +++ assets/lib/commands/out.rb | 2 +- spec/commands/out_spec.rb | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f665a12..61c65ec 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ resource_types: linking to builds. On newer versions of Concourse ( >= v0.71.0) , the resource will automatically sets the URL. + This supports the [build environment](http://concourse.ci/implementing-resources.html#resource-metadata) + variables provided by concourse. For example, `context: $BUILD_JOB_NAME` will set the context to the job name. + * `private_key`: *Optional.* Private key to use when pulling/pushing. Example: ``` diff --git a/assets/lib/commands/out.rb b/assets/lib/commands/out.rb index ccdef75..547a581 100755 --- a/assets/lib/commands/out.rb +++ b/assets/lib/commands/out.rb @@ -52,7 +52,7 @@ def output contextes.each do |context| Status.new( state: params.status, - atc_url: atc_url, + atc_url: whitelist(context: atc_url), sha: sha, repo: repo, context: whitelist(context: context) diff --git a/spec/commands/out_spec.rb b/spec/commands/out_spec.rb index f490200..a6524f0 100644 --- a/spec/commands/out_spec.rb +++ b/spec/commands/out_spec.rb @@ -39,6 +39,7 @@ def stub_status_post stub_json(:get, "https://api.github.com:443/repos/jtarchie/test/statuses/#{@sha}", []) ENV['BUILD_ID'] = '1234' + ENV['ATC_EXTERNAL_URL'] = 'default-test-atc-url.com' end def stub_json(method, uri, body) @@ -236,6 +237,16 @@ def stub_json(method, uri, body) end end + context 'with base_url defined on source containing environment variable' do + it 'sets the target_url for status' do + ENV['BUILD_TEAM_NAME'] = 'build-env-var' + stub_status_post.with(body: hash_including('target_url' => 'http://example.com/build-env-var/builds/1234')) + + put('params' => { 'status' => 'success', 'path' => 'resource' }, 'source' => { 'repo' => 'jtarchie/test', 'base_url' => 'http://example.com/$BUILD_TEAM_NAME' }) + ENV['BUILD_TEAM_NAME'] = nil + end + end + context 'with no base_url defined, but with ATC_EXTERNAL_URL defined' do it 'sets the target_url for status' do ENV['ATC_EXTERNAL_URL'] = 'http://atc-endpoint.com' From 7b324bee4f20249b3f998edfdea5fc645207c7a6 Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 7 Jun 2018 16:35:38 -0600 Subject: [PATCH 103/106] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 14 ++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2a58f93 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,14 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Provide a pipeline YAML that reproduces or demonstrates the issue. + +**Expected behavior** +A clear and concise description of what you expected to happen. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..1b2c02c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +** Is your feature request to extend the resource with a Github API call? ** +Please clarify why this is beneficial and necessary for the resource. Most Github API calls can be performed with [`hub`](https://github.com/github/hub) or `curl` command from a `task`. The resource should not be a complete wrapper of the Github API. + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. From 348d93da16a443824c60ebf5e9040ccf73633ddc Mon Sep 17 00:00:00 2001 From: JT Archie Date: Thu, 7 Jun 2018 16:38:23 -0600 Subject: [PATCH 104/106] Create pull_request_template.md --- .github/pull_request_template.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..8cbe5fe --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ +# How to contribute to the pullrequest resource + +## **Did you find a bug?** + +* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/jtarchie/pullrequest-resource/issues). + +* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/jtarchie/pullrequest-resource/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. + +## **Did you write a patch that fixes a bug?** + +* Open a new GitHub pull request with the patch. + +* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. + +* Write a test for your feature. Run all the tests! This will give you and us a higher confidence that nothing broke. + +## **Do you intend to add a new feature or change an existing one?** + +* Please open a [open a new issue](https://github.com/jtarchie/pullrequest-resource/issues/new) describing the feature you'd like to add. + +## **Requirements for a Pull Request + +A pull request won't be reviewed without the following: + +* Updated docs +* Test coverage of the added feature +* Clear explaination of the intention of the pull request. + +Thanks! From 22a4a267fdeaae481261c1b68b66921a425caad2 Mon Sep 17 00:00:00 2001 From: Bruno Bandeira de Azevedo Date: Mon, 25 Jun 2018 17:12:58 +0200 Subject: [PATCH 105/106] Fix on Readme for Concourse links --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 61c65ec..92460fe 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ resource only support *GITHUB*. ## Deploying to Concourse -You can use the docker image by defining the [resource type](http://concourse.ci/configuring-resource-types.html) in your pipeline YAML. +You can use the docker image by defining the [resource type](https://concourse-ci.org/resource-types.html) in your pipeline YAML. For example: @@ -41,7 +41,7 @@ resource_types: linking to builds. On newer versions of Concourse ( >= v0.71.0) , the resource will automatically sets the URL. - This supports the [build environment](http://concourse.ci/implementing-resources.html#resource-metadata) + This supports the [build environment](https://concourse-ci.org/implementing-resources.html#resource-metadata) variables provided by concourse. For example, `context: $BUILD_JOB_NAME` will set the context to the job name. * `private_key`: *Optional.* Private key to use when pulling/pushing. @@ -170,13 +170,13 @@ Set the status message for `concourse-ci` context on specified pull request. * `path`: *Required.* The path of the repository to reference the pull request. * `status`: *Required.* The status of success, failure, error, or pending. - * [`on_success`](https://concourse.ci/on-success-step.html) and [`on_failure`](https://concourse.ci/on-failure-step.html) triggers may be useful for you when you wanted to reflect build result to the PR (see the example below). + * [`on_success`](https://concourse-ci.org/on-success-step-hook.html#on_success) and [`on_failure`](https://concourse-ci.org/on-failure-step-hook.html#on_failure) triggers may be useful for you when you wanted to reflect build result to the PR (see the example below). * `context`: *Optional.* The context on the specified pull request (defaults to `status`). Any context will be prepended with `concourse-ci`, so a context of `unit-tests` will appear as `concourse-ci/unit-tests` on Github. - This supports the [build environment](http://concourse.ci/implementing-resources.html#resource-metadata) + This supports the [build environment](https://concourse-ci.org/implementing-resources.html#resource-metadata) variables provided by concourse. For example, `context: $BUILD_JOB_NAME` will set the context to the job name. * `comment`: *Optional.* The file path of the comment message. Comment owner is same with the owner of `access_token`. From aea5861a46480896ca73049a22b4a279c8e13be1 Mon Sep 17 00:00:00 2001 From: Cody Stamps Date: Fri, 19 Oct 2018 10:00:38 -0400 Subject: [PATCH 106/106] add a deprecation notice to the readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 92460fe..f45e30d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ +# DEPRECATED +We would like for you to start using the new [github-pr-resource](https://github.com/telia-oss/github-pr-resource) that is based on Github's GraphQL resources. Using GraphQL fixes a lot of issues this repo has. + +For history or context regarding this change, please see this [issue](https://github.com/telia-oss/github-pr-resource/issues/34). + # Github Pull Request Resource Tracks Github pull requests made to a particular Github repo. In the spirit of [Travis