build-buddy 1.11.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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