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