pullermann 1.2.2 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ class PullRequest
2
+
3
+ attr_accessor :id,
4
+ :content,
5
+ :comment,
6
+ :head_sha,
7
+ :target_head_sha
8
+
9
+ def initialize(content)
10
+ @content = content
11
+ @id = content.number
12
+ @head_sha = content.head.sha
13
+ end
14
+
15
+ end
@@ -9,7 +9,12 @@ class Pullermann
9
9
  :prepare_block,
10
10
  :exec_block,
11
11
  :logger,
12
- :success
12
+ :success,
13
+ :status_pending,
14
+ :status_failure,
15
+ :status_success,
16
+ :comment_failure,
17
+ :comment_success
13
18
 
14
19
  # Allow configuration blocks being passed to Pullermann.
15
20
  # See the README.md for examples on how to call this method.
@@ -33,24 +38,39 @@ class Pullermann
33
38
  def run
34
39
  # Populate variables and setup environment.
35
40
  configure
36
- self.prepare_block.call
41
+ begin
42
+ self.prepare_block.call
43
+ rescue Exception => e
44
+ @log.error "Preparation block raised an exception: #{e}"
45
+ end
37
46
  # Loop through all 'open' pull requests.
38
- pull_requests.each do |request|
39
- @request_id = request['number']
40
- # Jump to next iteration if source and/or target haven't change since last run.
47
+ selected_requests = pull_requests.select do |request|
48
+ @request = request
49
+ # Jump to next iteration if source and/or target didn't change since last run.
41
50
  next unless run_necessary?
42
51
  set_status_on_github
52
+ true
53
+ end
54
+ # Run code on all selected requests.
55
+ selected_requests.each do |request|
56
+ @request = request
43
57
  # GitHub always creates a merge commit for its 'Merge Button'.
44
58
  # Pullermann reuses that commit to run the code on it.
45
59
  switch_branch_to_merged_state
46
60
  # Run specified code (i.e. tests) for the project.
47
- self.exec_block.call
48
- # Unless self.success has already been set manually,
49
- # the success/failure is determined by the last command's return code.
50
- self.success ||= ($? == 0)
61
+ begin
62
+ self.exec_block.call
63
+ # Unless self.success has already been set manually,
64
+ # the success/failure is determined by the last command's return code.
65
+ self.success ||= ($? == 0)
66
+ rescue Exception => e
67
+ @log.error "Execution block raised an exception: #{e}"
68
+ self.success = false
69
+ end
51
70
  switch_branch_back
52
71
  comment_on_github
53
72
  set_status_on_github
73
+ self.success = nil
54
74
  end
55
75
  end
56
76
 
@@ -75,8 +95,14 @@ class Pullermann
75
95
  self.password ||= git_config['github.password']
76
96
  self.username_fail ||= self.username
77
97
  self.password_fail ||= self.password
78
- self.rerun_on_source_change = true unless self.rerun_on_source_change == false
79
- self.rerun_on_target_change = true unless self.rerun_on_target_change == false
98
+ self.rerun_on_source_change ||= true
99
+ self.rerun_on_target_change ||= true
100
+ # Allow for custom messages.
101
+ self.status_pending ||= 'Pullermann is still running.'
102
+ self.status_failure ||= 'Pullermann reports failure.'
103
+ self.status_success ||= 'Pullermann reports success.'
104
+ self.comment_failure ||= 'Pullermann reports failure.'
105
+ self.comment_success ||= 'Pullermann reports success.'
80
106
  # Find environment (tasks, project, ...).
81
107
  self.prepare_block ||= lambda {}
82
108
  self.exec_block ||= lambda { `rake` }
@@ -109,9 +135,12 @@ class Pullermann
109
135
  end
110
136
 
111
137
  def pull_requests
112
- pulls = @github.pulls @project, 'open'
113
- @log.info "Found #{pulls.size > 0 ? pulls.size : 'no'} open pull requests in '#{@project}'."
114
- pulls
138
+ request_list = @github.pulls @project, 'open'
139
+ requests = request_list.collect do |request|
140
+ PullRequest.new(@github.pull_request @project, request.number)
141
+ end
142
+ @log.info "Found #{requests.size > 0 ? requests.size : 'no'} open pull requests in '#{@project}'."
143
+ requests
115
144
  end
116
145
 
117
146
  # (Re-)runs are necessary if:
@@ -119,40 +148,38 @@ class Pullermann
119
148
  # - the pull request has been updated since the last run.
120
149
  # - the target (i.e. master) has been updated since the last run.
121
150
  def run_necessary?
122
- pull_request = @github.pull_request @project, @request_id
123
- @log.info "Checking pull request ##{@request_id}: #{pull_request.title}"
151
+ @log.info "Checking pull request ##{@request.id}: #{@request.content.title}"
124
152
  # Compare current sha ids of target and source branch with those from the last test run.
125
- @target_head_sha = @github.commits(@project).first.sha
126
- @pull_head_sha = pull_request.head.sha
127
- comments = @github.issue_comments(@project, @request_id)
128
- comments = comments.select{ |c| [username, username_fail].include?(c.user.login) }.reverse
153
+ @request.target_head_sha = @github.commits(@project).first.sha
154
+ comments = @github.issue_comments(@project, @request.id)
155
+ comments = comments.select { |c| [username, username_fail].include?(c.user.login) }.reverse
129
156
  # Initialize shas to ensure it will live on after the 'each' block.
130
157
  shas = nil
131
- @comment = nil
158
+ @request.comment = nil
132
159
  comments.each do |comment|
133
- shas = /master sha# ([\w]+) ; pull sha# ([\w]+)/.match(comment.body)
160
+ shas = /Merged ([\w]+) into ([\w]+)/.match(comment.body)
134
161
  if shas && shas[1] && shas[2]
135
- # Remember @comment to be able to update or delete it later.
136
- @comment = comment
162
+ # Remember comment to be able to update or delete it later.
163
+ @request.comment = comment
137
164
  break
138
165
  end
139
166
  end
140
167
  # If it's not mergeable, we need to delete all comments of former test runs.
141
- unless pull_request.mergeable
168
+ unless @request.content.mergeable
142
169
  @log.info 'Pull request not auto-mergeable. Not running.'
143
- if @comment
170
+ if @request.comment
144
171
  @log.info 'Deleting existing comment.'
145
- call_github(old_comment_success?).delete_comment(@project, @comment.id)
172
+ call_github(old_comment_success?).delete_comment(@project, @request.comment.id)
146
173
  end
147
174
  return false
148
175
  end
149
- if @comment
150
- @log.info "Current target sha: '#{@target_head_sha}', pull sha: '#{@pull_head_sha}'."
176
+ if @request.comment
177
+ @log.info "Current target sha: '#{@request.target_head_sha}', pull sha: '#{@request.head_sha}'."
151
178
  @log.info "Last test run target sha: '#{shas[1]}', pull sha: '#{shas[2]}'."
152
- if self.rerun_on_source_change && (shas[2] != @pull_head_sha)
179
+ if self.rerun_on_source_change && (shas[2] != @request.head_sha)
153
180
  @log.info 'Re-running due to new commit in pull request.'
154
181
  return true
155
- elsif self.rerun_on_target_change && (shas[1] != @target_head_sha)
182
+ elsif self.rerun_on_target_change && (shas[1] != @request.target_head_sha)
156
183
  @log.info 'Re-running due to new commit in target branch.'
157
184
  return true
158
185
  end
@@ -161,7 +188,7 @@ class Pullermann
161
188
  @log.info 'New pull request detected, run needed.'
162
189
  return true
163
190
  end
164
- @log.info "Not running for request ##{@request_id}."
191
+ @log.info "Not running for request ##{@request.id}."
165
192
  false
166
193
  end
167
194
 
@@ -169,7 +196,7 @@ class Pullermann
169
196
  # Fetch the merge-commit for the pull request.
170
197
  # NOTE: This commit is automatically created by 'GitHub Merge Button'.
171
198
  # FIXME: Use cheetah to pipe to @log.debug instead of that /dev/null hack.
172
- `git fetch origin refs/pull/#{@request_id}/merge: &> /dev/null`
199
+ `git fetch origin refs/pull/#{@request.id}/merge: &> /dev/null`
173
200
  `git checkout FETCH_HEAD &> /dev/null`
174
201
  unless $? == 0
175
202
  @log.error 'Unable to switch to merge branch.'
@@ -185,35 +212,34 @@ class Pullermann
185
212
  end
186
213
 
187
214
  def old_comment_success?
188
- return unless @comment
215
+ return unless @request.comment
189
216
  # Analyze old comment to see whether it was a successful or a failing one.
190
- @comment.body.include? 'Well done!'
217
+ @request.comment.body.include? '( Success: '
191
218
  end
192
219
 
193
220
  def comment_on_github
194
221
  # Determine comment message.
195
- # TODO: Allow for custom messages.
196
222
  message = if self.success
197
223
  @log.info 'Successful run.'
198
- 'Well done! Your code is still running successfully after merging this pull request.'
224
+ self.comment_success + "\n( Success: "
199
225
  else
200
226
  @log.info 'Failing run.'
201
- 'Unfortunately your code is failing after merging this pull request.'
227
+ self.comment_failure + "\n( Failure: "
202
228
  end
203
- message += "\n( master sha# #{@target_head_sha} ; pull sha# #{@pull_head_sha} )"
229
+ message += "Merged #{@request.head_sha} into #{@request.target_head_sha} )"
204
230
  if old_comment_success? == self.success
205
- # Replace existing @comment's body with the correct connection.
231
+ # Replace existing comment's body with the correct connection.
206
232
  @log.info "Updating existing #{notion(self.success)} comment."
207
- call_github(self.success).update_comment(@project, @comment['id'], message)
233
+ call_github(self.success).update_comment(@project, @request.comment.id, message)
208
234
  else
209
- if @comment
235
+ if @request.comment
210
236
  @log.info "Deleting existing #{notion(!self.success)} comment."
211
- # Delete old @comment with correct connection (if @comment exists).
212
- call_github(!self.success).delete_comment(@project, @comment['id'])
237
+ # Delete old comment with correct connection (if @request.comment exists).
238
+ call_github(!self.success).delete_comment(@project, @request.comment.id)
213
239
  end
214
240
  # Create new comment with correct connection.
215
241
  @log.info "Adding new #{notion(self.success)} comment."
216
- call_github(self.success).add_comment(@project, @request_id, message)
242
+ call_github(self.success).add_comment(@project, @request.id, message)
217
243
  end
218
244
  end
219
245
 
@@ -222,18 +248,18 @@ class Pullermann
222
248
  case self.success
223
249
  when true
224
250
  state_symbol = :success
225
- state_message = 'passing after merging'
251
+ state_message = self.status_success
226
252
  when false
227
253
  state_symbol = :failure
228
- state_message = 'failing after merging'
254
+ state_message = self.status_failure
229
255
  else
230
256
  state_symbol = :pending
231
- state_message = 'still running for'
257
+ state_message = self.status_pending
232
258
  end
233
259
  @github.post(
234
- "repos/#{@project}/statuses/#{@pull_head_sha}", {
260
+ "repos/#{@project}/statuses/#{@request.head_sha}", {
235
261
  :state => state_symbol,
236
- :description => "Tests are #{state_message} this pull request."
262
+ :description => state_message
237
263
  }
238
264
  )
239
265
  end
data/lib/pullermann.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'octokit'
2
2
  require 'logger'
3
3
  require 'pullermann/railtie' if defined?(Rails)
4
+ require 'pullermann/pull_request'
4
5
  require 'pullermann/pullermann'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pullermann
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-10 00:00:00.000000000 Z
14
+ date: 2012-09-20 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: octokit
@@ -59,6 +59,7 @@ files:
59
59
  - lib/tasks/pullermann.rake
60
60
  - lib/pullermann/pullermann.rb
61
61
  - lib/pullermann/railtie.rb
62
+ - lib/pullermann/pull_request.rb
62
63
  homepage: http://github.com/b4mboo/pullermann
63
64
  licenses: []
64
65
  post_install_message: