Skip to content

Commit 8d0b47f

Browse files
committed
check resource
0 parents  commit 8d0b47f

File tree

12 files changed

+396
-0
lines changed

12 files changed

+396
-0
lines changed

.rspec

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
--color
2+
--require spec_helper

Dockerfile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM ruby
2+
3+
ADD assets/ /opt/resource/
4+
RUN chmod +x /opt/resource/*
5+
6+
ADD / /opt/resource-tests/
7+
RUN cd /opt/resource-tests/ && \
8+
bundle && \
9+
rspec

Gemfile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'octokit'
4+
5+
gem 'development' do
6+
gem 'rubocop', require: false
7+
end
8+
9+
group :test do
10+
gem 'rspec'
11+
gem 'puffing-billy'
12+
end

Gemfile.lock

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
addressable (2.3.8)
5+
cookiejar (0.3.2)
6+
development (1.1.3)
7+
diff-lcs (1.2.5)
8+
em-http-request (1.1.2)
9+
addressable (>= 2.3.4)
10+
cookiejar
11+
em-socksify (>= 0.3)
12+
eventmachine (>= 1.0.3)
13+
http_parser.rb (>= 0.6.0)
14+
em-socksify (0.3.1)
15+
eventmachine (>= 1.0.0.beta.4)
16+
em-synchrony (1.0.4)
17+
eventmachine (>= 1.0.0.beta.1)
18+
eventmachine (1.0.8)
19+
eventmachine_httpserver (0.2.1)
20+
faraday (0.9.1)
21+
multipart-post (>= 1.2, < 3)
22+
http_parser.rb (0.6.0)
23+
multi_json (1.11.2)
24+
multipart-post (2.0.0)
25+
octokit (4.1.0)
26+
sawyer (~> 0.6.0, >= 0.5.3)
27+
puffing-billy (0.6.1)
28+
addressable
29+
em-http-request (~> 1.1.0)
30+
em-synchrony
31+
eventmachine (~> 1.0.4)
32+
eventmachine_httpserver
33+
http_parser.rb (~> 0.6.0)
34+
multi_json
35+
rspec (3.3.0)
36+
rspec-core (~> 3.3.0)
37+
rspec-expectations (~> 3.3.0)
38+
rspec-mocks (~> 3.3.0)
39+
rspec-core (3.3.2)
40+
rspec-support (~> 3.3.0)
41+
rspec-expectations (3.3.1)
42+
diff-lcs (>= 1.2.0, < 2.0)
43+
rspec-support (~> 3.3.0)
44+
rspec-mocks (3.3.2)
45+
diff-lcs (>= 1.2.0, < 2.0)
46+
rspec-support (~> 3.3.0)
47+
rspec-support (3.3.0)
48+
sawyer (0.6.0)
49+
addressable (~> 2.3.5)
50+
faraday (~> 0.8, < 0.10)
51+
52+
PLATFORMS
53+
ruby
54+
55+
DEPENDENCIES
56+
development
57+
octokit
58+
puffing-billy
59+
rspec
60+
61+
BUNDLED WITH
62+
1.10.6

Rakefile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
task :build do
2+
system('docker build -t pr-test .')
3+
end
4+
5+
task default: :build

assets/check

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'json'
4+
require 'octokit'
5+
6+
def input
7+
@input ||= JSON.parse(ARGF.read).tap do |input|
8+
input['version'] ||= {}
9+
end
10+
end
11+
12+
def json!(payload)
13+
puts JSON.generate(payload)
14+
exit
15+
end
16+
17+
def status(pr)
18+
statuses = Octokit.statuses(input['source']['repo'], pr['head']['sha'])
19+
statuses.find { |status| status['context'] == 'concourseci' } || { 'state' => 'pending' }
20+
end
21+
22+
def same_version?(pr)
23+
[pr['head']['sha'], pr['id']] == [input['version']['ref'], input['version']['pr']]
24+
end
25+
26+
def pending?(pr)
27+
status(pr)['state'] == 'pending'
28+
end
29+
30+
Octokit.connection_options[:ssl] = { verify: false } if ENV['http_proxy']
31+
Octokit.auto_paginate = true
32+
33+
prs = Octokit.pulls(input['source']['repo'], state: 'open', sort: 'updated', direction: 'desc')
34+
json!([]) if prs.empty?
35+
36+
current_pr = prs.find { |pr| same_version?(pr) }
37+
json!([]) if current_pr && pending?(current_pr)
38+
39+
most_recent = prs.first
40+
if pending?(most_recent)
41+
json!([{ ref: most_recent['head']['sha'], pr: most_recent['id'] }])
42+
else
43+
json!([])
44+
end

assets/in

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'json'
4+
require 'octokit'
5+
6+
destination = ARGV.shift
7+
8+
def input
9+
@input ||= JSON.parse(ARGF.read).tap do |input|
10+
input['version'] ||= {}
11+
input['params'] ||= {}
12+
end
13+
end
14+
15+
def uri
16+
input['source']['uri'] || "https://github.com/#{input['source']['repo']}"
17+
end
18+
19+
def ref
20+
input['version']['ref']
21+
end
22+
23+
Octokit.connection_options[:ssl] = { verify: false } if ENV['http_proxy']
24+
pr = Octokit.pull_request(input['source']['repo'], input['version']['pr'])
25+
26+
system("git clone --depth 1 #{uri} #{destination} 1>&2")
27+
Dir.chdir(destination) do
28+
system("git fetch -q origin #{ref}")
29+
system("git checkout -q #{ref}")
30+
system("git config --add pullrequest.url #{pr['url']}")
31+
end
32+
33+
puts JSON.generate(version: { ref: ref, pr: input['version']['pr'] },
34+
metadata: { url: pr['url'] })

assets/out

Whitespace-only changes.

spec/integration/check_spec.rb

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
require 'spec_helper'
2+
require 'json'
3+
require 'billy'
4+
5+
describe 'check' do
6+
let(:proxy) { Billy::Proxy.new }
7+
8+
before { proxy.start }
9+
after { proxy.reset }
10+
11+
def check(payload = {})
12+
path = ['./assets/check', '/opt/resource/check'].find { |p| File.exist? p }
13+
payload[:source] = { repo: 'jtarchie/test' }
14+
15+
output = `echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path}`
16+
JSON.parse(output)
17+
end
18+
19+
context 'when there are no pull requests' do
20+
before do
21+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls')
22+
.and_return(json: [])
23+
end
24+
25+
it 'returns no versions' do
26+
expect(check).to eq []
27+
end
28+
29+
context 'when there is a last known version' do
30+
it 'returns no versions' do
31+
payload = { version: { ref: '1' } }
32+
33+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls/1')
34+
.and_return(json: {})
35+
36+
expect(check(payload)).to eq []
37+
end
38+
end
39+
end
40+
41+
context 'when there is an open pull request' do
42+
before do
43+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls')
44+
.and_return(json: [{ id: '1', head: { sha: 'abcdef' } }])
45+
end
46+
47+
context 'that has no status' do
48+
before do
49+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/abcdef')
50+
.and_return(json: [])
51+
end
52+
53+
it 'returns SHA of the pull request' do
54+
expect(check).to eq [{ 'ref' => 'abcdef', 'pr' => '1' }]
55+
end
56+
57+
context 'and the version is the same as the pull request' do
58+
it 'returns nothing' do
59+
payload = { version: { ref: 'abcdef', pr: '1' } }
60+
61+
expect(check(payload)).to eq []
62+
end
63+
end
64+
end
65+
66+
context 'that has a pending status' do
67+
before do
68+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/abcdef')
69+
.and_return(json: [{ state: 'pending', context: 'concourseci' }])
70+
end
71+
72+
it 'returns SHA of the pull request' do
73+
expect(check).to eq [{ 'ref' => 'abcdef', 'pr' => '1' }]
74+
end
75+
76+
context 'and the version is the same as the pull request' do
77+
it 'returns nothing' do
78+
payload = { version: { ref: 'abcdef', pr: '1' } }
79+
80+
expect(check(payload)).to eq []
81+
end
82+
end
83+
end
84+
85+
context 'that has another status' do
86+
it 'does not return it' do
87+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/abcdef')
88+
.and_return(json: [{ state: 'success', context: 'concourseci' }])
89+
90+
expect(check).to eq []
91+
end
92+
end
93+
end
94+
95+
context 'when there is more than one open pull request' do
96+
before do
97+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls')
98+
.and_return(json: [
99+
{ id: '2', head: { sha: 'zyxwvu' } },
100+
{ id: '1', head: { sha: 'abcdef' } }
101+
])
102+
end
103+
104+
context 'and the version is the same as the older pull request' do
105+
it 'returns nothing when its still pending' do
106+
payload = { version: { ref: 'abcdef', pr: '1' } }
107+
108+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/abcdef')
109+
.and_return(json: [{ state: 'pending', context: 'concourseci' }])
110+
111+
expect(check(payload)).to eq []
112+
end
113+
114+
it 'returns the latest pull request when the current version is not pending' do
115+
payload = { version: { ref: 'abcdef', pr: '1' } }
116+
117+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/abcdef')
118+
.and_return(json: [{ state: 'success', context: 'concourseci' }])
119+
120+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/statuses/zyxwvu')
121+
.and_return(json: [{ state: 'pending', context: 'concourseci' }])
122+
123+
expect(check(payload)).to eq [{ 'ref' => 'zyxwvu', 'pr' => '2' }]
124+
end
125+
end
126+
end
127+
end

spec/integration/in_spec.rb

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
require 'spec_helper'
2+
require 'json'
3+
require 'tmpdir'
4+
require 'billy'
5+
6+
describe 'get' do
7+
let(:proxy) { Billy::Proxy.new }
8+
let(:dest_dir) { Dir.mktmpdir }
9+
let(:git_dir) { Dir.mktmpdir }
10+
let(:git_uri) { "file://#{git_dir}" }
11+
12+
before { proxy.start }
13+
after { proxy.reset }
14+
15+
def get(payload = {})
16+
path = ['./assets/in', '/opt/resource/in'].find { |p| File.exist? p }
17+
payload[:source][:repo] = 'jtarchie/test'
18+
19+
output = `echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path} #{dest_dir}`
20+
JSON.parse(output)
21+
end
22+
23+
def git(cmd, dir = git_dir)
24+
Dir.chdir(dir) { `git #{cmd}`.chomp }
25+
end
26+
27+
before do
28+
proxy.stub('https://api.github.com:443/repos/jtarchie/test/pulls/1')
29+
.and_return(json: { url: 'http://example.com' })
30+
31+
git('init -q')
32+
git("-c user.name='test' -c user.email='[email protected]' commit -q --allow-empty -m 'init'")
33+
end
34+
35+
it 'checks out the pull request to dest_dir' do
36+
ref = git('log --format=format:%H HEAD')
37+
get(version: { ref: ref, pr: '1' }, source: { uri: git_uri })
38+
expect(ref).to eq git('log --format=format:%H HEAD', dest_dir)
39+
end
40+
41+
it 'returns the correct JSON metadata' do
42+
ref = git('log --format=format:%H HEAD')
43+
output = get(version: { ref: ref, pr: '1' }, source: { uri: git_uri })
44+
expect(output).to eq('version' => { 'ref' => ref, 'pr' => '1' },
45+
'metadata' => { 'url' => 'http://example.com' })
46+
end
47+
48+
it 'adds metadata to `git config`' do
49+
ref = git('log --format=format:%H HEAD')
50+
get(version: { ref: ref, pr: '1' }, source: { uri: git_uri })
51+
52+
value = git('config --get pullrequest.url', dest_dir)
53+
expect(value).to eq 'http://example.com'
54+
end
55+
end

spec/integration/out_spec.rb

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'spec_helper'
2+
3+
describe 'out' do
4+
let(:proxy) { Billy::Proxy.new }
5+
let(:dest_dir) { Dir.mktmpdir }
6+
7+
before { proxy.start }
8+
after { proxy.reset }
9+
10+
def out(payload = {})
11+
path = ['./assets/out', '/opt/resource/out'].find { |p| File.exist? p }
12+
payload[:source] = { repo: 'jtarchie/test' }
13+
14+
output = `echo '#{JSON.generate(payload)}' | env http_proxy=#{proxy.url} #{path} #{dest_dir}`
15+
JSON.parse(output)
16+
end
17+
18+
context 'when acquiring a pull request' do
19+
it 'sets into pending mode' do
20+
out(params: {}, source: {})
21+
end
22+
end
23+
24+
context 'when the pull request is being release' do
25+
context 'and the build passed' do
26+
it 'sets into success mode' do
27+
out(params: {}, source: {})
28+
end
29+
end
30+
31+
context 'and the build failed' do
32+
it 'sets into failure mode' do
33+
out(params: {}, source: {})
34+
end
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)