kitchen_hooks 1.5.0 → 1.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a997335e993e6cded0cb5dfe84803138e646ddc
4
- data.tar.gz: f01a6aa92888bbcc0a74d36a9dc763ed8b409c78
3
+ metadata.gz: fdb2a72a6956b35d41937cde0cee3be69ad832f2
4
+ data.tar.gz: 8f033c77c713dee2abe2ef435b7ef2d01645bdc6
5
5
  SHA512:
6
- metadata.gz: 073e0b9b0264c27d8fc27ae2db1c94740b2eaf6a89ea9b7834dd67ff081e951f529fc65d63bf4f883c4e4dd533ccd7bc36273d059c5acf27f03708625d6b340d
7
- data.tar.gz: b8298d57885f831d7f8edb496b623fb2524bbfaf44896cf97b5f590c3939575355486f205120c00e6f70cf0e277e0d377bc2416958f105dcb98351245f5e25b3
6
+ metadata.gz: 9ab833ecddff610020cec29609480d136514a069425a16ab9daaa941c9de9453e5fc5b380a5a5b9bbe72b9a62b5ccc85ce44431f7c48ee9aaa3b42d3ea810dd6
7
+ data.tar.gz: cbea2a4672b06e4e096e335e7e2efd2220944bc59e1504f6ddd774a81d622cef6993029e76cade61722f43d5999c9725f4fd1ac44d148dc7ff42e60ba57425ce
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kitchen_hooks (1.4.4)
4
+ kitchen_hooks (1.5.0)
5
5
  berkshelf (~> 3)
6
6
  chef (~> 11.16.4)
7
7
  daybreak (~> 0.3)
data/Readme.md CHANGED
@@ -32,15 +32,14 @@ Use the `server` command to start the WebHook receiver:
32
32
 
33
33
  ## TODO
34
34
 
35
- * Add indication of success or failure
36
35
  * Use Ridley for data bag, role, and environment uploads to remove Chef dependency
37
- * Only make changes on commits to `master` branches
38
-
39
36
 
40
37
  ## Changelog
41
38
 
42
39
  ### 1.5
43
40
 
41
+ * Add indication of success or failure
42
+ * Only upload on commits to Kitchen `master` branch
44
43
  * Add custom timeline icons to distinguish event types
45
44
 
46
45
  ### 1.4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 1.5.1
data/etc/commit.json CHANGED
@@ -6,51 +6,11 @@
6
6
  "user_name": "Sean Clemmer",
7
7
  "repository": {
8
8
  "name": "Kitchen Hooks",
9
- "url": "git@git.bluejeansnet.com:kitchen-hooks.git",
9
+ "url": "git@git.bluejeansnet.com:chef/kitchen.git",
10
10
  "description": "",
11
- "homepage": "http://git.bluejeansnet.com/kitchen-hooks"
11
+ "homepage": "http://git.bluejeansnet.com/kitchen"
12
12
  },
13
13
  "commits": [
14
- {
15
- "id": "b635fcb8f05e7503c7e6255a6b3e0cebbf487df3",
16
- "message": "Initial script",
17
- "timestamp": "2014-11-20T15:45:54-08:00",
18
- "url": "http://git.bluejeansnet.com/kitchen-hooks/commit/b635fcb8f05e7503c7e6255a6b3e0cebbf487df3",
19
- "author": {
20
- "name": "Kelly Wong",
21
- "email": "kelly@bluejeans.com"
22
- }
23
- },
24
- {
25
- "id": "b76fd9058de0f0236605f1ac12aaa405e905a383",
26
- "message": "Add notifications",
27
- "timestamp": "2014-11-24T18:23:21-08:00",
28
- "url": "http://git.bluejeansnet.com/kitchen-hooks/commit/b76fd9058de0f0236605f1ac12aaa405e905a383",
29
- "author": {
30
- "name": "Kelly Wong",
31
- "email": "kelly@bluejeans.com"
32
- }
33
- },
34
- {
35
- "id": "750a5fbb0741977a2b3e5b87e680b8e1beec001e",
36
- "message": "Make a gem",
37
- "timestamp": "2014-11-25T17:47:16-08:00",
38
- "url": "http://git.bluejeansnet.com/kitchen-hooks/commit/750a5fbb0741977a2b3e5b87e680b8e1beec001e",
39
- "author": {
40
- "name": "Kelly Wong",
41
- "email": "kelly@bluejeans.com"
42
- }
43
- },
44
- {
45
- "id": "e3727928632d4ac30599c6726e9532b5e0cd86d7",
46
- "message": "Remove MIT license",
47
- "timestamp": "2014-11-25T18:29:17-08:00",
48
- "url": "http://git.bluejeansnet.com/kitchen-hooks/commit/e3727928632d4ac30599c6726e9532b5e0cd86d7",
49
- "author": {
50
- "name": "Kelly Wong",
51
- "email": "kelly@bluejeans.com"
52
- }
53
- },
54
14
  {
55
15
  "id": "fb38bcc884a0579cb52836b00589bca653a9c229",
56
16
  "message": "Update readme",
data/etc/config.json CHANGED
@@ -1,10 +1,4 @@
1
1
  {
2
- "hipchat": {
3
- "nick": "Kitchen (bot)",
4
- "room": "test",
5
- "token": "YOUR_V1_HIPCHAT_TOKEN"
6
- },
7
- "knives": {
8
- "prod": "~/.chef/knife.rb"
9
- }
2
+ "hipchat": null,
3
+ "knives": {}
10
4
  }
@@ -57,7 +57,7 @@ module KitchenHooks
57
57
 
58
58
  post '/' do
59
59
  request.body.rewind
60
- event = JSON::parse request.body.read
60
+ event = JSON::parse request.body.read rescue nil
61
61
  Thread.new do
62
62
  process event
63
63
  end
@@ -75,39 +75,49 @@ module KitchenHooks
75
75
  color: color, notify: notify, message_format: 'html'
76
76
  end
77
77
 
78
- def notify event, type
79
- hipchat notification(event, type)
78
+ def notify entry
79
+ hipchat notification(entry)
80
80
  end
81
81
 
82
- def mark event, type
82
+ # error == nil => success
83
+ # error == false => nop
84
+ # otherwise => failure
85
+ def mark event, type, error=nil
86
+ return if error == false
87
+ entry = { type: type, event: event }
88
+ entry.merge!(error: error, type: 'failure') if error
83
89
  db.synchronize do
84
- db[Time.now.to_f] = {
85
- type: type,
86
- event: event
87
- }
90
+ db[Time.now.to_f] = entry
88
91
  end
89
- notify event, type
92
+ db.flush
93
+ notify entry
90
94
  end
91
95
 
92
96
  def process event
97
+ if event.nil? # JSON parse failed
98
+ mark event, 'failure', 'Could not parse WebHook payload'
99
+ return
100
+ end
101
+
93
102
  if commit_to_kitchen?(event)
94
- perform_kitchen_upload(event, knives)
95
- mark event, 'kitchen upload'
103
+ possible_error = perform_kitchen_upload(event, knives) \
104
+ rescue 'Unable to perform kitchen upload'
105
+ mark event, 'kitchen upload', possible_error
96
106
  end
97
107
 
98
108
  if tagged_commit_to_cookbook?(event) &&
99
- tag_name(event) =~ /^v\d+/ # Tagged with version we're releasing
100
- perform_cookbook_upload(event, knives)
101
- mark event, 'cookbook upload'
109
+ tag_name(event) =~ /^v\d+/ # Cookbooks tagged with a version
110
+ possible_error = perform_cookbook_upload(event, knives) \
111
+ rescue 'Unable to perform cookbook upload'
112
+ mark event, 'cookbook upload', possible_error
102
113
  end
103
114
 
104
115
  if tagged_commit_to_realm?(event) &&
105
- tag_name(event) =~ /^bjn_/ # Tagged with environment we're pinning
106
- perform_constraint_application(event, knives)
107
- mark event, 'constraint application'
116
+ tag_name(event) =~ /^bjn_/ # Realms tagged with an environment
117
+ possible_error = perform_constraint_application(event, knives) \
118
+ rescue 'Unable to apply constraints'
119
+ mark event, 'constraint application', possible_error
108
120
  end
109
-
110
- db.flush
111
121
  end
112
122
  end
113
123
  end
@@ -11,10 +11,10 @@ Berkshelf.logger = Logger.new $stdout
11
11
 
12
12
  module KitchenHooks
13
13
  module Helpers
14
+
14
15
  def perform_constraint_application event, knives
15
- tag = tag_name event
16
- tmp_clone event, :tagged_commit do |dir|
17
- Dir.chdir dir do
16
+ tmp_clone event, :tagged_commit do |clone|
17
+ Dir.chdir clone do
18
18
  logger.info 'Applying constraints'
19
19
  constraints = lockfile_constraints 'Berksfile.lock'
20
20
  environment = tag_name event
@@ -23,9 +23,14 @@ module KitchenHooks
23
23
  end
24
24
  end
25
25
  end
26
+
27
+ return nil # no error
26
28
  end
27
29
 
30
+
28
31
  def perform_kitchen_upload event, knives
32
+ return false unless commit_to_master?(event)
33
+
29
34
  tmp_clone event, :latest_commit do |clone|
30
35
  Dir.chdir clone do
31
36
  logger.info 'Uploading data_bags'
@@ -42,13 +47,13 @@ module KitchenHooks
42
47
  end
43
48
  end
44
49
  end
50
+
51
+ return nil # no error
45
52
  end
46
53
 
47
- def perform_cookbook_upload event, knives
48
- berksfile = nil
49
54
 
55
+ def perform_cookbook_upload event, knives
50
56
  tmp_clone event, :tagged_commit do |clone|
51
-
52
57
  Dir.chdir clone do
53
58
  tagged_version = tag_name(event).delete('v')
54
59
  cookbook_version = File.read('VERSION').strip
@@ -68,8 +73,11 @@ module KitchenHooks
68
73
  end
69
74
  end
70
75
  end
76
+
77
+ return nil # no error
71
78
  end
72
79
 
80
+
73
81
  def berks_upload berksfile, knife, options={}
74
82
  ridley = Ridley::from_chef_config knife
75
83
  options.merge! \
@@ -85,6 +93,7 @@ module KitchenHooks
85
93
  berksfile.upload [], options
86
94
  end
87
95
 
96
+
88
97
  def tmp_clone event, commit_method, &block
89
98
  Dir.mktmpdir do |tmp|
90
99
  dir = File::join tmp, cookbook_name(event)
@@ -94,12 +103,14 @@ module KitchenHooks
94
103
  end
95
104
  end
96
105
 
106
+
97
107
  def with_each_knife command, knives
98
108
  knives.map do |k|
99
109
  `knife #{command} --config #{Shellwords::escape k}`
100
110
  end
101
111
  end
102
112
 
113
+
103
114
  def apply_constraints constraints, environment, knife
104
115
  # Ripped from Berkshelf::Cli::apply and Berkshelf::Lockfile::apply
105
116
  # https://github.com/berkshelf/berkshelf/blob/master/lib/berkshelf/cli.rb
@@ -112,6 +123,7 @@ module KitchenHooks
112
123
  chef_environment.save
113
124
  end
114
125
 
126
+
115
127
  def lockfile_constraints lockfile_path
116
128
  # Ripped from Berkshelf::Cli::apply and Berkshelf::Lockfile::apply
117
129
  # https://github.com/berkshelf/berkshelf/blob/master/lib/berkshelf/cli.rb
@@ -123,6 +135,7 @@ module KitchenHooks
123
135
  end
124
136
  end
125
137
 
138
+
126
139
  def upload_environment environment, knife
127
140
  # Load the local environment from a JSON file
128
141
  local_environment = JSON::parse File.read(environment)
@@ -149,10 +162,13 @@ module KitchenHooks
149
162
  chef_environment.save
150
163
  end
151
164
 
152
- def notification event, type
153
- case type
165
+
166
+ def notification entry
167
+ return entry[:error] if entry[:error]
168
+ event = entry[:event]
169
+ case entry[:type]
154
170
  when 'kitchen upload'
155
- %Q| <i>#{author(event)}</i> updated <a href="#{gitlab_url(event)}">the Kitchen</a></p> |
171
+ %Q| <i>#{author(event)}</i> updated <a href="#{gitlab_url(event)}">the Kitchen</a> |
156
172
  when 'cookbook upload'
157
173
  %Q| <i>#{author(event)}</i> released <a href="#{gitlab_tag_url(event)}">#{tag_name(event)}</a> of <a href="#{gitlab_url(event)}">#{repo_name(event)}</a> |
158
174
  when 'constraint application'
@@ -160,40 +176,70 @@ module KitchenHooks
160
176
  end.strip
161
177
  end
162
178
 
179
+
180
+ def generic_details event
181
+ return if event.nil?
182
+ %Q|
183
+ <i>#{author(event)}</i> pushed #{push_details(event)}
184
+ |.strip
185
+ end
186
+
187
+
188
+ def push_details event
189
+ return if event.nil?
190
+ %Q|
191
+ <a href="#{gitlab_url(event)}">#{event['after']}</a> to <a href="#{repo_url(event)}">#{repo_name(event)}</a>
192
+ |.strip
193
+ end
194
+
195
+
163
196
  def author event
164
197
  event['user_name']
165
198
  end
166
199
 
200
+
167
201
  def repo_name event
168
202
  File::basename event['repository']['url'], '.git'
169
203
  end
170
204
 
205
+
171
206
  def cookbook_name event
172
207
  repo_name(event).sub /^(app|base|realm|fork)_/, 'bjn_'
173
208
  end
174
209
 
210
+
175
211
  def cookbook_repo? event
176
212
  repo_name(event) =~ /^(app|base|realm|fork)_/
177
213
  end
178
214
 
215
+
216
+ def repo_url event
217
+ git_daemon_style_url(event).sub(/^git/, 'http').sub(/\.git$/, '')
218
+ end
219
+
220
+
179
221
  def git_daemon_style_url event
180
222
  event['repository']['url'].sub(':', '/').sub('@', '://')
181
223
  end
182
224
 
225
+
183
226
  def gitlab_url event
184
227
  url = git_daemon_style_url(event).sub(/^git/, 'http').sub(/\.git$/, '')
185
228
  "#{url}/commit/#{event['after']}"
186
229
  end
187
230
 
231
+
188
232
  def gitlab_tag_url event
189
233
  url = git_daemon_style_url(event).sub(/^git/, 'http').sub(/\.git$/, '')
190
234
  "#{url}/commits/#{tag_name(event)}"
191
235
  end
192
236
 
237
+
193
238
  def latest_commit event
194
239
  event['commits'].last['id']
195
240
  end
196
241
 
242
+
197
243
  def tagged_commit event
198
244
  event['ref'] =~ %r{/tags/(.*)$}
199
245
  return $1 # First regex capture
@@ -201,20 +247,29 @@ module KitchenHooks
201
247
 
202
248
  alias_method :tag_name, :tagged_commit
203
249
 
250
+
251
+ def commit_to_master? event
252
+ event['ref'] == 'refs/heads/master'
253
+ end
254
+
255
+
204
256
  def not_deleted? event
205
257
  event['after'] != '0000000000000000000000000000000000000000'
206
258
  end
207
259
 
260
+
208
261
  def commit_to_kitchen? event
209
262
  repo_name(event) == 'kitchen' && not_deleted?(event)
210
263
  end
211
264
 
265
+
212
266
  def tagged_commit_to_cookbook? event
213
267
  cookbook_repo?(event) &&
214
268
  event['ref'] =~ %r{/tags/} &&
215
269
  not_deleted?(event)
216
270
  end
217
271
 
272
+
218
273
  def tagged_commit_to_realm? event
219
274
  tagged_commit_to_cookbook?(event) &&
220
275
  repo_name(event) =~ /^realm_/
@@ -3,7 +3,11 @@ body {
3
3
  }
4
4
 
5
5
  .cd-timeline-img {
6
- background: #75ce66;
6
+ background: #5cb85c;
7
+ }
8
+
9
+ .failure .cd-timeline-img {
10
+ background: #d9534f;
7
11
  }
8
12
 
9
13
  .cd-timeline-content {
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0"?>
2
+ <svg width="512" height="512" xmlns="http://www.w3.org/2000/svg">
3
+
4
+ <g>
5
+ <title>background</title>
6
+ <rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
7
+ </g>
8
+ <g>
9
+ <title>Layer 1</title>
10
+ <path fill="#ffffff" d="m341.328003,50l-170.656006,0l-120.671997,120.671997l0,170.656006l120.671997,120.671997l170.656006,0l120.671997,-120.671997l0,-170.656006l-120.671997,-120.671997zm-84.868011,348.518005c-16.207001,0 -29.345001,-13.139008 -29.345001,-29.346008c0,-16.204987 13.138,-29.34198 29.345001,-29.34198c16.204987,0 29.34201,13.136993 29.34201,29.34198c0,16.207001 -13.136993,29.346008 -29.34201,29.346008zm38.77301,-240.279007c-2.480988,19.779999 -20.700012,116.080002 -26.722992,147.724014c-1.113007,5.85199 -6.229004,10.099976 -12.187012,10.099976l-0.238983,0c-6.169022,0 -11.438019,-4.378998 -12.588013,-10.437988c-6.100006,-32.121002 -24.292999,-128.503998 -26.735001,-147.970993c-2.940002,-23.440994 15.354004,-44.171005 38.977005,-44.171005c23.936005,0 42.475006,21.005005 39.494995,44.755997z" id="error-3-icon"/>
11
+ </g>
12
+ </svg>
data/web/views/app.erb CHANGED
@@ -1,10 +1,9 @@
1
1
  <section id="cd-timeline" class="cd-container">
2
2
  <% database.reverse.each do |(timestamp, entry)| %>
3
3
  <% type = entry[:type] %>
4
- <% event = entry[:event] %>
5
- <% timestamp = timestamp.to_f %>
6
- <% datetime = Time.at(timestamp).iso8601 %>
7
- <div class="cd-timeline-block">
4
+ <% klass = type.sub(' ','-') %>
5
+ <% datetime = Time.at(timestamp.to_f).iso8601 %>
6
+ <div class="cd-timeline-block <%= klass %>">
8
7
  <div class="cd-timeline-img">
9
8
  <% case type %>
10
9
  <% when 'kitchen upload' %>
@@ -13,11 +12,19 @@
13
12
  <img src="/vendor/img/book.svg" alt="Book">
14
13
  <% when 'constraint application' %>
15
14
  <img src="/vendor/img/shield.svg" alt="Shield">
15
+ <% when 'failure' %>
16
+ <img src="/vendor/img/error.svg" alt="Error">
16
17
  <% end %>
17
18
  </div>
18
19
  <div class="cd-timeline-content">
19
20
  <h2><%= type %></h2>
20
- <p><%= notification(event, type) %></p>
21
+ <% if entry[:error] && entry[:event] %>
22
+ <p><%= notification entry %>. Triggered when <%= generic_details(entry[:event]) %></p>
23
+ <% elsif entry[:error] # Failed before event generated %>
24
+ <p><%= notification entry %></p>
25
+ <% else %>
26
+ <p><%= notification entry %> by pushing <%= push_details(entry[:event]) %></p>
27
+ <% end %>
21
28
  <span class="cd-date"><time datetime="<%= datetime %>" pubdate="pubdate" class="time-ago" title="<%= datetime %>"><%= datetime %></time></span>
22
29
  </div>
23
30
  </div>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kitchen_hooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Wong
@@ -167,6 +167,7 @@ files:
167
167
  - web/public/vendor/img/book.svg
168
168
  - web/public/vendor/img/cd-icon.svg
169
169
  - web/public/vendor/img/cutlery.svg
170
+ - web/public/vendor/img/error.svg
170
171
  - web/public/vendor/img/shield.svg
171
172
  - web/public/vendor/js/bootstrap-v3.3.0.js
172
173
  - web/public/vendor/js/jquery-timeago-v1.4.1.js