build-buddy 1.4.5 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e77e4f6935ead118d2908d44a69515dee524b9eb
4
- data.tar.gz: 13dd9ad73465c2069b9922bc62e26718161ff949
3
+ metadata.gz: bef0733301b651a89087ca1ff896ca3a94b71770
4
+ data.tar.gz: 41362a034b27006f47ac7523c1c0679e908c8e20
5
5
  SHA512:
6
- metadata.gz: 02b0a753a08207047d8413ca2335c3845735e3db8d93367ff52daf45a71d4ea1293915c49699cd32416fe90a3d3adb1abfe6763e8d31e75563ff719329c12861
7
- data.tar.gz: f6d6b31b9231c8ae69a55ce6e87775460dacde77741e6b622b099f132298c98b956a00737702b32e3886f76b88063c3423273a2442075ceb2a715b5e0a6690fb
6
+ metadata.gz: 45de0b0813df8f847226008136eb741e73b1ae172f86b8992b83d6ceb671aeb661597039b14aa79fcb39c976108eedddc2c2e4fede13b1ad46f9289c1c7ca79d
7
+ data.tar.gz: ef301af974c69cad37e50d230b799c587aab6b583aa7ee73829f3863278f3da23cdd1971de6e75f307462cde3a66cb0faa1387e30180605d46cccde5523f92b4
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require 'bundler/setup'
5
4
  require 'celluloid/current'
6
5
  require 'celluloid/supervision'
7
6
  require 'celluloid/supervision/container'
@@ -45,6 +44,7 @@ module BuildBuddy
45
44
  Gitter.supervise as: :gitter
46
45
  Scheduler.supervise as: :scheduler
47
46
  Server.supervise as: :server
47
+ Recorder.supervise as: :recorder
48
48
 
49
49
  begin
50
50
  sleep
@@ -5,8 +5,9 @@ require 'build_buddy/builder'
5
5
  require 'build_buddy/watcher'
6
6
  require 'build_buddy/scheduler'
7
7
  require 'build_buddy/server'
8
+ require 'build_buddy/recorder'
8
9
  require 'build_buddy/build_data'
9
10
 
10
11
  module BuildBuddy
11
- VERSION = "1.4.5"
12
+ VERSION = "1.6.0"
12
13
  end
@@ -1,5 +1,6 @@
1
1
  module BuildBuddy
2
2
  class BuildData
3
+ attr_accessor :_id # Mongo ID
3
4
  attr_accessor :build_type # one of :master, :release or :pull_request
4
5
  attr_accessor :repo_full_name
5
6
  attr_accessor :build_version
@@ -12,12 +13,20 @@ module BuildBuddy
12
13
  attr_accessor :end_time
13
14
  attr_accessor :build_log_filename
14
15
 
15
- def initialize(build_type, args)
16
- @build_type = build_type
17
- @repo_full_name = args[:repo_full_name]
18
- @repo_sha = args[:repo_sha]
19
- @build_version = args[:build_version]
20
- @pull_request = args[:pull_request]
16
+ def initialize(args)
17
+ args.each do |key, value|
18
+ setter = self.method((key.to_s + '=').to_sym)
19
+
20
+ unless setter.nil?
21
+ setter.call(value)
22
+ end
23
+ end
24
+ end
25
+
26
+ def to_h
27
+ hash = {}
28
+ instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
29
+ hash
21
30
  end
22
31
  end
23
32
  end
@@ -3,7 +3,6 @@ module BuildBuddy
3
3
  extend self
4
4
 
5
5
  attr_accessor :github_webhook_port
6
- attr_accessor :github_webhook_path
7
6
  attr_accessor :github_webhook_secret_token
8
7
  attr_accessor :github_webhook_repo_full_name
9
8
  attr_accessor :github_api_token
@@ -18,12 +17,12 @@ module BuildBuddy
18
17
  attr_accessor :release_build_script
19
18
  attr_accessor :valid_release_versions
20
19
  attr_accessor :kill_build_after_mins
20
+ attr_accessor :server_base_uri
21
21
  end
22
22
 
23
23
  class << self
24
24
  def configure
25
25
  Config.github_webhook_port = 4567
26
- Config.github_webhook_path = '/webhook'
27
26
  Config.kill_build_after_mins = 30
28
27
  block_given? ? yield(Config) : Config
29
28
  end
@@ -19,4 +19,4 @@ module BuildBuddy
19
19
  repo_full_name, repo_sha, status.to_s, { :description => description.length > 140 ? "#{description[0..136]}..." : description})
20
20
  end
21
21
  end
22
- end
22
+ end
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'celluloid'
4
+ require 'mongo'
5
+ require_relative './config.rb'
6
+
7
+ module BuildBuddy
8
+ class Recorder
9
+ include Celluloid
10
+ include Celluloid::Internals::Logger
11
+
12
+ def initialize()
13
+ @mongo ||= Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'build-buddy')
14
+ info "Connected to MongoDB"
15
+ end
16
+
17
+ def record_build_data(build_data)
18
+ builds = @mongo[:builds]
19
+ result = builds.insert_one(build_data.to_h)
20
+ build_data._id = result.inserted_id
21
+ end
22
+
23
+ def update_build_data(build_data)
24
+ unless build_data._id.nil?
25
+ builds = @mongo[:builds]
26
+ builds.replace_one({ :_id => build_data._id }, build_data.to_h)
27
+ end
28
+ end
29
+
30
+ def get_build_data(id)
31
+ builds = @mongo[:builds]
32
+ document = builds.find({ :_id => BSON::ObjectId.from_string(id) }, { :limit => 1 }).first
33
+ if document.nil?
34
+ return nil
35
+ end
36
+ BuildData.new(document)
37
+ end
38
+ end
39
+ end
@@ -56,6 +56,7 @@ module BuildBuddy
56
56
  if @build_queue.length > 0
57
57
  build_data = @build_queue.pop()
58
58
  @active_build = build_data
59
+ Celluloid::Actor[:recorder].async.record_build_data(build_data)
59
60
  if build_data.build_type == :pull_request
60
61
  Celluloid::Actor[:gitter].async.set_status(
61
62
  build_data.repo_full_name, build_data.repo_sha, :pending, "This build has started")
@@ -64,6 +65,7 @@ module BuildBuddy
64
65
  elsif @done_queue.length > 0
65
66
  build_data = @done_queue.pop
66
67
  status_message = build_data.termination_type == :killed ? "was stopped" : build_data.exit_code != 0 ? "failed" : "succeeded"
68
+ status_message += '. '
67
69
 
68
70
  if build_data.build_type == :pull_request
69
71
  message = "The buddy build #{status_message}"
@@ -73,9 +75,7 @@ module BuildBuddy
73
75
  message)
74
76
  info "Pull request build #{status_message}"
75
77
  else
76
- if build_data.exit_code != 0
77
- status_message += ". Exit code #{build_data.exit_code}, log file `#{build_data.build_log_filename}`."
78
- end
78
+ status_message += "Log file at #{Config.server_base_uri + '/log/' + build_data._id.to_s}."
79
79
  if build_data.build_type == :master
80
80
  message = "A build of the `master` branch #{status_message}"
81
81
  info "`master` branch build #{status_message}"
@@ -85,6 +85,7 @@ module BuildBuddy
85
85
  end
86
86
  Celluloid::Actor[:slacker].async.notify_channel(message)
87
87
  end
88
+ Celluloid::Actor[:recorder].async.update_build_data(build_data)
88
89
  else
89
90
  @build_timer.cancel
90
91
  @build_timer = nil
@@ -92,7 +93,8 @@ module BuildBuddy
92
93
  end
93
94
  else
94
95
  # Make sure that the build has not run too long and kill if necessary
95
- if Time.now.utc - @active_build.start_time > Config.kill_build_after_mins * 60
96
+ start_time = @active_build.start_time
97
+ if !start_time.nil? and Time.now.utc - start_time > Config.kill_build_after_mins * 60
96
98
  Celluloid::Actor[:builder].async.stop_build()
97
99
  end
98
100
  end
@@ -16,10 +16,10 @@ module BuildBuddy
16
16
 
17
17
  def on_connection(connection)
18
18
  connection.each_request do |request|
19
- case request.method
20
- when 'POST'
21
- case request.path
22
- when Config.github_webhook_path
19
+ case request.path
20
+ when '/webhook'
21
+ case request.method
22
+ when 'POST'
23
23
  case request.headers["X-GitHub-Event"]
24
24
  when 'pull_request'
25
25
  payload_text = request.body.to_s
@@ -28,10 +28,11 @@ module BuildBuddy
28
28
  else
29
29
  payload = JSON.parse(payload_text)
30
30
  pull_request = payload['pull_request']
31
- build_data = BuildData.new(:pull_request,
32
- :pull_request => pull_request['number'],
33
- :repo_sha => pull_request['head']['sha'],
34
- :repo_full_name => pull_request['base']['repo']['full_name'])
31
+ build_data = BuildData.new(
32
+ build_type => :pull_request,
33
+ :pull_request => pull_request['number'],
34
+ :repo_sha => pull_request['head']['sha'],
35
+ :repo_full_name => pull_request['base']['repo']['full_name'])
35
36
  info "Got pull request #{build_data.pull_request} from GitHub"
36
37
  Celluloid::Actor[:scheduler].queue_a_build(build_data)
37
38
  request.respond 200
@@ -39,15 +40,56 @@ module BuildBuddy
39
40
  when 'ping'
40
41
  request.respond 200, "Running"
41
42
  else
42
- request.respond 404, "Path not found"
43
+ request.respond 404, "Event not supported"
43
44
  end
44
45
  else
45
- request.respond 404, "Path not found"
46
+ request.respond 404, "Method not supported"
47
+ end
48
+ when /^\/log\/([0-9a-z]*)$/
49
+ case request.method
50
+ when 'GET'
51
+ build_data = Celluloid::Actor[:recorder].get_build_data($1)
52
+ log_contents = nil
53
+ if build_data.nil? or build_data.build_log_filename.nil? or !File.exist?(build_data.build_log_filename)
54
+ sleep 1
55
+ request.respond 404, "Not found"
56
+ end
57
+ log_contents = 'Log file has been deleted.'
58
+ File.open(build_data.build_log_filename) do |io|
59
+ log_contents = io.read
60
+ end
61
+ html = %Q(
62
+ <!doctype html>
63
+ <html lang="en">
64
+ <head>
65
+ <meta charset="utf-8">
66
+ <title>Build Log</title>
67
+ <meta name="description" content="Build Log">
68
+ <style>
69
+ body {
70
+ background-color: black;
71
+ color: #f0f0f0;
72
+ }
73
+ pre {
74
+ font-family: "Menlo", "Courier New";
75
+ font-size: 10pt;
76
+ }
77
+ </style>
78
+ </head>
79
+
80
+ <body>
81
+ <pre>
82
+ #{log_contents}
83
+ </pre>
84
+ </body>
85
+ </html>
86
+ )
87
+ request.respond 200, html
88
+ else
89
+ request.respond 404, "Method not supported"
46
90
  end
47
- # TODO: Implement basic access authentication from config file
48
- # TODO: Implement getting the log file
49
91
  else
50
- request.respond 404, "Method not supported"
92
+ request.respond 404, "Path not found"
51
93
  end
52
94
  end
53
95
  end
@@ -18,17 +18,16 @@ module BuildBuddy
18
18
  self.on_slack_data(data)
19
19
  end
20
20
  @rt_client.on :error do |error|
21
- self.on_slack_error(error)
21
+ sub_error = error['error']
22
+ error "Slack error #{sub_error['code']} - #{sub_error['msg']}}"
23
+ end
24
+ @rt_client.on :close do |event|
25
+ raise "Slack connection was closed"
22
26
  end
23
27
  @rt_client.start_async
24
28
  @notify_slack_channel = nil
25
29
  end
26
30
 
27
- def on_slack_error(error)
28
- sub_error = error['error']
29
- error "Whoops! Slack error #{sub_error['code']} - #{sub_error['msg']}}"
30
- end
31
-
32
31
  def on_slack_hello
33
32
  user_id = @rt_client.self['id']
34
33
  map_user_id_to_name = @rt_client.users.map {|id, user| [id, user.name]}.to_h
@@ -102,15 +101,17 @@ module BuildBuddy
102
101
  case message
103
102
  when /master/i
104
103
  response = "OK, I've queued a build of the `master` branch."
105
- scheduler.queue_a_build(BuildData.new(:master,
106
- :repo_full_name => Config.github_webhook_repo_full_name))
104
+ scheduler.queue_a_build(BuildData.new(
105
+ :build_type => :master,
106
+ :repo_full_name => Config.github_webhook_repo_full_name))
107
107
  when /(?<version>v\d+\.\d+)/
108
108
  version = $~[:version]
109
109
  if Config.valid_release_versions.include?(version)
110
110
  response = "OK, I've queued a build of `#{version}` branch."
111
- scheduler.queue_a_build(BuildData.new(:release,
112
- :build_version => version,
113
- :repo_full_name => Config.github_webhook_repo_full_name))
111
+ scheduler.queue_a_build(BuildData.new(
112
+ :build_type => :release,
113
+ :build_version => version,
114
+ :repo_full_name => Config.github_webhook_repo_full_name))
114
115
  else
115
116
  response = "I'm sorry, I cannot build the #{version} release branch"
116
117
  end
@@ -174,4 +175,4 @@ You can also ask me for `status` and I'll tell you what's being built and what's
174
175
  end
175
176
  end
176
177
  end
177
- end
178
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: build-buddy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Lyon-smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-10 00:00:00.000000000 Z
11
+ date: 2016-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: timers
@@ -112,16 +112,16 @@ dependencies:
112
112
  name: reel
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '='
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.6.0.pre3
117
+ version: '0.6'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '='
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.6.0.pre3
124
+ version: '0.6'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: octokit
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.6'
153
+ - !ruby/object:Gem::Dependency
154
+ name: mongo
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '2.2'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.2'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: code-tools
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -177,11 +191,12 @@ files:
177
191
  - lib/build_buddy/builder.rb
178
192
  - lib/build_buddy/config.rb
179
193
  - lib/build_buddy/gitter.rb
194
+ - lib/build_buddy/recorder.rb
180
195
  - lib/build_buddy/scheduler.rb
181
196
  - lib/build_buddy/server.rb
182
197
  - lib/build_buddy/slacker.rb
183
198
  - lib/build_buddy/watcher.rb
184
- homepage: http://rubygems.org/gems/build-buddy
199
+ homepage: https://github.com/jlyonsmith/build-buddy
185
200
  licenses:
186
201
  - MIT
187
202
  metadata: {}