prophet 1.6.1 → 2.2.0
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.
- checksums.yaml +5 -5
- data/lib/prophet/prophet.rb +155 -111
- data/lib/prophet/pull_request.rb +5 -1
- data/lib/prophet/railtie.rb +1 -1
- metadata +20 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 63a3b73db0063a2926440a4e1f19a0ae76d62be4a5ae20e7a88fb677229000b5
|
|
4
|
+
data.tar.gz: 7fff7b419b81c22b5f612a3523a04a73b71c53f935d1bdd7f0aca05ec4470ee5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 12ce2eda7bcb9e7e401b32c0f28375a7e873188d41b83dc1a6ec892dc7f4f14f64daeb79f6e3509f918f086852368e0fb2ba0b8bc7310f00d7ec4e00621409e5
|
|
7
|
+
data.tar.gz: 0bd79da7a4d39026bc89e3cdb31a8efcc7109cf1c98948f57e915349fa4689a162c9ac6814b54156c480aabd7561bb9e4fe22d4580eadc195b912ac642d85840
|
data/lib/prophet/prophet.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
require 'English'
|
|
2
|
+
require 'open3'
|
|
3
|
+
|
|
1
4
|
class Prophet
|
|
2
5
|
|
|
3
|
-
attr_accessor :
|
|
4
|
-
:
|
|
6
|
+
attr_accessor :username_pass,
|
|
7
|
+
:access_token_pass,
|
|
5
8
|
:username_fail,
|
|
6
|
-
:
|
|
9
|
+
:access_token_fail,
|
|
7
10
|
:rerun_on_source_change,
|
|
8
11
|
:rerun_on_target_change,
|
|
9
12
|
:prepare_block,
|
|
@@ -15,7 +18,10 @@ class Prophet
|
|
|
15
18
|
:status_success,
|
|
16
19
|
:comment_failure,
|
|
17
20
|
:comment_success,
|
|
18
|
-
:
|
|
21
|
+
:disable_comments,
|
|
22
|
+
:reuse_comments,
|
|
23
|
+
:status_context,
|
|
24
|
+
:status_target_url
|
|
19
25
|
|
|
20
26
|
# Allow configuration blocks being passed to Prophet.
|
|
21
27
|
# See the README.md for examples on how to call this method.
|
|
@@ -42,7 +48,7 @@ class Prophet
|
|
|
42
48
|
begin
|
|
43
49
|
self.prepare_block.call
|
|
44
50
|
rescue Exception => e
|
|
45
|
-
|
|
51
|
+
logger.error "Preparation block raised an exception: #{e}"
|
|
46
52
|
end
|
|
47
53
|
# Loop through all 'open' pull requests.
|
|
48
54
|
selected_requests = pull_requests.select do |request|
|
|
@@ -53,30 +59,38 @@ class Prophet
|
|
|
53
59
|
remove_comment unless self.reuse_comments
|
|
54
60
|
true
|
|
55
61
|
end
|
|
62
|
+
|
|
56
63
|
# Run code on all selected requests.
|
|
57
64
|
selected_requests.each do |request|
|
|
58
65
|
@request = request
|
|
59
|
-
|
|
66
|
+
logger.info "Running for request ##{@request.id}."
|
|
60
67
|
# GitHub always creates a merge commit for its 'Merge Button'.
|
|
61
68
|
# Prophet reuses that commit to run the code on it.
|
|
62
|
-
switch_branch_to_merged_state
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
if switch_branch_to_merged_state
|
|
70
|
+
# Run specified code (i.e. tests) for the project.
|
|
71
|
+
begin
|
|
72
|
+
self.exec_block.call
|
|
73
|
+
# Unless self.success has already been set (to true/false) manually,
|
|
74
|
+
# the success/failure is determined by the last command's return code.
|
|
75
|
+
self.success = ($CHILD_STATUS && $CHILD_STATUS.exitstatus == 0) if self.success.nil?
|
|
76
|
+
rescue Exception => e
|
|
77
|
+
logger.error "Execution block raised an exception: #{e}"
|
|
78
|
+
self.success = false
|
|
79
|
+
end
|
|
80
|
+
switch_branch_back
|
|
81
|
+
comment_on_github
|
|
82
|
+
set_status_on_github
|
|
72
83
|
end
|
|
73
|
-
switch_branch_back
|
|
74
|
-
comment_on_github
|
|
75
|
-
set_status_on_github
|
|
76
84
|
self.success = nil
|
|
77
85
|
end
|
|
78
86
|
end
|
|
79
87
|
|
|
88
|
+
def logger
|
|
89
|
+
@logger ||= Logger.new(STDOUT).tap do |log|
|
|
90
|
+
log.level = Logger::INFO
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
80
94
|
|
|
81
95
|
private
|
|
82
96
|
|
|
@@ -86,67 +100,57 @@ class Prophet
|
|
|
86
100
|
end
|
|
87
101
|
|
|
88
102
|
def configure
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
else
|
|
93
|
-
@log = Logger.new(STDOUT)
|
|
94
|
-
@log.level = Logger::INFO
|
|
95
|
-
end
|
|
103
|
+
self.username_fail ||= self.username_pass
|
|
104
|
+
self.access_token_fail ||= self.access_token_pass
|
|
105
|
+
|
|
96
106
|
# Set default fall back values for options that aren't set.
|
|
97
|
-
self.username ||= git_config['github.login']
|
|
98
|
-
self.password ||= git_config['github.password']
|
|
99
|
-
self.username_fail ||= self.username
|
|
100
|
-
self.password_fail ||= self.password
|
|
101
107
|
self.rerun_on_source_change = true if self.rerun_on_source_change.nil?
|
|
102
108
|
self.rerun_on_target_change = true if self.rerun_on_target_change.nil?
|
|
103
109
|
self.reuse_comments = false if self.reuse_comments.nil?
|
|
110
|
+
self.disable_comments = false if self.disable_comments.nil?
|
|
104
111
|
# Allow for custom messages.
|
|
105
112
|
self.status_pending ||= 'Prophet is still running.'
|
|
106
113
|
self.status_failure ||= 'Prophet reports failure.'
|
|
107
114
|
self.status_success ||= 'Prophet reports success.'
|
|
108
115
|
self.comment_failure ||= 'Prophet reports failure.'
|
|
109
116
|
self.comment_success ||= 'Prophet reports success.'
|
|
117
|
+
self.status_context ||= 'prophet/default'
|
|
110
118
|
# Find environment (tasks, project, ...).
|
|
111
119
|
self.prepare_block ||= lambda {}
|
|
112
120
|
self.exec_block ||= lambda { `rake` }
|
|
113
|
-
@github = connect_to_github
|
|
114
|
-
@github_fail =
|
|
115
|
-
@github
|
|
116
|
-
else
|
|
117
|
-
connect_to_github self.username_fail, self.password_fail
|
|
118
|
-
end
|
|
121
|
+
@github = connect_to_github(access_token: access_token_pass)
|
|
122
|
+
@github_fail = connect_to_github(access_token: access_token_fail)
|
|
119
123
|
end
|
|
120
124
|
|
|
121
|
-
def connect_to_github(
|
|
122
|
-
github = Octokit::Client.new(
|
|
123
|
-
|
|
124
|
-
:password => pass
|
|
125
|
-
)
|
|
125
|
+
def connect_to_github(access_token:)
|
|
126
|
+
github = Octokit::Client.new(access_token: access_token)
|
|
127
|
+
|
|
126
128
|
# Check user login to GitHub.
|
|
127
129
|
github.login
|
|
128
|
-
|
|
130
|
+
logger.info "Successfully logged into GitHub with user '#{github.user.login}'."
|
|
131
|
+
|
|
129
132
|
# Ensure the user has access to desired project.
|
|
130
|
-
# NOTE:
|
|
133
|
+
# NOTE: All three variants should work:
|
|
131
134
|
# 'ssh://git@github.com:user/project.git'
|
|
132
135
|
# 'git@github.com:user/project.git'
|
|
133
|
-
|
|
136
|
+
# 'https://github.com/user/project.git'
|
|
137
|
+
@project ||= /github\.com[\/:](.*)\.git$/.match(git_config['remote.origin.url'])[1]
|
|
134
138
|
begin
|
|
135
139
|
github.repo @project
|
|
136
|
-
|
|
140
|
+
logger.info "Successfully accessed GitHub project '#{@project}'"
|
|
137
141
|
github
|
|
138
142
|
rescue Octokit::Unauthorized => e
|
|
139
|
-
|
|
143
|
+
logger.error "Unable to access GitHub project with user '#{github.user}':\n#{e.message}"
|
|
140
144
|
abort
|
|
141
145
|
end
|
|
142
146
|
end
|
|
143
147
|
|
|
144
148
|
def pull_requests
|
|
145
|
-
request_list = @github.pulls @project, 'open'
|
|
149
|
+
request_list = @github.pulls @project, state: 'open'
|
|
146
150
|
requests = request_list.collect do |request|
|
|
147
151
|
PullRequest.new(@github.pull_request @project, request.number)
|
|
148
152
|
end
|
|
149
|
-
|
|
153
|
+
logger.info "Found #{requests.size > 0 ? requests.size : 'no'} open pull requests in '#{@project}'."
|
|
150
154
|
requests
|
|
151
155
|
end
|
|
152
156
|
|
|
@@ -154,73 +158,91 @@ class Prophet
|
|
|
154
158
|
# - the pull request hasn't been used for a run before.
|
|
155
159
|
# - the pull request has been updated since the last run.
|
|
156
160
|
# - the target (i.e. master) has been updated since the last run.
|
|
161
|
+
# - the pull request does not originate from a fork (to avoid malicious code execution on CI machines)
|
|
157
162
|
def run_necessary?
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
@request.
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
shas = /Merged ([\w]+) into ([\w]+)/.match(comment.body)
|
|
168
|
-
if shas && shas[1] && shas[2]
|
|
169
|
-
# Remember comment to be able to update or delete it later.
|
|
170
|
-
@request.comment = comment
|
|
171
|
-
break
|
|
163
|
+
logger.info "Checking pull request ##{@request.id}: #{@request.content.title}"
|
|
164
|
+
|
|
165
|
+
unless @request.from_fork || @request.wip
|
|
166
|
+
# Compare current sha ids of target and source branch with those from the last test run.
|
|
167
|
+
@request.target_head_sha = @github.commits(@project).first.sha
|
|
168
|
+
comments = @github.issue_comments(@project, @request.id)
|
|
169
|
+
comments = comments.select { |c| [username_pass, username_fail].include?(c.user.login) }.reverse
|
|
170
|
+
comments.each do |comment|
|
|
171
|
+
@request.comment = comment if /Merged ([\w]+) into ([\w]+)/.match(comment.body)
|
|
172
172
|
end
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
|
|
174
|
+
statuses = @github.status(@project, @request.head_sha).statuses.select { |s| s.context == self.status_context }
|
|
175
|
+
# Only run if it's mergeable.
|
|
176
|
+
if @request.content.mergeable
|
|
177
|
+
if statuses.empty?
|
|
178
|
+
# If there is no status yet, it has to be a new request.
|
|
179
|
+
logger.info 'New pull request detected, run needed.'
|
|
180
|
+
return true
|
|
181
|
+
elsif !self.disable_comments && !@request.comment
|
|
182
|
+
logger.info 'Rerun forced.'
|
|
183
|
+
return true
|
|
184
|
+
end
|
|
180
185
|
else
|
|
181
|
-
|
|
182
|
-
if @request.
|
|
183
|
-
|
|
184
|
-
|
|
186
|
+
# Sometimes GitHub doesn't have a proper boolean value stored.
|
|
187
|
+
if @request.content.mergeable.nil? && switch_branch_to_merged_state
|
|
188
|
+
# Pull request is mergeable after all.
|
|
189
|
+
switch_branch_back
|
|
190
|
+
else
|
|
191
|
+
logger.info 'Pull request not auto-mergeable. Not running.'
|
|
192
|
+
if @request.comment
|
|
193
|
+
logger.info 'Deleting existing comment.'
|
|
194
|
+
call_github(old_comment_success?).delete_comment(@project, @request.comment.id)
|
|
195
|
+
end
|
|
196
|
+
create_status(:error, "Pull request not auto-mergeable. Not running.") if statuses.first && statuses.first.state != 'error'
|
|
197
|
+
return false
|
|
185
198
|
end
|
|
186
|
-
return false
|
|
187
199
|
end
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
|
|
201
|
+
# Initialize shas to ensure it will live on after the 'each' block.
|
|
202
|
+
shas = nil
|
|
203
|
+
statuses.each do |status|
|
|
204
|
+
shas = /Merged ([\w]+) into ([\w]+)/.match(status.description)
|
|
205
|
+
break if shas && shas[1] && shas[2]
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
if shas
|
|
209
|
+
logger.info "Current target sha: '#{@request.target_head_sha}', pull sha: '#{@request.head_sha}'."
|
|
210
|
+
logger.info "Last test run target sha: '#{shas[2]}', pull sha: '#{shas[1]}'."
|
|
211
|
+
if self.rerun_on_source_change && (shas[1] != @request.head_sha)
|
|
212
|
+
logger.info 'Re-running due to new commit in pull request.'
|
|
213
|
+
return true
|
|
214
|
+
elsif self.rerun_on_target_change && (shas[2] != @request.target_head_sha)
|
|
215
|
+
logger.info 'Re-running due to new commit in target branch.'
|
|
216
|
+
return true
|
|
217
|
+
end
|
|
218
|
+
else
|
|
219
|
+
# If there are no SHAs yet, it has to be a new request.
|
|
220
|
+
logger.info 'New pull request detected, run needed.'
|
|
197
221
|
return true
|
|
198
222
|
end
|
|
199
|
-
else
|
|
200
|
-
# If there are no comments yet, it has to be a new request.
|
|
201
|
-
@log.info 'New pull request detected, run needed.'
|
|
202
|
-
return true
|
|
203
223
|
end
|
|
204
|
-
|
|
224
|
+
|
|
225
|
+
logger.info "Pull request comes from a fork." if @request.from_fork
|
|
226
|
+
logger.info "Not running for request ##{@request.id}."
|
|
205
227
|
false
|
|
206
228
|
end
|
|
207
229
|
|
|
208
|
-
def switch_branch_to_merged_state
|
|
230
|
+
def switch_branch_to_merged_state
|
|
209
231
|
# Fetch the merge-commit for the pull request.
|
|
210
232
|
# NOTE: This commit is automatically created by 'GitHub Merge Button'.
|
|
211
|
-
# FIXME: Use cheetah to pipe to
|
|
233
|
+
# FIXME: Use cheetah to pipe to logger.debug instead of that /dev/null hack.
|
|
212
234
|
`git fetch origin refs/pull/#{@request.id}/merge: &> /dev/null`
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
235
|
+
_output, status = Open3.capture2 'git checkout FETCH_HEAD &> /dev/null'
|
|
236
|
+
if status != 0
|
|
237
|
+
logger.error 'Unable to switch to merge branch.'
|
|
238
|
+
return false
|
|
217
239
|
end
|
|
218
240
|
true
|
|
219
241
|
end
|
|
220
242
|
|
|
221
243
|
def switch_branch_back
|
|
222
|
-
# FIXME: Use cheetah to pipe to
|
|
223
|
-
|
|
244
|
+
# FIXME: Use cheetah to pipe to logger.debug instead of that /dev/null hack.
|
|
245
|
+
logger.info 'Switching back to original branch.'
|
|
224
246
|
# FIXME: For branches other than master, remember the original branch.
|
|
225
247
|
`git checkout master &> /dev/null`
|
|
226
248
|
# Clean up potential remains and run garbage collector.
|
|
@@ -242,33 +264,60 @@ class Prophet
|
|
|
242
264
|
end
|
|
243
265
|
|
|
244
266
|
def comment_on_github
|
|
267
|
+
return if self.disable_comments
|
|
268
|
+
|
|
245
269
|
# Determine comment message.
|
|
246
270
|
message = if self.success
|
|
247
|
-
|
|
248
|
-
self.comment_success
|
|
271
|
+
logger.info 'Successful run.'
|
|
272
|
+
self.comment_success
|
|
249
273
|
else
|
|
250
|
-
|
|
251
|
-
self.comment_failure
|
|
274
|
+
logger.info 'Failing run.'
|
|
275
|
+
self.comment_failure
|
|
252
276
|
end
|
|
253
|
-
message +=
|
|
277
|
+
message += status_string
|
|
254
278
|
if self.reuse_comments && old_comment_success? == self.success
|
|
255
279
|
# Replace existing comment's body with the correct connection.
|
|
256
|
-
|
|
280
|
+
logger.info "Updating existing #{notion(self.success)} comment."
|
|
257
281
|
call_github(self.success).update_comment(@project, @request.comment.id, message)
|
|
258
282
|
else
|
|
259
283
|
if @request.comment
|
|
260
|
-
|
|
284
|
+
logger.info "Deleting existing #{notion(!self.success)} comment."
|
|
261
285
|
# Delete old comment with correct connection (if @request.comment exists).
|
|
262
286
|
call_github(!self.success).delete_comment(@project, @request.comment.id)
|
|
263
287
|
end
|
|
264
288
|
# Create new comment with correct connection.
|
|
265
|
-
|
|
289
|
+
logger.info "Adding new #{notion(self.success)} comment."
|
|
266
290
|
call_github(self.success).add_comment(@project, @request.id, message)
|
|
267
291
|
end
|
|
268
292
|
end
|
|
269
293
|
|
|
294
|
+
def status_string
|
|
295
|
+
case self.success
|
|
296
|
+
when true
|
|
297
|
+
" (Merged #{@request.head_sha} into #{@request.target_head_sha})"
|
|
298
|
+
when false
|
|
299
|
+
" (Merged #{@request.head_sha} into #{@request.target_head_sha})"
|
|
300
|
+
else
|
|
301
|
+
""
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def create_status(state, description)
|
|
306
|
+
logger.info "Setting status '#{state}': '#{description}'"
|
|
307
|
+
@github.create_status(
|
|
308
|
+
@project,
|
|
309
|
+
@request.head_sha,
|
|
310
|
+
state,
|
|
311
|
+
{
|
|
312
|
+
"description" => description,
|
|
313
|
+
"context" => status_context,
|
|
314
|
+
"target_url" => self.status_target_url
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
end
|
|
318
|
+
|
|
270
319
|
def set_status_on_github
|
|
271
|
-
|
|
320
|
+
logger.info 'Updating status on GitHub.'
|
|
272
321
|
case self.success
|
|
273
322
|
when true
|
|
274
323
|
state_symbol = :success
|
|
@@ -280,12 +329,7 @@ class Prophet
|
|
|
280
329
|
state_symbol = :pending
|
|
281
330
|
state_message = self.status_pending
|
|
282
331
|
end
|
|
283
|
-
|
|
284
|
-
"repos/#{@project}/statuses/#{@request.head_sha}", {
|
|
285
|
-
:state => state_symbol,
|
|
286
|
-
:description => state_message
|
|
287
|
-
}
|
|
288
|
-
)
|
|
332
|
+
create_status(state_symbol, state_message + status_string)
|
|
289
333
|
end
|
|
290
334
|
|
|
291
335
|
def notion(success)
|
data/lib/prophet/pull_request.rb
CHANGED
|
@@ -4,12 +4,16 @@ class PullRequest
|
|
|
4
4
|
:content,
|
|
5
5
|
:comment,
|
|
6
6
|
:head_sha,
|
|
7
|
-
:target_head_sha
|
|
7
|
+
:target_head_sha,
|
|
8
|
+
:from_fork,
|
|
9
|
+
:wip
|
|
8
10
|
|
|
9
11
|
def initialize(content)
|
|
10
12
|
@content = content
|
|
11
13
|
@id = content.number
|
|
12
14
|
@head_sha = content.head.sha
|
|
15
|
+
@from_fork = content.head.repo.fork
|
|
16
|
+
@wip = content.labels.map(&:name).map(&:downcase).include? 'wip'
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
end
|
data/lib/prophet/railtie.rb
CHANGED
metadata
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prophet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dominik Bamberger
|
|
8
8
|
- Thomas Schmidt
|
|
9
9
|
- Jordi Massaguer Pla
|
|
10
|
-
autorequire:
|
|
10
|
+
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2020-09-28 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: faraday_middleware
|
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
|
18
18
|
requirements:
|
|
19
|
-
- -
|
|
19
|
+
- - "~>"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 0.
|
|
21
|
+
version: 0.11.0
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
25
|
requirements:
|
|
26
|
-
- -
|
|
26
|
+
- - "~>"
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: 0.
|
|
28
|
+
version: 0.11.0
|
|
29
29
|
- !ruby/object:Gem::Dependency
|
|
30
30
|
name: faraday
|
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
|
32
32
|
requirements:
|
|
33
|
-
- -
|
|
33
|
+
- - "~>"
|
|
34
34
|
- !ruby/object:Gem::Version
|
|
35
|
-
version: 0.
|
|
35
|
+
version: 0.11.0
|
|
36
36
|
type: :runtime
|
|
37
37
|
prerelease: false
|
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
39
39
|
requirements:
|
|
40
|
-
- -
|
|
40
|
+
- - "~>"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: 0.
|
|
42
|
+
version: 0.11.0
|
|
43
43
|
- !ruby/object:Gem::Dependency
|
|
44
44
|
name: octokit
|
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
|
-
- -
|
|
47
|
+
- - "~>"
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version:
|
|
49
|
+
version: '4.0'
|
|
50
50
|
type: :runtime
|
|
51
51
|
prerelease: false
|
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
|
53
53
|
requirements:
|
|
54
|
-
- -
|
|
54
|
+
- - "~>"
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
version:
|
|
56
|
+
version: '4.0'
|
|
57
57
|
description: Prophet runs custom code (i.e. your project's test suite) on open pull
|
|
58
58
|
requests on GitHub. Afterwards it posts the result as a comment to the respective
|
|
59
59
|
request. This should give you an outlook on the future state of your repository
|
|
@@ -73,26 +73,24 @@ homepage: http://github.com/b4mboo/prophet
|
|
|
73
73
|
licenses:
|
|
74
74
|
- MIT
|
|
75
75
|
metadata: {}
|
|
76
|
-
post_install_message:
|
|
76
|
+
post_install_message:
|
|
77
77
|
rdoc_options: []
|
|
78
78
|
require_paths:
|
|
79
79
|
- lib
|
|
80
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
81
|
requirements:
|
|
82
|
-
- -
|
|
82
|
+
- - ">="
|
|
83
83
|
- !ruby/object:Gem::Version
|
|
84
84
|
version: '0'
|
|
85
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- -
|
|
87
|
+
- - ">="
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
89
|
version: '0'
|
|
90
90
|
requirements: []
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
signing_key:
|
|
91
|
+
rubygems_version: 3.1.4
|
|
92
|
+
signing_key:
|
|
94
93
|
specification_version: 4
|
|
95
94
|
summary: An easy way to loop through open pull requests and run code onthe merged
|
|
96
95
|
branch.
|
|
97
96
|
test_files: []
|
|
98
|
-
has_rdoc:
|