kitchen_hooks 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/Readme.md +2 -3
- data/VERSION +1 -1
- data/etc/commit.json +2 -42
- data/etc/config.json +2 -8
- data/lib/kitchen_hooks/app.rb +29 -19
- data/lib/kitchen_hooks/helpers.rb +64 -9
- data/web/app/style/kitchen_hooks.css +5 -1
- data/web/public/vendor/img/error.svg +12 -0
- data/web/views/app.erb +12 -5
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdb2a72a6956b35d41937cde0cee3be69ad832f2
|
4
|
+
data.tar.gz: 8f033c77c713dee2abe2ef435b7ef2d01645bdc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ab833ecddff610020cec29609480d136514a069425a16ab9daaa941c9de9453e5fc5b380a5a5b9bbe72b9a62b5ccc85ce44431f7c48ee9aaa3b42d3ea810dd6
|
7
|
+
data.tar.gz: cbea2a4672b06e4e096e335e7e2efd2220944bc59e1504f6ddd774a81d622cef6993029e76cade61722f43d5999c9725f4fd1ac44d148dc7ff42e60ba57425ce
|
data/Gemfile.lock
CHANGED
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.
|
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
|
9
|
+
"url": "git@git.bluejeansnet.com:chef/kitchen.git",
|
10
10
|
"description": "",
|
11
|
-
"homepage": "http://git.bluejeansnet.com/kitchen
|
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
data/lib/kitchen_hooks/app.rb
CHANGED
@@ -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
|
79
|
-
hipchat notification(
|
78
|
+
def notify entry
|
79
|
+
hipchat notification(entry)
|
80
80
|
end
|
81
81
|
|
82
|
-
|
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
|
-
|
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
|
-
|
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+/ #
|
100
|
-
perform_cookbook_upload(event, knives)
|
101
|
-
|
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_/ #
|
106
|
-
perform_constraint_application(event, knives)
|
107
|
-
|
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
|
-
|
16
|
-
|
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
|
-
|
153
|
-
|
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
|
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_/
|
@@ -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
|
-
<%
|
5
|
-
<%
|
6
|
-
|
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
|
-
|
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.
|
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
|