build-buddy 1.11.0 → 1.12.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.
@@ -9,24 +9,24 @@ module BuildBuddy
9
9
  include Celluloid
10
10
  include Celluloid::Internals::Logger
11
11
 
12
- attr_reader :active_build
13
-
14
12
  def initialize()
15
- @build_queue = Queue.new
16
- @done_queue = Queue.new
13
+ @build_queue = []
14
+ @done_queue = []
17
15
  @build_timer = nil
16
+ @active_build = nil
18
17
  end
19
18
 
20
19
  def queue_a_build(build_data)
21
- @build_queue.push(build_data)
20
+ @build_queue.unshift(build_data)
22
21
 
23
22
  case build_data.type
24
- when :pull_request
25
- Celluloid::Actor[:gitter].async.set_status(
26
- build_data.repo_full_name, build_data.repo_sha, :pending, "This build is in the queue")
27
- info "Pull request build queued"
28
- when :branch
29
- info "'#{build_data.branch}' branch build queued"
23
+ when :pull_request
24
+ Celluloid::Actor[:gitter].async.set_status(
25
+ build_data.repo_full_name, build_data.repo_sha, :pending, "Build is queued",
26
+ build_data.server_log_uri)
27
+ info "Pull request build queued"
28
+ when :branch
29
+ info "'#{build_data.branch}' branch build queued"
30
30
  end
31
31
 
32
32
  if @build_timer.nil?
@@ -39,14 +39,29 @@ module BuildBuddy
39
39
  @build_queue.length
40
40
  end
41
41
 
42
- def stop_build
43
- # Centralize stopping bulids here in case we allow multiple active builders in future
44
- unless @active_build.nil?
42
+ def active_build
43
+ @active_build
44
+ end
45
+
46
+ def stop_build(id, slack_user_name)
47
+ # Centralize stopping builds here
48
+ if @active_build != nil and @active_build._id != id
49
+ @active_build.stopped_by = slack_user_name
45
50
  Celluloid::Actor[:builder].stop_build
46
51
  true
47
- else
48
- false
49
52
  end
53
+
54
+ # Look for the build in the queue
55
+ i = @build_queue.find { |build_data| build_data._id == id}
56
+ if i != nil
57
+ build_data = @build_queue[i]
58
+ @build_queue.delete_at(i)
59
+ build_data.stopped_by = slack_user_name
60
+ Celluloid::Actor[:recorder].async.record_build_data(build_data)
61
+ true
62
+ end
63
+
64
+ false
50
65
  end
51
66
 
52
67
  def on_build_interval
@@ -60,10 +75,6 @@ module BuildBuddy
60
75
  build_data = @build_queue.pop()
61
76
  @active_build = build_data
62
77
  Celluloid::Actor[:recorder].async.record_build_data(build_data)
63
- if build_data.type == :pull_request
64
- Celluloid::Actor[:gitter].async.set_status(
65
- build_data.repo_full_name, build_data.repo_sha, :pending, "This build has started")
66
- end
67
78
  Celluloid::Actor[:builder].async.start_build(build_data)
68
79
  else # Otherwise, stop the timer until we get a build queued.
69
80
  @build_timer.cancel
@@ -82,7 +93,11 @@ module BuildBuddy
82
93
 
83
94
  def on_build_completed(build_data)
84
95
  @active_build = nil
85
- @done_queue.push(build_data)
96
+ @done_queue.unshift(build_data)
97
+ end
98
+
99
+ def get_build_queue
100
+ @build_queue.clone
86
101
  end
87
102
  end
88
103
  end
@@ -30,40 +30,51 @@ module BuildBuddy
30
30
  action = payload['action']
31
31
  pull_request = payload['pull_request']
32
32
 
33
+ info "Got pull request '#{action}' from #{forwarded_for(request)}"
33
34
  case action
34
35
  when 'opened', 'reopened', 'synchronize'
35
36
  build_data = BuildData.new(
36
37
  :type => :pull_request,
37
38
  :pull_request => pull_request['number'],
38
- :flags => [],
39
+ :flags => {},
39
40
  :repo_sha => pull_request['head']['sha'],
40
41
  :repo_full_name => pull_request['base']['repo']['full_name'])
41
42
  info "Got #{action} pull request #{build_data.pull_request} from GitHub"
42
43
  Celluloid::Actor[:scheduler].queue_a_build(build_data)
43
44
  request.respond 200, "Building"
45
+ return
44
46
  else
45
47
  request.respond 200, "Ignoring"
48
+ return
46
49
  end
47
50
  end
48
51
  when 'ping'
52
+ info "Got pinged from #{forwarded_for(request)}"
49
53
  request.respond 200, "Running"
54
+ return
50
55
  else
51
56
  request.respond 404, "Event not supported"
57
+ return
52
58
  end
53
59
  else
54
60
  request.respond 404, "Method not supported"
61
+ return
55
62
  end
56
- when /^\/log\/([0-9a-z]*)$/
63
+ when /^\/log\/([0-9abcdef]{24})$/
57
64
  case request.method
58
65
  when 'GET'
59
66
  build_data = Celluloid::Actor[:recorder].get_build_data($1)
60
- if build_data.nil? or build_data.log_filename.nil? or !File.exist?(build_data.log_filename)
61
- sleep 1
67
+ if build_data.nil?
62
68
  request.respond 404, "Not found"
69
+ return
63
70
  end
64
- log_contents = 'Log file has been deleted.'
65
- File.open(build_data.log_filename) do |io|
66
- log_contents = io.read
71
+ log_file_name = build_data.log_file_name
72
+ if log_file_name.nil? or !File.exist?(log_file_name)
73
+ log_contents = 'Log file has been deleted.'
74
+ else
75
+ File.open(log_file_name) do |io|
76
+ log_contents = io.read
77
+ end
67
78
  end
68
79
  html = %Q(
69
80
  <!doctype html>
@@ -92,15 +103,97 @@ module BuildBuddy
92
103
  </html>
93
104
  )
94
105
  request.respond 200, html
106
+ return
95
107
  else
96
108
  request.respond 404, "Method not supported"
109
+ return
110
+ end
111
+ when Regexp.new("^/hud/#{Config.hud_secret_token}/(index\\.html|[a-z_]+\\.png)$")
112
+ if request.method != 'GET'
113
+ request.response 404, "Method not supported"
114
+ return
115
+ end
116
+
117
+ if $1 == "index.html"
118
+ html = %q(
119
+ <!doctype html>
120
+ <html lang="en">
121
+ <head>
122
+ <title>Build Metrics</title>
123
+ <meta charset="utf-8">
124
+ <meta name="viewport" content="width=device-width, initial-scale=1">
125
+ <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
126
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/css/bootstrap.min.css" integrity="sha384-MIwDKRSSImVFAZCVLtU0LMDdON6KVCrZHyVQQj6e8wIEJkW4tvwqXrbMIya1vriY" crossorigin="anonymous">
127
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.3/js/bootstrap.min.js" integrity="sha384-ux8v3A6CPtOTqOzMKiuo3d/DomGaaClxFYdCu2HPMBEkf6x2xiDyJ7gkXU0MWwaD" crossorigin="anonymous"></script>
128
+ </head>
129
+ <body>
130
+
131
+ <div class="jumbotron text-center">
132
+ <h1>Build Metrics</h1>
133
+ <p>Build server data</p>
134
+ </div>
135
+
136
+ <div class="container-fluid">
137
+ <div class="row">
138
+ <div class="col-sm-4">
139
+ <img class="img-fluid" src="code_coverage.png" alt="Code Coverage">
140
+ </div>
141
+ <div class="col-sm-4">
142
+ <img class="img-fluid" src="build_times.png" alt="Build Times">
143
+ </div>
144
+ <div class="col-sm-4">
145
+ <img class="img-fluid" src="daily_builds.png" alt="Daily Builds">
146
+ </div>
147
+ </div>
148
+ <div class="row">
149
+ <div class="col-sm-4">
150
+ <img class="img-fluid" src="lines_of_code.png" alt="Lines of Code">
151
+ </div>
152
+ <div class="col-sm-4">
153
+ <img class="img-fluid" src="localization_data.png" alt="Localization Data">
154
+ </div>
155
+ <div class="col-sm-4">
156
+ <img class="img-fluid" src="warning_count.png" alt="Warning Count">
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ </body>
162
+ </html>
163
+ )
164
+ request.respond 200, html
165
+ return
166
+ elsif
167
+ png_file_name = File.join(Config.hud_image_dir, $1)
168
+
169
+ if File.exist?(png_file_name)
170
+ request.respond Reel::Response.new(200, {"content-type" => "image/png"}, File.open(png_file_name))
171
+ return
172
+ else
173
+ request.response 404, "Image not found"
174
+ return
175
+ end
176
+ else
177
+ request.response 404, "Path not found"
178
+ return
97
179
  end
98
180
  else
99
- request.respond 404, "Path not found"
181
+ request.respond 404, "Path not found"
182
+ return
100
183
  end
101
184
  end
102
185
  end
103
186
 
187
+ def forwarded_for(request)
188
+ addr = request.headers["X-Forwarded-For"]
189
+
190
+ if addr.start_with?("192.30.252")
191
+ return "github.com (#{addr})"
192
+ else
193
+ return "unknown (#{addr})"
194
+ end
195
+ end
196
+
104
197
  def verify_signature(payload_body, gh_signature)
105
198
  signature = 'sha1=' + OpenSSL::HMAC.hexdigest(
106
199
  OpenSSL::Digest.new('sha1'), Config.github_webhook_secret_token, payload_body)
@@ -10,7 +10,7 @@ module BuildBuddy
10
10
  include Celluloid::Internals::Logger
11
11
 
12
12
  def initialize()
13
- @rt_client = Slack::RealTime::Client.new
13
+ @rt_client = Slack::RealTime::Client.new(websocket_ping: 3)
14
14
  @rt_client.on :hello do
15
15
  self.on_slack_hello()
16
16
  end
@@ -21,29 +21,36 @@ module BuildBuddy
21
21
  sub_error = error['error']
22
22
  error "Slack error #{sub_error['code']} - #{sub_error['msg']}}"
23
23
  end
24
- @rt_client.on :close do |event|
25
- raise "Slack connection was closed"
24
+ @rt_client.on :closed do |event|
25
+ info "Slack connection was closed"
26
+ self.terminate
26
27
  end
27
- @rt_client.start_async
28
- @build_slack_channel = nil
29
- @test_slack_channel = nil
28
+
29
+ begin
30
+ @rt_client.start_async
31
+ rescue
32
+ info "Unable to connect to Slack"
33
+ self.terminate
34
+ end
35
+
36
+ @build_channel_id = nil
30
37
  end
31
38
 
32
- def self.get_build_flags message
39
+ def self.extract_build_flags(message)
33
40
  flags = []
34
41
  unless message.nil?
35
42
  message.split(',').each do |s|
36
- flags.push(s.lstrip.rstrip.gsub(' ', '_').to_sym)
43
+ flags.push(s.lstrip.rstrip.downcase.gsub(' ', '_').to_sym)
37
44
  end
38
45
  end
39
46
  flags
40
47
  end
41
48
 
42
- def do_build(message, from_slack_channel, slack_user_name)
49
+ def do_build(message, is_from_slack_channel, slack_user_name)
43
50
  response = ''
44
51
  sender_is_a_builder = (Config.slack_builders.nil? ? true : Config.slack_builders.include?('@' + slack_user_name))
45
52
  unless sender_is_a_builder
46
- if from_slack_channel
53
+ if is_from_slack_channel
47
54
  response = "I'm sorry @#{slack_user_name} you are not on my list of allowed builders."
48
55
  else
49
56
  response = "I'm sorry but you are not on my list of allowed builders."
@@ -53,15 +60,16 @@ module BuildBuddy
53
60
 
54
61
  case message
55
62
  when /^master(?: with )?(?<flags>.*)?/i
56
- flags = Slacker.get_build_flags($~[:flags])
63
+ flags = Slacker.extract_build_flags($~[:flags])
57
64
  response = "OK, I've queued a build of the `master` branch."
58
65
  scheduler.queue_a_build(BuildData.new(
59
66
  :type => :branch,
60
67
  :branch => 'master',
61
68
  :flags => flags,
62
- :repo_full_name => Config.github_webhook_repo_full_name))
69
+ :repo_full_name => Config.github_webhook_repo_full_name,
70
+ :started_by => slack_user_name))
63
71
  when /^(?<version>v\d+\.\d+)(?: with )?(?<flags>.*)?/
64
- flags = Slacker.get_build_flags($~[:flags])
72
+ flags = Slacker.extract_build_flags($~[:flags])
65
73
  version = $~[:version]
66
74
  if Config.allowed_build_branches.include?(version)
67
75
  response = "OK, I've queued a build of the `#{version}` branch."
@@ -69,101 +77,114 @@ module BuildBuddy
69
77
  :type => :branch,
70
78
  :branch => version,
71
79
  :flags => flags,
72
- :repo_full_name => Config.github_webhook_repo_full_name))
80
+ :repo_full_name => Config.github_webhook_repo_full_name,
81
+ :started_by => slack_user_name))
73
82
  else
74
83
  response = "I'm sorry, I am not allowed to build the `#{version}` branch"
75
84
  end
76
85
  else
77
- response = "Sorry#{from_slack_channel ? " <@#{data['user']}>" : ""}, I'm not sure if you want do a `master` or release branch build"
86
+ response = "Sorry#{is_from_slack_channel ? ' @' + slack_user_name : ''}, I'm not sure if you want do a `master` or release branch build"
78
87
  end
79
88
  end
80
89
  response
81
90
  end
82
91
 
83
- def do_stop
84
- scheduler = Celluloid::Actor[:scheduler]
85
-
86
- if scheduler.stop_build
87
- response = "OK, I stopped the currently running build."
88
- else
89
- response = "There is no build running to stop."
90
- end
91
-
92
- response
93
- end
94
-
95
- def do_status
96
- scheduler = Celluloid::Actor[:scheduler]
97
- build_data = scheduler.active_build
98
- queue_length = scheduler.queue_length
92
+ def do_stop(message, is_from_slack_channel, slack_user_name)
99
93
  response = ''
100
- if build_data.nil?
101
- response = "There is currently no build running"
102
- if queue_length == 0
103
- response += " and no builds in the queue."
94
+ m = message.match(/[0-9abcdef]{24}/)
95
+
96
+ unless m.nil?
97
+ if Celluloid::Actor[:scheduler].stop_build(BSON::ObjectId.from_string(m[0]), slack_user_name)
98
+ response = "OK#{is_from_slack_channel ? ' @' + slack_user_name : ''}, I stopped the build with identifier #{m[0]}."
104
99
  else
105
- response += " and #{queue_length} in the queue."
100
+ response = "I could not find a queued or active build with that identifier"
106
101
  end
107
102
  else
108
- case build_data.type
109
- when :pull_request
110
- response = "There is a pull request build in progress for https://github.com/#{build_data.repo_full_name}/pull/#{build_data.pull_request}."
111
- when :branch
112
- response = "There is a build of the `#{build_data.branch}` branch of https://github.com/#{build_data.repo_full_name} in progress."
113
- end
114
- if queue_length == 1
115
- response += " There is one build in the queue."
116
- elsif queue_length > 1
117
- response += " There are #{queue_length} builds in the queue."
118
- end
103
+ response = "You must specify the 24 digit hexadecimal build identifier. It can be an active build or a build in the queue."
119
104
  end
105
+
120
106
  response
121
107
  end
122
108
 
123
- def do_help from_slack_channel
124
- # TODO: The repository should be a link to GitHub
125
- %Q(Hello#{from_slack_channel ? " <@#{data['user']}>" : ""}, I'm the *@#{@rt_client.self['name']}* build bot version #{BuildBuddy::VERSION}! I look after 3 types of build: pull request, master and release.
109
+ def do_help is_from_slack_channel
110
+ %Q(Hello#{is_from_slack_channel ? " <@#{data['user']}>" : ""}, I'm the *@#{@rt_client.self['name']}* build bot version #{BuildBuddy::VERSION}!
126
111
 
127
- A pull request build happens when you make a pull request to the *#{Config.github_webhook_repo_full_name}* GitHub repository.
112
+ I understand types of build - pull requests and branch. A pull request build happens when you make a pull request to the https://github.com/#{Config.github_webhook_repo_full_name} GitHub repository.
128
113
 
129
- I can run builds of the master branch if you say `build master`. I can do builds of release branches, e.g. `build v2.3` but only for those branches that I am allowed to build.
114
+ For branch builds, I can run builds of the master branch if you say `build master`. I can do builds of release branches, e.g. `build v2.3` but only for those branches that I am allowed to build in by configuration file.
130
115
 
131
- I can stop any running build if you ask me to `stop build`, even pull request builds. I am configured to let the *#{Config.slack_build_channel}* channel know if master or release builds are stopped.
116
+ I can stop any running build if you ask me to `stop build X`, even pull request builds if you give the id X from the `show status` or `show queue` command. I am configured to let the *#{Config.slack_build_channel}* channel know if builds are stopped.
132
117
 
133
- You can also ask me for `status` and I'll tell you what's being built.
118
+ I have lots of `show` commands:
134
119
 
135
- Ask me `what happened` to get a list of recent builds and log files and `what options` to see the list of options for running builds.
120
+ - `show status` and I'll tell you what my status is
121
+ - `show queue` and I will show you what is in the queue
122
+ - `show options` to a see a list of build options
123
+ - `show builds` to see the last 5 builds or `show last N builds` to see a list of the last N builds
124
+
125
+ Build metrics and charts are available at #{Config.server_base_uri}/hud/#{Config.hud_secret_token}/index.html
136
126
  )
137
127
  end
138
128
 
139
- def do_what(question)
140
- question = question.lstrip.rstrip
141
-
142
- case question
143
- when /happened/
144
- case question
145
- when /([0-9]+)/
146
- limit = $1.to_i
147
- else
148
- limit = 5
149
- end
129
+ def do_show(request)
130
+ request = request.lstrip.rstrip
150
131
 
151
- recorder = Celluloid::Actor[:recorder]
152
- build_datas = recorder.get_build_data_history(limit)
132
+ case request
133
+ when /builds/
134
+ limit = 5
135
+ m = request.match(/last ([0-9]+)/)
136
+ limit = m[1].to_i unless m.nil?
137
+ build_datas = Celluloid::Actor[:recorder].get_build_data_history(limit)
153
138
 
154
139
  if build_datas.count == 0
155
140
  response = "No builds have performed yet"
156
141
  else
157
- response = "Here are the last #{build_datas.count} builds:\n"
142
+ response = ''
143
+ if build_datas.count < limit
144
+ response += "There have only been #{build_datas.count} builds:\n"
145
+ else
146
+ response += "Here are the last #{build_datas.count} builds:\n"
147
+ end
158
148
  build_datas.each do |build_data|
159
149
  response += "A "
160
150
  response += case build_data.type
161
151
  when :branch
162
152
  "`#{build_data.branch}` branch build"
163
153
  when :pull_request
164
- "pull request `#{build_data.pull_request}` build"
154
+ "pull request build #{build_data.pull_request_uri}"
165
155
  end
166
- response += " at #{build_data.start_time.to_s}. #{Config.server_base_uri + '/log/' + build_data._id.to_s}\n"
156
+ response += " at #{build_data.start_time.to_s}. #{Config.server_base_uri + '/log/' + build_data._id.to_s}"
157
+ response += ' ' + build_data.status_verb
158
+ response += "\n"
159
+ end
160
+ end
161
+ when /status/
162
+ scheduler = Celluloid::Actor[:scheduler]
163
+ build_data = scheduler.active_build
164
+ queue_length = scheduler.queue_length
165
+ response = ''
166
+ if build_data.nil?
167
+ response = "There is currently no build running"
168
+ if queue_length == 0
169
+ response += " and no builds in the queue."
170
+ else
171
+ response += " and #{queue_length} in the queue."
172
+ end
173
+ else
174
+ case build_data.type
175
+ when :pull_request
176
+ response = "There is a pull request build in progress for https://github.com/#{build_data.repo_full_name}/pull/#{build_data.pull_request} (#{build_data._id.to_s})"
177
+ when :branch
178
+ response = "There is a build of the `#{build_data.branch}` branch of https://github.com/#{build_data.repo_full_name} in progress (#{build_data._id.to_s})"
179
+ end
180
+ unless build_data.started_by.nil?
181
+ response += build_data.started_by
182
+ end
183
+ response += '.'
184
+ if queue_length == 1
185
+ response += " There is one build in the queue."
186
+ elsif queue_length > 1
187
+ response += " There are #{queue_length} builds in the queue."
167
188
  end
168
189
  end
169
190
  when /options/
@@ -171,6 +192,27 @@ Ask me `what happened` to get a list of recent builds and log files and `what op
171
192
  - *test channel* to have notifications go to the test channel
172
193
  - *no upload* to not have the build upload
173
194
  )
195
+ when /queue/
196
+ response = ''
197
+ build_datas = Celluloid::Actor[:scheduler].get_build_queue
198
+ if build_datas.count == 0
199
+ response = "There are no builds in the queue."
200
+ else
201
+ build_datas.each { |build_data|
202
+ response += "A "
203
+ response += case build_data.type
204
+ when :branch
205
+ "`#{build_data.branch}` branch build"
206
+ when :pull_request
207
+ "pull request build #{build_data.pull_request_uri}"
208
+ end
209
+ unless build_data.started_by.nil?
210
+ response += " by #{build_data.started_by}"
211
+ end
212
+ response += " (#{build_data._id.to_s})"
213
+ response += "\n"
214
+ }
215
+ end
174
216
  else
175
217
  response = "I'm not sure what to say..."
176
218
  end
@@ -189,24 +231,21 @@ Ask me `what happened` to get a list of recent builds and log files and `what op
189
231
  map_channel_name_to_id = @rt_client.channels.map {|id, channel| [channel.name, id]}.to_h
190
232
  map_group_name_to_id = @rt_client.groups.map {|id, group| [group.name, id]}.to_h
191
233
 
192
- @build_slack_channel = Slacker.get_channel_id(Config.slack_build_channel, map_channel_name_to_id, map_group_name_to_id)
234
+ @build_channel_id = Slacker.get_channel_id(Config.slack_build_channel, map_channel_name_to_id, map_group_name_to_id)
193
235
 
194
- if @build_slack_channel.nil?
236
+ if @build_channel_id.nil?
195
237
  error "Unable to identify the build slack channel #{channel}"
196
238
  else
197
- info "Slack build notification channel is #{@build_slack_channel} (#{Config.slack_build_channel})"
198
- end
199
-
200
- @test_slack_channel = Slacker.get_channel_id(Config.slack_test_channel, map_channel_name_to_id, map_group_name_to_id)
201
-
202
- if @test_slack_channel.nil?
203
- error "Unable to identify the test slack channel #{channel}"
204
- else
205
- info "Slack test notification channel is #{@test_slack_channel} (#{Config.slack_test_channel})"
239
+ info "Slack build notification channel is #{@build_channel_id} (#{Config.slack_build_channel})"
206
240
  end
207
241
  end
208
242
 
209
243
  def on_slack_data(data)
244
+ # Don't respond to ephemeral messages from Slack
245
+ if data['is_ephemeral']
246
+ return
247
+ end
248
+
210
249
  message = data['text']
211
250
 
212
251
  # If no message, then there's nothing to do
@@ -238,65 +277,50 @@ Ask me `what happened` to get a list of recent builds and log files and `what op
238
277
  end
239
278
 
240
279
  c = data['channel'][0]
241
- from_slack_channel = (c == 'C' || c == 'G')
280
+ is_from_slack_channel = (c == 'C' || c == 'G')
242
281
 
243
- # Don't respond if the message is to a channel and our name is not in the message
244
- if from_slack_channel and !message.match(@rt_client.self['id'])
282
+ # Don't respond if the message is from a channel and our name is not in the message
283
+ if is_from_slack_channel and !message.match(@rt_client.self['id'])
245
284
  return
246
285
  end
247
286
 
248
287
  response = case message
249
288
  when /build (.*)/i
250
- do_build $1, from_slack_channel, slack_user_name
251
- when /status/i
252
- do_status
253
- when /what(.*)/
254
- do_what $1
255
- when /help/i, /what can/i
256
- do_help from_slack_channel
257
- when /stop/i
258
- do_stop
289
+ do_build $1, is_from_slack_channel, slack_user_name
290
+ when /show(.*)/
291
+ do_show $1
292
+ when /help/i
293
+ do_help is_from_slack_channel
294
+ when /stop(?: build)(.*)/i
295
+ do_stop $1, is_from_slack_channel, slack_user_name
259
296
  else
260
- "Sorry#{from_slack_channel ? " <@#{data['user']}>" : ""}, I'm not sure how to respond."
297
+ "Sorry#{is_from_slack_channel ? ' ' + slack_user_name : ''}, I'm not sure how to respond."
261
298
  end
262
299
  @rt_client.message channel: data['channel'], text: response
263
300
  info "Slack message '#{message}' from #{data['channel']} handled"
264
301
  end
265
302
 
266
303
  def notify_channel(build_data)
267
- status_message = build_data.termination_type == :killed ? "was stopped" : build_data.exit_code != 0 ? "failed" : "succeeded"
268
- status_message += '. '
269
- log_url = Config.server_base_uri + '/log/' + build_data._id.to_s
270
-
271
- if build_data.type == :pull_request
272
- message = "Build #{status_message}"
273
- git_state = (build_data.termination_type == :killed ? :failure : build_data.exit_code != 0 ? :error : :success)
274
- Celluloid::Actor[:gitter].async.set_status(build_data.repo_full_name, build_data.repo_sha, git_state, message, log_url)
275
- info "Pull request build #{status_message}"
304
+ status_verb = build_data.status_verb
305
+
306
+ if build_data.type == :branch
307
+ message = "A `#{build_data.branch}` branch build #{status_verb}"
308
+ info "Branch build #{status_verb}"
276
309
  else
277
- status_message += "Log file at #{log_url}."
278
- if build_data.type == :branch
279
- message = "A build of the `#{build_data.branch}` branch #{status_message}"
280
- info "Release branch build #{status_message}"
281
- end
310
+ message = "Pull request `#{build_data.pull_request}` #{status_verb}"
311
+ info "Pull request build #{status_verb}"
312
+ end
282
313
 
283
- # See https://api.slack.com/docs/attachments for more information about formatting Slack attachments
284
- attach = [
285
- :title => build_data.type == :pull_request ? "Pull Request" : "Branch Build",
286
- :text => message,
287
- :color => build_data.termination_type == :killed ? :warning : build_data.exit_code != 0 ? :danger : :good,
288
- ]
314
+ message += ". Log file at #{build_data.server_log_uri}"
289
315
 
290
- if build_data.flags.include?(:test_channel)
291
- unless @test_slack_channel.nil?
292
- @rt_client.message(channel: @test_slack_channel, text: message, attachments: attach)
293
- end
294
- else
295
- unless @build_slack_channel.nil?
296
- @rt_client.message(channel: @build_slack_channel, text: message, attachments: attach)
297
- end
298
- end
299
- end
316
+ # See https://api.slack.com/docs/attachments for more information about formatting Slack attachments
317
+ attach = [
318
+ :title => build_data.type == :pull_request ? "Pull Request" : "Branch Build",
319
+ :text => message,
320
+ :color => build_data.termination_type == :killed ? :warning : build_data.exit_code != 0 ? :danger : :good,
321
+ ]
322
+
323
+ @rt_client.message(channel: @build_channel_id, text: message, attachments: attach) unless @build_channel_id.nil?
300
324
  end
301
325
  end
302
326
  end