stash_notifier 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## version 2.0.0
2
+ Add stash_pwd option to notify
3
+ Add VCR support for offline testing
4
+ Refactor StashNotifier into Module
5
+ Create StashNotifier::BuildResult class
6
+ Create StashNotifier::HTTPClient class
7
+
8
+ Fixes #8: Add to_s method to StashNotifier class
9
+
1
10
  ## version 1.1.0
2
11
  Fixes #4: Rename "job\_" parameters to "build\_" and add `build_name` param
3
12
 
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard :rspec do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # StashNotifier
2
+ [![Build Status](https://travis-ci.org/dougireton/stash_notifier.png)](https://travis-ci.org/dougireton/stash_notifier)
2
3
 
3
4
  A Ruby gem to send CI build status to [Atlassian Stash 2.1+][1]
4
5
 
data/bin/notify CHANGED
@@ -16,31 +16,38 @@
16
16
  # limitations under the License.
17
17
 
18
18
  require 'slop'
19
-
20
19
  require 'stash_notifier'
20
+ require 'chef-vault'
21
21
 
22
22
  # EXAMPLE:
23
- # notify -s https://git.mycompany.com -u my_chef_user -c e2b8a34c60eeec41d3e9d83f60d3b288e909c1eb -r failed -k REPO-MASTER -n REPO-MASTER-12 -l http://jenkins.my_company.com/jenkins/view/FOO/job/Deploy/17/console -d 'Jenkins deploy job'
23
+ # notify -s https://git.mycompany.com -u my_stash_user -g e2b8a34c60eeec41d3e9d83f60d3b288e909c1eb -r failed -k REPO-MASTER -n REPO-MASTER-12 -l http://jenkins.my_company.com/jenkins/view/FOO/job/Deploy/17/console -d 'Jenkins deploy job'
24
24
 
25
- opts = Slop.parse( help: true, strict: true, arguments: true ) do
25
+ opts = Slop.parse(help: true, strict: true, arguments: true) do
26
26
  banner 'Usage: notify [options]'
27
- on :s, :stash_url=, 'Atlassian Stash server base URL, e.g. https://git.mycompany.com'
28
- on :u, :stash_user=, 'Stash API user'
29
- on :g, :git_commit=, 'Git commit sha'
30
- on :d, :data_bag=, 'Name of Chef passwords data bag'
31
- on :c, :config=, 'Chef config file'
32
- on :r, :build_status=, 'CI server job status, e.g. INPROGRESS, SUCCESSFUL, FAILED'
33
- on :k, :build_key=, 'CI server job name'
34
- on :n, :build_name=, 'CI server build name'
35
- on :l, :build_url=, 'URL to CI server job results'
36
- on :d, :build_description=, 'CI server job description'
27
+ on :s, :stash_url=, 'Atlassian Stash server base URL, e.g. https://git.mycompany.com'
28
+ on :u, :stash_user=, 'Stash API user'
29
+ on :p, :stash_pwd=, "Stash API user's password"
30
+ on :g, :git_commit=, 'Git commit sha'
31
+
32
+ on :d, :data_bag=, 'Name of Chef passwords data bag'
33
+ on :c, :config=, 'Chef config file'
34
+
35
+ on :r, :build_status=, 'CI server job status, e.g. INPROGRESS, SUCCESSFUL, FAILED'
36
+ on :k, :build_key=, 'CI server job name'
37
+ on :n, :build_name=, 'CI server build name'
38
+ on :l, :build_url=, 'URL to CI server job results'
39
+ on :d, :build_description=, 'CI server job description'
37
40
  end
38
41
 
39
- args = opts.to_hash
42
+ @args = opts.to_hash
43
+
44
+ def get_stash_pwd
45
+ ChefVault.load_config(@args[:config])
46
+ user = ChefVault::Item.load(@args[:data_bag], @args[:stash_user])
47
+ user['password']
48
+ end
40
49
 
41
- # this is bad. ChefVault should set this.
42
- args[:data_bag] ||= 'passwords'
50
+ @args[:stash_pwd] ||= get_stash_pwd
43
51
 
44
- notify = StashNotifier.new(args)
45
- notify.pwd_vault = ChefVault.new(args[:data_bag], args[:config])
52
+ notify = StashNotifier.new(@args)
46
53
  notify.post_to_stash
@@ -13,93 +13,26 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'faraday'
17
- require 'chef-vault'
18
- require 'json'
19
- require "stash_notifier/version"
20
-
21
- class StashNotifier
22
- attr_accessor :stash_url, :stash_user, :git_commit,
23
- :build_key, :build_name, :build_url, :build_description, :http_client, :pwd_vault
24
-
25
- attr_reader :build_status
26
-
27
- VALID_BUILD_STATUSES = %w{ INPROGRESS SUCCESSFUL FAILED }
28
- STASH_BUILD_STATUS_PATH = 'rest/build-status/1.0/commits'
29
-
30
- DEFAULTS = {
31
- http_client: Faraday.new,
32
- pwd_vault: ChefVault.new('passwords')
33
- }
34
-
35
- def initialize(args)
36
- args = DEFAULTS.merge(args) {|key, arg, default| arg.nil? ? default : arg}
37
-
38
- @stash_url = args[:stash_url]
39
- @stash_user = args[:stash_user]
40
- @git_commit = args[:git_commit]
41
- self.build_status = args[:build_status]
42
- @build_key = args[:build_key]
43
- @build_name = args[:build_name]
44
- @build_url = args[:build_url]
45
- @build_description = args[:build_description]
46
- @http_client = args[:http_client]
47
- @pwd_vault = args[:pwd_vault]
48
- end
49
-
50
- def build_status=(new_build_status)
51
- new_build_status = new_build_status.strip.upcase
52
-
53
- if VALID_BUILD_STATUSES.include?(new_build_status)
54
- @build_status = new_build_status
55
- else
56
- raise ArgumentError, "'#{new_build_status}' is not a valid Stash Build Status! Valid job statuses are #{VALID_BUILD_STATUSES}."
57
- end
58
- end
59
-
60
- def post_to_stash
61
- setup_http_client
62
- response = post_results
63
- check_errors(response)
64
- end
65
-
66
- private
67
-
68
- def setup_http_client
69
- http_client.url_prefix = stash_url
70
- http_client.path_prefix = STASH_BUILD_STATUS_PATH
71
- http_client.basic_auth(stash_user, get_pwd)
72
- http_client.ssl[:verify] = false
73
- end
74
-
75
- def post_results
76
- http_client.post do |req|
77
- req.url git_commit
78
- req.headers['Content-Type'] = 'application/json'
79
- req.body = format_build_result
80
- end
81
- end
82
-
83
- def check_errors(response, success_codes=[204])
84
- unless success_codes.include?(response.status)
85
- # raise an error here please
86
- puts "FAILED: #{response.to_s}"
16
+ require 'stash_notifier/build_result'
17
+ require 'stash_notifier/http_client'
18
+ require 'stash_notifier/version'
19
+
20
+ module StashNotifier
21
+ class << self
22
+ def new(args)
23
+ # TODO: Refactor this into private method
24
+ build_args = {}
25
+ build_args[:state] = args[:build_status]
26
+ build_args[:key] = args[:build_key]
27
+ build_args[:name] = args[:build_name]
28
+ build_args[:url] = args[:build_url]
29
+ build_args[:description] = args[:build_description]
30
+
31
+ build_result = StashNotifier::BuildResult.new(build_args)
32
+
33
+ args[:build_result] = build_result.to_json
34
+
35
+ StashNotifier::HTTPClient.new(args)
87
36
  end
88
37
  end
89
-
90
- def format_build_result
91
- build_result = {
92
- state: build_status,
93
- key: build_key,
94
- name: build_name,
95
- url: build_url,
96
- description: build_description
97
- }
98
- build_result.to_json
99
- end
100
-
101
- def get_pwd
102
- user = pwd_vault.user(stash_user)
103
- user.decrypt_password
104
- end
105
38
  end
@@ -0,0 +1,53 @@
1
+ # build_result.rb
2
+ # Copyright 2013 Doug Ireton
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module StashNotifier
17
+ class BuildResult
18
+
19
+ attr_accessor :key, :name, :url, :description
20
+ attr_reader :state
21
+
22
+ VALID_BUILD_STATES = %w{ INPROGRESS SUCCESSFUL FAILED }
23
+
24
+ def initialize(args)
25
+ self.state = args[:state]
26
+ @key = args[:key]
27
+ @name = args[:name]
28
+ @url = args[:url]
29
+ @description = args[:description]
30
+ end
31
+
32
+ def state=(new_state)
33
+ new_state = new_state.upcase
34
+ if VALID_BUILD_STATES.include?(new_state)
35
+ @state = new_state
36
+ else
37
+ raise ArgumentError, "'#{new_state}' is not a valid Stash Build state! Valid states are #{VALID_BUILD_STATES}."
38
+ end
39
+ end
40
+
41
+ def to_json
42
+ result = {
43
+ state: state,
44
+ key: key,
45
+ name: name,
46
+ url: url,
47
+ description: description
48
+ }
49
+ result.to_json
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ # exceptions.rb
2
+ # Copyright 2013 Doug Ireton
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module StashNotifier
17
+ class Error < StandardError; end
18
+ class BadRequest < StandardError; end
19
+ class Unauthorized < StandardError; end
20
+ end
@@ -0,0 +1,97 @@
1
+ # stash_nofier.rb
2
+ # Copyright 2013 Doug Ireton
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'faraday'
17
+ require 'json'
18
+ require 'stash_notifier/exceptions'
19
+
20
+ module StashNotifier
21
+
22
+ class HTTPClient
23
+ STASH_BUILD_STATUS_PATH = 'rest/build-status/1.0/commits'
24
+ DEFAULTS = {
25
+ http_client: Faraday.new
26
+ }.freeze
27
+
28
+ attr_accessor :stash_url, :stash_user, :stash_pwd, :git_commit,
29
+ :build_result, :http_client
30
+
31
+ def initialize(args)
32
+ args = DEFAULTS.merge(args)
33
+
34
+ @stash_url = args[:stash_url]
35
+ @stash_user = args[:stash_user]
36
+ @stash_pwd = args[:stash_pwd]
37
+ @git_commit = args[:git_commit]
38
+ @build_result = args[:build_result]
39
+ @http_client = args[:http_client]
40
+ end
41
+
42
+ def to_s
43
+ "StashNotifier connection:
44
+ url: #{stash_url},
45
+ git_commit: #{git_commit},
46
+ user: #{stash_user},
47
+ pwd: ***********,
48
+ build_result: #{build_result}"
49
+ end
50
+
51
+ def post_to_stash
52
+ setup_http_client
53
+ response = post_results
54
+ check_errors(response)
55
+ response
56
+ end
57
+
58
+ private
59
+
60
+ def setup_http_client
61
+ http_client.url_prefix = stash_url
62
+ http_client.path_prefix = STASH_BUILD_STATUS_PATH
63
+ http_client.basic_auth(stash_user, stash_pwd)
64
+ http_client.ssl[:verify] = false
65
+ end
66
+
67
+ def post_results
68
+ http_client.post do |req|
69
+ req.url git_commit
70
+ req.headers['Content-Type'] = 'application/json'
71
+ req.body = build_result
72
+ end
73
+ end
74
+
75
+ def check_errors(response)
76
+ unless response.success?
77
+
78
+ err_msg = get_stash_err(response)
79
+
80
+ case response.status
81
+ when 400
82
+ raise StashNotifier::BadRequest, err_msg
83
+ when 401
84
+ raise StashNotifier::Unauthorized, err_msg
85
+ else
86
+ raise StashNotifier::Error, err_msg
87
+ end
88
+ end
89
+ end
90
+
91
+ def get_stash_err(response)
92
+ response_body = JSON.parse(response.body)
93
+ response_body['errors'].first['message']
94
+ end
95
+
96
+ end
97
+ end
@@ -13,6 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- class StashNotifier
17
- VERSION = "1.1.0"
16
+ module StashNotifier
17
+ VERSION = '2.0.0'
18
18
  end
data/spec/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,46 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"SUCCESSFUL","key":"repo-master","name":"repo-master-42","url":"https://jenkins.example.com/view/All/job/myproject/57/console","description":null}'
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ Authorization:
13
+ - Basic <Base-64 encoded password>
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 204
19
+ message:
20
+ headers:
21
+ server:
22
+ - Apache-Coyote/1.1
23
+ x-arequestid:
24
+ - 1018x2286998x1
25
+ set-cookie:
26
+ - JSESSIONID=78EC7ADF309F13A72875495FA5DE378D; Path=/; Secure; HttpOnly
27
+ x-ausername:
28
+ - MY_STASH_USER
29
+ x-asessionid:
30
+ - p4ihzt
31
+ cache-control:
32
+ - no-cache, no-transform
33
+ vary:
34
+ - X-AUSERNAME, Cookie
35
+ content-type:
36
+ - application/json
37
+ date:
38
+ - Tue, 17 Sep 2013 23:58:14 GMT
39
+ connection:
40
+ - close
41
+ body:
42
+ encoding: US-ASCII
43
+ string: ''
44
+ http_version:
45
+ recorded_at: Tue, 17 Sep 2013 23:58:13 GMT
46
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,49 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/bogus
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"SUCCESSFUL","key":"repo-master","name":"repo-master-42","url":"https://jenkins.example.com/view/All/job/myproject/57/console","description":null}'
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ Authorization:
13
+ - Basic <Base-64 encoded password>
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 400
19
+ message:
20
+ headers:
21
+ server:
22
+ - Apache-Coyote/1.1
23
+ x-arequestid:
24
+ - 1018x2287000x1
25
+ set-cookie:
26
+ - JSESSIONID=902D30453B14A38C1D8978CAFB949FDE; Path=/; Secure; HttpOnly
27
+ x-ausername:
28
+ - MY_STASH_USER
29
+ x-asessionid:
30
+ - 12cpxek
31
+ cache-control:
32
+ - no-cache, no-transform
33
+ vary:
34
+ - X-AUSERNAME, Cookie
35
+ content-type:
36
+ - application/json;charset=UTF-8
37
+ transfer-encoding:
38
+ - chunked
39
+ date:
40
+ - Tue, 17 Sep 2013 23:58:14 GMT
41
+ connection:
42
+ - close
43
+ body:
44
+ encoding: US-ASCII
45
+ string: ! '{"errors":[{"context":null,"message":"Please specify the changeset
46
+ id as a 40-character hash","exceptionName":null}]}'
47
+ http_version:
48
+ recorded_at: Tue, 17 Sep 2013 23:58:13 GMT
49
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,50 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"successful","key":null,"name":"repo-master-42","url":"https://gittst.example.com","description":"This
9
+ is the description"}'
10
+ headers:
11
+ User-Agent:
12
+ - Faraday v0.8.8
13
+ Authorization:
14
+ - Basic <Base-64 encoded password>
15
+ Content-Type:
16
+ - application/json
17
+ response:
18
+ status:
19
+ code: 400
20
+ message:
21
+ headers:
22
+ server:
23
+ - Apache-Coyote/1.1
24
+ x-arequestid:
25
+ - 1018x2286996x1
26
+ set-cookie:
27
+ - JSESSIONID=A67AE640B7FA3BC552DE426A490B7FCB; Path=/; Secure; HttpOnly
28
+ x-ausername:
29
+ - MY_STASH_USER
30
+ x-asessionid:
31
+ - 1l5rkd0
32
+ cache-control:
33
+ - no-cache, no-transform
34
+ vary:
35
+ - X-AUSERNAME, Cookie
36
+ content-type:
37
+ - application/json;charset=UTF-8
38
+ transfer-encoding:
39
+ - chunked
40
+ date:
41
+ - Tue, 17 Sep 2013 23:58:13 GMT
42
+ connection:
43
+ - close
44
+ body:
45
+ encoding: US-ASCII
46
+ string: ! '{"errors":[{"context":null,"message":"Please specify a non-blank
47
+ key","exceptionName":null}]}'
48
+ http_version:
49
+ recorded_at: Tue, 17 Sep 2013 23:58:12 GMT
50
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,50 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"bogus","key":"repo-master","name":"repo-master-42","url":"https://gittst.example.com","description":"This
9
+ is the description"}'
10
+ headers:
11
+ User-Agent:
12
+ - Faraday v0.8.8
13
+ Authorization:
14
+ - Basic <Base-64 encoded password>
15
+ Content-Type:
16
+ - application/json
17
+ response:
18
+ status:
19
+ code: 400
20
+ message:
21
+ headers:
22
+ server:
23
+ - Apache-Coyote/1.1
24
+ x-arequestid:
25
+ - 1018x2286997x1
26
+ set-cookie:
27
+ - JSESSIONID=EF4D56A1F42560CBBD897C99B903E0C0; Path=/; Secure; HttpOnly
28
+ x-ausername:
29
+ - MY_STASH_USER
30
+ x-asessionid:
31
+ - 879ej3
32
+ cache-control:
33
+ - no-cache, no-transform
34
+ vary:
35
+ - X-AUSERNAME, Cookie
36
+ content-type:
37
+ - application/json;charset=UTF-8
38
+ transfer-encoding:
39
+ - chunked
40
+ date:
41
+ - Tue, 17 Sep 2013 23:58:13 GMT
42
+ connection:
43
+ - close
44
+ body:
45
+ encoding: US-ASCII
46
+ string: ! '{"errors":[{"context":null,"message":"Please specify a valid state
47
+ (valid states: {SUCCESSFUL,FAILED,INPROGRESS})","exceptionName":null}]}'
48
+ http_version:
49
+ recorded_at: Tue, 17 Sep 2013 23:58:13 GMT
50
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,49 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"successful","key":"repo-master","name":"repo-master-42","url":"bogus","description":"This
9
+ is the description"}'
10
+ headers:
11
+ User-Agent:
12
+ - Faraday v0.8.8
13
+ Authorization:
14
+ - Basic <Base-64 encoded password>
15
+ Content-Type:
16
+ - application/json
17
+ response:
18
+ status:
19
+ code: 400
20
+ message:
21
+ headers:
22
+ server:
23
+ - Apache-Coyote/1.1
24
+ x-arequestid:
25
+ - 1018x2286994x1
26
+ set-cookie:
27
+ - JSESSIONID=9FC5CD033AAEE6B9019416F415E4D03F; Path=/; Secure; HttpOnly
28
+ x-ausername:
29
+ - MY_STASH_USER
30
+ x-asessionid:
31
+ - 16txqub
32
+ cache-control:
33
+ - no-cache, no-transform
34
+ vary:
35
+ - X-AUSERNAME, Cookie
36
+ content-type:
37
+ - application/json;charset=UTF-8
38
+ transfer-encoding:
39
+ - chunked
40
+ date:
41
+ - Tue, 17 Sep 2013 23:58:13 GMT
42
+ connection:
43
+ - close
44
+ body:
45
+ encoding: US-ASCII
46
+ string: ! '{"errors":[{"context":null,"message":"Please specify a valid url","exceptionName":null}]}'
47
+ http_version:
48
+ recorded_at: Tue, 17 Sep 2013 23:58:12 GMT
49
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"SUCCESSFUL","key":"repo-master","name":"repo-master-42","url":"https://jenkins.example.com/view/All/job/myproject/57/console","description":null}'
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ Authorization:
13
+ - Basic <Base-64 encoded password>
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 401
19
+ message:
20
+ headers:
21
+ server:
22
+ - Apache-Coyote/1.1
23
+ x-arequestid:
24
+ - 1018x2286999x1
25
+ set-cookie:
26
+ - JSESSIONID=6B3D48F2656588A1AF9F323BDA04FFA7; Path=/; Secure; HttpOnly, _atl_stash_remember_me="";
27
+ Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
28
+ www-authenticate:
29
+ - Basic realm="Atlassian Stash"
30
+ content-type:
31
+ - application/json;charset=UTF-8
32
+ content-length:
33
+ - '130'
34
+ date:
35
+ - Tue, 17 Sep 2013 23:58:14 GMT
36
+ connection:
37
+ - close
38
+ body:
39
+ encoding: US-ASCII
40
+ string: ! '{"errors":[{"context":null,"message":"Authentication failed. Please
41
+ check your credentials and try again.","exceptionName":null}]}'
42
+ http_version:
43
+ recorded_at: Tue, 17 Sep 2013 23:58:13 GMT
44
+ recorded_with: VCR 2.5.0
@@ -0,0 +1,44 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://stash.example.com/rest/build-status/1.0/commits/68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"state":"SUCCESSFUL","key":"repo-master","name":"repo-master-42","url":"https://jenkins.example.com/view/All/job/myproject/57/console","description":null}'
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ Authorization:
13
+ - Basic Ym9ndXM6TTBiaWxlLXNoZWxs
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 401
19
+ message:
20
+ headers:
21
+ server:
22
+ - Apache-Coyote/1.1
23
+ x-arequestid:
24
+ - 1018x2286995x1
25
+ set-cookie:
26
+ - JSESSIONID=F0BB7905B2B5E65755F44E61DCDF9215; Path=/; Secure; HttpOnly, _atl_stash_remember_me="";
27
+ Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
28
+ www-authenticate:
29
+ - Basic realm="Atlassian Stash"
30
+ content-type:
31
+ - application/json;charset=UTF-8
32
+ content-length:
33
+ - '130'
34
+ date:
35
+ - Tue, 17 Sep 2013 23:58:13 GMT
36
+ connection:
37
+ - close
38
+ body:
39
+ encoding: US-ASCII
40
+ string: ! '{"errors":[{"context":null,"message":"Authentication failed. Please
41
+ check your credentials and try again.","exceptionName":null}]}'
42
+ http_version:
43
+ recorded_at: Tue, 17 Sep 2013 23:58:12 GMT
44
+ recorded_with: VCR 2.5.0
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- # speck_helper.rb
1
+ # spec_helper.rb
2
2
  # Copyright 2013 Doug Ireton
3
3
 
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,3 +15,28 @@
15
15
 
16
16
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
17
17
  require 'stash_notifier'
18
+ require 'vcr'
19
+
20
+ VCR.configure do |c|
21
+ c.cassette_library_dir = 'spec/cassettes'
22
+ c.hook_into :faraday
23
+ c.configure_rspec_metadata!
24
+ end
25
+
26
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
27
+ RSpec.configure do |config|
28
+ config.treat_symbols_as_metadata_keys_with_true_values = true
29
+ config.run_all_when_everything_filtered = true
30
+ config.filter_run :focus
31
+
32
+ # disable should syntax
33
+ config.expect_with :rspec do |c|
34
+ c.syntax = :expect
35
+ end
36
+
37
+ # Run specs in random order to surface order dependencies. If you find an
38
+ # order dependency and want to debug it, you can fix the order by providing
39
+ # the seed, which is printed after each run.
40
+ # --seed 1234
41
+ config.order = 'random'
42
+ end
@@ -0,0 +1,79 @@
1
+ # build_result_spec.rb
2
+ # Copyright 2013 Doug Ireton
3
+
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'json'
17
+ require 'spec_helper'
18
+
19
+ describe StashNotifier::BuildResult do
20
+
21
+ let(:args) {
22
+ {
23
+ state: 'successful',
24
+ key: 'repo-master',
25
+ name: 'repo-master-42',
26
+ url: 'https://gittst.example.com',
27
+ description: 'This is the description'
28
+ }
29
+ }
30
+
31
+ let(:build_result) { StashNotifier::BuildResult.new(args) }
32
+
33
+ describe '#state' do
34
+ it "returns UPPERCASE state" do
35
+ expect(build_result.state).to eq('SUCCESSFUL')
36
+ end
37
+
38
+ it 'accepts a different state' do
39
+ build_result.state = 'failed'
40
+ expect(build_result.state).to eq('FAILED')
41
+ end
42
+
43
+ it 'raises an ArgumentError when state is not valid' do
44
+ expect { build_result.state = 'foo' }.to raise_error(ArgumentError)
45
+ end
46
+ end
47
+
48
+ describe '#key' do
49
+ it 'returns the build key' do
50
+ expect(build_result.key).to eq 'repo-master'
51
+ end
52
+ end
53
+
54
+ describe '#name' do
55
+ it 'returns the name' do
56
+ expect(build_result.name).to eq 'repo-master-42'
57
+ end
58
+ end
59
+
60
+ describe '#url' do
61
+ it 'returns the url' do
62
+ expect(build_result.url).to eq 'https://gittst.example.com'
63
+ end
64
+ end
65
+
66
+ describe '#description' do
67
+ it 'returns the description' do
68
+ expect(build_result.description).to eq 'This is the description'
69
+ end
70
+ end
71
+
72
+ describe '#to_json' do
73
+ it 'returns a JSON string suitable for sending to the Stash Build Result API endpoint' do
74
+ args[:state] = 'SUCCESSFUL'
75
+ expect(build_result.to_json).to eq(args.to_json)
76
+ end
77
+ end
78
+
79
+ end
@@ -14,10 +14,110 @@
14
14
  # limitations under the License.
15
15
 
16
16
  require 'spec_helper'
17
+ require 'json'
17
18
 
18
19
  describe StashNotifier do
19
- it 'should have a version number' do
20
- expect(StashNotifier::VERSION).to_not be_nil
20
+
21
+ let(:build_result) do
22
+ {
23
+ state: 'successful',
24
+ key: 'repo-master',
25
+ name: 'repo-master-42',
26
+ url: 'https://jenkins.example.com/view/All/job/myproject/57/console',
27
+ description: 'This is the description'
28
+ }
29
+ end
30
+
31
+ let(:args) do
32
+ {
33
+ stash_url: 'https://stash.example.com',
34
+ stash_user: 'my_stash_user',
35
+ stash_pwd: 'P@ssword',
36
+ git_commit: '68ccfc66971c2e1e2ca57e17707dbebb6c6b4ebb',
37
+ build_status: build_result[:state],
38
+ build_key: build_result[:key],
39
+ build_name: build_result[:name],
40
+ build_url: build_result[:url],
41
+ description: build_result[:description],
42
+ # you must supply http_client so that VCR can override it
43
+ http_client: Faraday.new
44
+ }
45
+ end
46
+
47
+ let!(:stash_notifier) { StashNotifier.new(args) }
48
+
49
+ it 'should have a SimVer compatible version number' do
50
+ SIMVER_REGEXP = /^\d{1}\.\d{1,2}\.\d{1,2}\.*\w*$/
51
+ expect(StashNotifier::VERSION).to match SIMVER_REGEXP
52
+ end
53
+
54
+ describe '#post_to_stash', :vcr do
55
+ it 'returns 204 when passed valid parameters' do
56
+
57
+ response = stash_notifier.post_to_stash
58
+ expect(response.status).to eq 204
59
+ end
60
+
61
+ it 'returns 401 when passed an invalid stash_user' do
62
+ stash_notifier.stash_user = 'bogus'
63
+
64
+ expect { stash_notifier.post_to_stash }.to \
65
+ raise_error(StashNotifier::Unauthorized,
66
+ 'Authentication failed. Please check your credentials and try again.')
67
+ end
68
+
69
+ it 'returns 401 when passed an invalid stash_pwd' do
70
+ stash_notifier.stash_pwd = 'bogus'
71
+
72
+ expect { stash_notifier.post_to_stash }.to \
73
+ raise_error(StashNotifier::Unauthorized,
74
+ 'Authentication failed. Please check your credentials and try again.')
75
+ end
76
+
77
+ it 'returns 400 when passed an invalid git_commit' do
78
+ stash_notifier.git_commit = 'bogus'
79
+
80
+ expect { stash_notifier.post_to_stash }.to \
81
+ raise_error(StashNotifier::BadRequest)
82
+ end
83
+
84
+ it 'returns 400 when the build state is missing or invalid' do
85
+ build_result[:state] = 'bogus'
86
+ stash_notifier.build_result = build_result.to_json
87
+
88
+ expect { stash_notifier.post_to_stash }.to \
89
+ raise_error(StashNotifier::BadRequest)
90
+ end
91
+
92
+ it 'returns 400 when the build key is missing or invalid' do
93
+ build_result[:key] = nil
94
+ stash_notifier.build_result = build_result.to_json
95
+
96
+ expect { stash_notifier.post_to_stash }.to \
97
+ raise_error(StashNotifier::BadRequest)
98
+ end
99
+
100
+ it 'returns 400 when the build url is missing or invalid' do
101
+ build_result[:url] = 'bogus'
102
+ stash_notifier.build_result = build_result.to_json
103
+
104
+ expect { stash_notifier.post_to_stash }.to \
105
+ raise_error(StashNotifier::BadRequest)
106
+ end
107
+ end
108
+
109
+ describe '#to_s' do
110
+ it 'returns a nice, descriptive string' do
111
+ stash_notifier = StashNotifier.new(args)
112
+ expect(stash_notifier.to_s).to start_with('StashNotifier connection')
113
+ end
114
+
115
+ end
116
+
117
+ describe '#http_client' do
118
+ it 'returns the http_client' do
119
+ expect(stash_notifier.http_client).to be_an_instance_of(Faraday::Connection)
120
+ end
21
121
  end
22
122
 
23
123
  end
@@ -19,25 +19,28 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
19
19
  require 'stash_notifier/version'
20
20
 
21
21
  Gem::Specification.new do |spec|
22
- spec.name = "stash_notifier"
22
+ spec.name = 'stash_notifier'
23
23
  spec.version = StashNotifier::VERSION
24
- spec.authors = ["Doug Ireton"]
25
- spec.email = ["doug.ireton@nordstrom.com"]
24
+ spec.authors = ['Doug Ireton']
25
+ spec.email = ['doug.ireton@nordstrom.com']
26
26
  spec.description = %q{Send per-commit CI server build results to Atlassian Stash}
27
27
  spec.summary = %q{Send per-commit CI server build results to Atlassian Stash}
28
- spec.homepage = "https://github.com/dougireton/stash_notifier"
29
- spec.license = "Apache License, Version 2.0"
28
+ spec.homepage = 'https://github.com/dougireton/stash_notifier'
29
+ spec.license = 'Apache License, Version 2.0'
30
30
 
31
31
  spec.files = `git ls-files`.split($/)
32
32
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
33
33
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
34
- spec.require_paths = ["lib"]
34
+ spec.require_paths = ['lib']
35
35
 
36
36
  spec.add_dependency 'faraday', '~> 0.8'
37
- spec.add_dependency 'chef-vault', '~> 1.2'
37
+ spec.add_dependency 'chef-vault', '~> 2.0'
38
38
  spec.add_dependency 'slop'
39
39
 
40
- spec.add_development_dependency "bundler", "~> 1.3"
41
- spec.add_development_dependency "rake"
42
- spec.add_development_dependency "rspec"
40
+ spec.add_development_dependency 'bundler', '~> 1.3'
41
+ spec.add_development_dependency 'rake'
42
+ spec.add_development_dependency 'rspec', '~> 2.14'
43
+ spec.add_development_dependency 'vcr', '~> 2.5'
44
+ spec.add_development_dependency 'guard'
45
+ spec.add_development_dependency 'guard-rspec'
43
46
  end
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stash_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Doug Ireton
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-05-22 00:00:00.000000000 Z
12
+ date: 2013-09-23 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: faraday
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
@@ -27,20 +30,23 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: chef-vault
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
33
- version: '1.2'
37
+ version: '2.0'
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
40
- version: '1.2'
45
+ version: '2.0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: slop
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - ! '>='
46
52
  - !ruby/object:Gem::Version
@@ -48,6 +54,7 @@ dependencies:
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - ! '>='
53
60
  - !ruby/object:Gem::Version
@@ -55,6 +62,7 @@ dependencies:
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: bundler
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ~>
60
68
  - !ruby/object:Gem::Version
@@ -62,6 +70,7 @@ dependencies:
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ~>
67
76
  - !ruby/object:Gem::Version
@@ -69,6 +78,7 @@ dependencies:
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: rake
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ! '>='
74
84
  - !ruby/object:Gem::Version
@@ -76,6 +86,7 @@ dependencies:
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ! '>='
81
92
  - !ruby/object:Gem::Version
@@ -83,6 +94,55 @@ dependencies:
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: rspec
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '2.14'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.14'
110
+ - !ruby/object:Gem::Dependency
111
+ name: vcr
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '2.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '2.5'
126
+ - !ruby/object:Gem::Dependency
127
+ name: guard
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: guard-rspec
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
86
146
  requirements:
87
147
  - - ! '>='
88
148
  - !ruby/object:Gem::Version
@@ -90,6 +150,7 @@ dependencies:
90
150
  type: :development
91
151
  prerelease: false
92
152
  version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
93
154
  requirements:
94
155
  - - ! '>='
95
156
  - !ruby/object:Gem::Version
@@ -107,39 +168,62 @@ files:
107
168
  - .travis.yml
108
169
  - CHANGELOG.md
109
170
  - Gemfile
171
+ - Guardfile
110
172
  - LICENSE
111
173
  - README.md
112
174
  - Rakefile
113
175
  - bin/notify
114
176
  - lib/stash_notifier.rb
177
+ - lib/stash_notifier/build_result.rb
178
+ - lib/stash_notifier/exceptions.rb
179
+ - lib/stash_notifier/http_client.rb
115
180
  - lib/stash_notifier/version.rb
181
+ - spec/.rspec
182
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_204_when_passed_valid_parameters.yml
183
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_passed_an_invalid_git_commit.yml
184
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_key_is_missing_or_invalid.yml
185
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_state_is_missing_or_invalid.yml
186
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_url_is_missing_or_invalid.yml
187
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_401_when_passed_an_invalid_stash_pwd.yml
188
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_401_when_passed_an_invalid_stash_user.yml
116
189
  - spec/spec_helper.rb
190
+ - spec/stash_notifier/build_result_spec.rb
117
191
  - spec/stash_notifier_spec.rb
118
192
  - stash_notifier.gemspec
119
193
  homepage: https://github.com/dougireton/stash_notifier
120
194
  licenses:
121
195
  - Apache License, Version 2.0
122
- metadata: {}
123
196
  post_install_message:
124
197
  rdoc_options: []
125
198
  require_paths:
126
199
  - lib
127
200
  required_ruby_version: !ruby/object:Gem::Requirement
201
+ none: false
128
202
  requirements:
129
203
  - - ! '>='
130
204
  - !ruby/object:Gem::Version
131
205
  version: '0'
132
206
  required_rubygems_version: !ruby/object:Gem::Requirement
207
+ none: false
133
208
  requirements:
134
209
  - - ! '>='
135
210
  - !ruby/object:Gem::Version
136
211
  version: '0'
137
212
  requirements: []
138
213
  rubyforge_project:
139
- rubygems_version: 2.0.3
214
+ rubygems_version: 1.8.23
140
215
  signing_key:
141
- specification_version: 4
216
+ specification_version: 3
142
217
  summary: Send per-commit CI server build results to Atlassian Stash
143
218
  test_files:
219
+ - spec/.rspec
220
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_204_when_passed_valid_parameters.yml
221
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_passed_an_invalid_git_commit.yml
222
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_key_is_missing_or_invalid.yml
223
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_state_is_missing_or_invalid.yml
224
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_400_when_the_build_url_is_missing_or_invalid.yml
225
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_401_when_passed_an_invalid_stash_pwd.yml
226
+ - spec/cassettes/StashNotifier/_post_to_stash/returns_401_when_passed_an_invalid_stash_user.yml
144
227
  - spec/spec_helper.rb
228
+ - spec/stash_notifier/build_result_spec.rb
145
229
  - spec/stash_notifier_spec.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDQ5MWE1ZGYxMTgwNjVkZDUzYTFmYzkzZTZmMWIzMWY3ZTc0MDcwYQ==
5
- data.tar.gz: !binary |-
6
- OTlhZTZjYTYxYzZiNGE1ZTc5MjkwNjcyMTQwODdmM2UzOTg1MGJlMg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- NTgxOGE5NGQxYjcxODQwNzFjOTUxZWYzYmQxZjVhNjMwNDZiYWE1NTIxYjhh
10
- MGZhMDVlOWVhM2JlNDdjZmVhZGYyYzFiYzg4MGQzMmUyZjQ4ZDU0N2UwMGY4
11
- ZDhhMjI0NjEyNzZmNmQwM2VmNWVhOGRmZDVmOWNkZmU1NzdkMTA=
12
- data.tar.gz: !binary |-
13
- MmMwZDlmNGM3MjI2ZjZmMmM4ZDBlZDViNjkyMTUyOGRlYTdhZTM3Y2JkYTQ4
14
- NGIxMDkwMjI0ZDkzZTJhM2FkNmJkMWY2YjMzYTQwNDUxM2FiODA0ZTg2ZjBh
15
- OWU1ZjczZTc1MDc2NzcyZTNkZjBkOThlOGFjNTc1YWI4N2I3NmY=