pullermann 1.2.2 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/pullermann/pull_request.rb +15 -0
- data/lib/pullermann/pullermann.rb +76 -50
- data/lib/pullermann.rb +1 -0
- metadata +3 -2
@@ -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
|
-
|
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.
|
39
|
-
@
|
40
|
-
# Jump to next iteration if source and/or target
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
79
|
-
self.rerun_on_target_change
|
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
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
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
|
-
|
127
|
-
comments =
|
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 = /
|
160
|
+
shas = /Merged ([\w]+) into ([\w]+)/.match(comment.body)
|
134
161
|
if shas && shas[1] && shas[2]
|
135
|
-
# Remember
|
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
|
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: '#{@
|
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] != @
|
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 ##{@
|
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/#{@
|
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? '
|
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
|
-
|
224
|
+
self.comment_success + "\n( Success: "
|
199
225
|
else
|
200
226
|
@log.info 'Failing run.'
|
201
|
-
|
227
|
+
self.comment_failure + "\n( Failure: "
|
202
228
|
end
|
203
|
-
message += "
|
229
|
+
message += "Merged #{@request.head_sha} into #{@request.target_head_sha} )"
|
204
230
|
if old_comment_success? == self.success
|
205
|
-
# Replace existing
|
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
|
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
|
212
|
-
call_github(!self.success).delete_comment(@project, @comment
|
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, @
|
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 =
|
251
|
+
state_message = self.status_success
|
226
252
|
when false
|
227
253
|
state_symbol = :failure
|
228
|
-
state_message =
|
254
|
+
state_message = self.status_failure
|
229
255
|
else
|
230
256
|
state_symbol = :pending
|
231
|
-
state_message =
|
257
|
+
state_message = self.status_pending
|
232
258
|
end
|
233
259
|
@github.post(
|
234
|
-
"repos/#{@project}/statuses/#{@
|
260
|
+
"repos/#{@project}/statuses/#{@request.head_sha}", {
|
235
261
|
:state => state_symbol,
|
236
|
-
:description =>
|
262
|
+
:description => state_message
|
237
263
|
}
|
238
264
|
)
|
239
265
|
end
|
data/lib/pullermann.rb
CHANGED
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.
|
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-
|
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:
|