pullermann 1.2.2 → 1.4.1

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.
@@ -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: