stash_notifier 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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=