git_reflow 0.7.5 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Appraisals +2 -2
- data/CHANGELOG.md +75 -0
- data/Gemfile.lock +34 -35
- data/README.rdoc +187 -60
- data/circle.yml +9 -9
- data/git_reflow.gemspec +8 -8
- data/lib/git_reflow/commands/deliver.rb +1 -9
- data/lib/git_reflow/commands/refresh.rb +23 -0
- data/lib/git_reflow/commands/review.rb +7 -7
- data/lib/git_reflow/commands/setup.rb +7 -3
- data/lib/git_reflow/commands/start.rb +13 -5
- data/lib/git_reflow/git_helpers.rb +22 -23
- data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +4 -4
- data/lib/git_reflow/git_server/bit_bucket.rb +7 -7
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +75 -2
- data/lib/git_reflow/git_server/git_hub.rb +17 -8
- data/lib/git_reflow/git_server/pull_request.rb +73 -5
- data/lib/git_reflow/git_server.rb +3 -3
- data/lib/git_reflow/merge_error.rb +9 -0
- data/lib/git_reflow/sandbox.rb +4 -16
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow.rb +32 -75
- data/spec/git_reflow_spec.rb +157 -141
- data/spec/lgtm_git_reflow_spec.rb +165 -139
- data/spec/lib/git_reflow/git_helpers_spec.rb +19 -63
- data/spec/lib/git_reflow/git_server_spec.rb +24 -24
- data/spec/lib/git_server/bit_bucket_spec.rb +12 -12
- data/spec/lib/git_server/git_hub/pull_request_spec.rb +7 -5
- data/spec/lib/git_server/git_hub_spec.rb +34 -34
- data/spec/lib/git_server/pull_request_spec.rb +207 -16
- data/spec/support/command_line_helpers.rb +14 -9
- data/spec/support/github_helpers.rb +21 -21
- data/spec/support/rspec_stub_helpers.rb +2 -2
- metadata +18 -16
@@ -23,14 +23,17 @@ describe GitReflow do
|
|
23
23
|
allow(GitReflow::Config).to receive(:get).with("constants.minimumApprovals").and_return("2")
|
24
24
|
allow(GitReflow::Config).to receive(:get).and_call_original
|
25
25
|
|
26
|
-
HighLine.
|
26
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
27
27
|
values = {
|
28
28
|
"Please enter your GitHub username: " => user,
|
29
29
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
30
30
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
31
31
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
32
32
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'yes',
|
33
|
-
"Would you like to open it in your browser?" => 'n'
|
33
|
+
"Would you like to open it in your browser?" => 'n',
|
34
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
35
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
36
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
34
37
|
}
|
35
38
|
return_value = values[question] || values[terminal]
|
36
39
|
question = ""
|
@@ -40,7 +43,13 @@ describe GitReflow do
|
|
40
43
|
|
41
44
|
context :deliver do
|
42
45
|
let(:branch) { 'new-feature' }
|
43
|
-
let(:inputs)
|
46
|
+
let(:inputs) {
|
47
|
+
{ :title => "new-feature",
|
48
|
+
:message => "message",
|
49
|
+
:head => "reenhanced:new-feature"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
let(:merge_response) { {} }
|
44
53
|
let!(:github) do
|
45
54
|
allow_any_instance_of(GitReflow::GitServer::GitHub::PullRequest).to receive(:build).and_return(Struct.new(:state, :description, :url).new)
|
46
55
|
stub_github_with({
|
@@ -54,7 +63,12 @@ describe GitReflow do
|
|
54
63
|
|
55
64
|
|
56
65
|
before do
|
57
|
-
GitReflow.
|
66
|
+
allow(GitReflow::GitServer::GitHub).to receive_message_chain(:connection, :pull_requests, :merge).and_return(merge_response)
|
67
|
+
allow(merge_response).to receive(:success?).and_return(true)
|
68
|
+
|
69
|
+
# Stubs out the http response to github api
|
70
|
+
allow(GitReflow::GitServer::GitHub).to receive_message_chain(:connection, :pull_requests, :merge).and_return(merge_response)
|
71
|
+
allow(merge_response).to receive(:success?).and_return(true);
|
58
72
|
|
59
73
|
module Kernel
|
60
74
|
def system(cmd)
|
@@ -65,55 +79,83 @@ describe GitReflow do
|
|
65
79
|
|
66
80
|
subject { GitReflow.deliver inputs }
|
67
81
|
|
68
|
-
it "fetches the latest changes to the destination branch" do
|
69
|
-
GitReflow.should_receive(:fetch_destination).with('master')
|
70
|
-
subject
|
71
|
-
end
|
72
|
-
|
73
82
|
it "looks for a pull request matching the feature branch and destination branch" do
|
74
|
-
github.
|
83
|
+
expect(github).to receive(:find_open_pull_request).with(from: branch, to: 'master')
|
75
84
|
subject
|
76
85
|
end
|
77
86
|
|
78
87
|
context "and pull request exists for the feature branch to the destination branch" do
|
79
88
|
before do
|
80
|
-
github.
|
81
|
-
github.
|
82
|
-
existing_pull_request.
|
83
|
-
github.
|
84
|
-
|
85
|
-
existing_pull_request.
|
86
|
-
|
89
|
+
allow(github).to receive(:build_status).and_return(build_status)
|
90
|
+
expect(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
91
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
92
|
+
allow(github).to receive(:reviewers).and_return(['codenamev'])
|
93
|
+
allow(existing_pull_request).to receive(:approvals).and_return(["Simon", "John"])
|
94
|
+
allow(existing_pull_request).to receive_message_chain(:last_comment, :match).and_return(true)
|
95
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-deliver").and_return("true")
|
96
|
+
allow(GitReflow).to receive(:status)
|
87
97
|
end
|
88
98
|
|
89
99
|
context 'and build status is not "success"' do
|
90
100
|
let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)' }) }
|
91
101
|
|
92
102
|
before do
|
93
|
-
existing_pull_request.
|
94
|
-
existing_pull_request.
|
103
|
+
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
104
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
95
105
|
end
|
96
106
|
|
97
107
|
it "halts delivery and notifies user of a failed build" do
|
98
108
|
expect { subject }.to have_said "#{build_status.description}: #{build_status.target_url}", :deliver_halted
|
99
109
|
end
|
110
|
+
|
111
|
+
context 'forces a merge' do
|
112
|
+
before do
|
113
|
+
inputs[:skip_lgtm] = true
|
114
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
115
|
+
allow(existing_pull_request).to receive(:reviewers).and_return([])
|
116
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
117
|
+
allow(existing_pull_request).to receive(:approvals).and_return(['simonzhu24'])
|
118
|
+
allow(GitReflow).to receive(:append_to_squashed_commit_message)
|
119
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "checks out the base branch" do
|
123
|
+
expect { subject }.to have_run_command("git checkout master")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "pulls changes from remote repo to local branch" do
|
127
|
+
expect { subject }.to have_run_command("git pull origin master")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "deletes the remote feature branch" do
|
131
|
+
expect { subject }.to have_run_command("git push origin :new-feature")
|
132
|
+
end
|
133
|
+
|
134
|
+
it "deletes the local feature branch" do
|
135
|
+
expect { subject }.to have_run_command("git branch -D new-feature")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "forces a merge" do
|
139
|
+
expect { subject }.to have_said "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'", :notice
|
140
|
+
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
141
|
+
end
|
142
|
+
end
|
100
143
|
end
|
101
144
|
|
102
145
|
context 'and build status is nil' do
|
103
146
|
let(:build_status) { nil }
|
104
|
-
let(:inputs) {{ 'skip_lgtm' => true }}
|
105
147
|
|
106
148
|
before do
|
107
149
|
# stubbing unrelated results so we can just test that it made it insdide the conditional block
|
108
|
-
|
109
|
-
existing_pull_request.
|
110
|
-
|
111
|
-
|
112
|
-
|
150
|
+
inputs[:skip_lgtm] = false
|
151
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
152
|
+
allow(existing_pull_request).to receive(:reviewers).and_return([])
|
153
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
154
|
+
allow(existing_pull_request).to receive(:approvals).and_return(['simonzhu24'])
|
113
155
|
end
|
114
156
|
|
115
157
|
it "ignores build status when not setup" do
|
116
|
-
expect { subject }.to have_said "
|
158
|
+
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
117
159
|
end
|
118
160
|
end
|
119
161
|
|
@@ -122,23 +164,18 @@ describe GitReflow do
|
|
122
164
|
|
123
165
|
context 'and has comments' do
|
124
166
|
before do
|
125
|
-
|
167
|
+
inputs[:skip_lgtm] = false
|
168
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
126
169
|
end
|
127
170
|
|
128
171
|
context 'but there are 2 LGTMs and irrelevant last comment' do
|
129
172
|
let(:lgtm_comment_authors) { ['nhance', 'Simon'] }
|
130
173
|
before do
|
131
|
-
existing_pull_request.
|
132
|
-
existing_pull_request.
|
174
|
+
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
175
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
133
176
|
allow(GitReflow::GitServer::PullRequest).to receive(:minimum_approvals).and_return("2")
|
134
|
-
existing_pull_request.
|
135
|
-
existing_pull_request.
|
136
|
-
end
|
137
|
-
|
138
|
-
it "doesn't include the pull request body in the commit message" do
|
139
|
-
squash_message = "#{existing_pull_request.body}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance, @Simon\n"
|
140
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).never.with(squash_message)
|
141
|
-
subject
|
177
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
178
|
+
allow(existing_pull_request).to receive_message_chain(:last_comment, :match).and_return(nil)
|
142
179
|
end
|
143
180
|
|
144
181
|
context "and the pull request has no body" do
|
@@ -146,44 +183,34 @@ describe GitReflow do
|
|
146
183
|
|
147
184
|
before do
|
148
185
|
existing_pull_request.description = ''
|
149
|
-
github.
|
150
|
-
GitReflow.
|
151
|
-
existing_pull_request.
|
152
|
-
end
|
153
|
-
|
154
|
-
it "doesn't include the first commit message for the new branch in the commit message of the merge" do
|
155
|
-
squash_message = "#{first_commit_message}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance, @Simon\n"
|
156
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).never.with(squash_message)
|
157
|
-
subject
|
186
|
+
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
187
|
+
allow(GitReflow).to receive(:get_first_commit_message).and_return(first_commit_message)
|
188
|
+
allow(existing_pull_request).to receive(:reviewers).and_return(lgtm_comment_authors)
|
158
189
|
end
|
159
190
|
end
|
160
191
|
|
161
192
|
it "doesn't notify user of the merge and performs it" do
|
162
|
-
|
163
|
-
destination_branch: 'master',
|
164
|
-
pull_request_number: existing_pull_request.number,
|
165
|
-
lgtm_authors: ['nhance', 'Simon'],
|
166
|
-
message: existing_pull_request.body
|
167
|
-
})
|
168
|
-
|
169
|
-
expect { subject }.to_not have_output "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'"
|
193
|
+
expect { subject }.to_not have_said "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'"
|
170
194
|
end
|
171
195
|
|
172
196
|
it "doesn't update the destination branch" do
|
173
|
-
GitReflow.
|
197
|
+
expect(GitReflow).to receive(:update_destination).with('master').never
|
174
198
|
subject
|
175
199
|
end
|
176
200
|
|
177
201
|
context "and doesn't clean up feature branch" do
|
178
202
|
before do
|
179
|
-
HighLine.
|
203
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
180
204
|
values = {
|
181
205
|
"Please enter your GitHub username: " => user,
|
182
206
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
183
207
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
184
208
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
185
|
-
"Would you like to push this branch to your remote repo and cleanup your feature branch?
|
186
|
-
"Would you like to open it in your browser?" => 'no'
|
209
|
+
"Would you like to push this branch to your remote repo and cleanup your feature branch?" => 'yes',
|
210
|
+
"Would you like to open it in your browser?" => 'no',
|
211
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
212
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
213
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
187
214
|
}
|
188
215
|
return_value = values[question] || values[terminal]
|
189
216
|
question = ""
|
@@ -193,11 +220,15 @@ describe GitReflow do
|
|
193
220
|
|
194
221
|
context "not always" do
|
195
222
|
before do
|
196
|
-
GitReflow::Config.
|
223
|
+
allow(GitReflow::Config).to receive(:get) { "false" }
|
224
|
+
end
|
225
|
+
|
226
|
+
it "doesn't checkout the base branch" do
|
227
|
+
expect { subject }.to_not have_run_command("git checkout master")
|
197
228
|
end
|
198
229
|
|
199
230
|
it "doesn't push local squash merged base branch to remote repo" do
|
200
|
-
expect { subject }.to_not have_run_command("git
|
231
|
+
expect { subject }.to_not have_run_command("git pull origin master")
|
201
232
|
end
|
202
233
|
|
203
234
|
it "doesn't delete the remote feature branch" do
|
@@ -211,11 +242,15 @@ describe GitReflow do
|
|
211
242
|
|
212
243
|
context "always" do
|
213
244
|
before do
|
214
|
-
GitReflow::Config.
|
245
|
+
allow(GitReflow::Config).to receive(:get) { "true" }
|
246
|
+
end
|
247
|
+
|
248
|
+
it "doesn't checkout the base branch" do
|
249
|
+
expect { subject }.to_not have_run_command("git checkout master")
|
215
250
|
end
|
216
251
|
|
217
252
|
it "doesn't push local squash merged base branch to remote repo" do
|
218
|
-
expect { subject }.to_not have_run_command("git
|
253
|
+
expect { subject }.to_not have_run_command("git pull origin master")
|
219
254
|
end
|
220
255
|
|
221
256
|
it "doesn't delete the remote feature branch" do
|
@@ -231,14 +266,17 @@ describe GitReflow do
|
|
231
266
|
|
232
267
|
context "and not cleaning up feature branch" do
|
233
268
|
before do
|
234
|
-
HighLine.
|
269
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
235
270
|
values = {
|
236
271
|
"Please enter your GitHub username: " => user,
|
237
272
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
238
273
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
239
274
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
240
275
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'no',
|
241
|
-
"Would you like to open it in your browser?" => 'no'
|
276
|
+
"Would you like to open it in your browser?" => 'no',
|
277
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
278
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
279
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
242
280
|
}
|
243
281
|
return_value = values[question] || values[terminal]
|
244
282
|
question = ""
|
@@ -246,8 +284,12 @@ describe GitReflow do
|
|
246
284
|
end
|
247
285
|
end
|
248
286
|
|
249
|
-
it "doesn't
|
250
|
-
expect { subject }.to_not have_run_command('git
|
287
|
+
it "doesn't checkout the base branch" do
|
288
|
+
expect { subject }.to_not have_run_command('git checkout master')
|
289
|
+
end
|
290
|
+
|
291
|
+
it "doesn't pull changes from remote repo to local branch" do
|
292
|
+
expect { subject }.to_not have_run_command('git pull origin master')
|
251
293
|
end
|
252
294
|
|
253
295
|
it "doesn't delete the feature branch on the remote repo" do
|
@@ -274,24 +316,18 @@ describe GitReflow do
|
|
274
316
|
context 'but there are 2 LGTMs and LGTM last comment' do
|
275
317
|
let(:lgtm_comment_authors) { ['nhance', 'Simon'] }
|
276
318
|
before do
|
277
|
-
existing_pull_request.
|
278
|
-
existing_pull_request.
|
279
|
-
existing_pull_request.
|
280
|
-
end
|
281
|
-
|
282
|
-
it "includes the pull request body in the commit message" do
|
283
|
-
squash_message = "#{existing_pull_request.body}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance, @Simon\n"
|
284
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).with(squash_message)
|
285
|
-
subject
|
319
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
320
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
321
|
+
allow(existing_pull_request).to receive_message_chain(:last_comment, :match).and_return(true)
|
286
322
|
end
|
287
323
|
|
288
324
|
context "build status failure, testing description and target_url" do
|
289
325
|
let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)', target_url: "www.error.com" }) }
|
290
326
|
|
291
327
|
before do
|
292
|
-
existing_pull_request.
|
293
|
-
existing_pull_request.
|
294
|
-
existing_pull_request.
|
328
|
+
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
329
|
+
allow(existing_pull_request).to receive(:reviewers).and_return(lgtm_comment_authors)
|
330
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
295
331
|
end
|
296
332
|
|
297
333
|
it "halts delivery and notifies user of a failed build" do
|
@@ -303,13 +339,13 @@ describe GitReflow do
|
|
303
339
|
let(:build_status) { nil }
|
304
340
|
|
305
341
|
before do
|
306
|
-
github.
|
307
|
-
existing_pull_request.
|
308
|
-
existing_pull_request.
|
342
|
+
allow(github).to receive(:build).and_return(build_status)
|
343
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
344
|
+
allow(existing_pull_request).to receive(:has_comments_or_approvals).and_return(true)
|
309
345
|
end
|
310
346
|
|
311
347
|
it "commits the changes if the build status is nil but has comments/approvals and no pending response" do
|
312
|
-
expect{ subject }.to have_said
|
348
|
+
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
313
349
|
end
|
314
350
|
end
|
315
351
|
|
@@ -318,48 +354,38 @@ describe GitReflow do
|
|
318
354
|
|
319
355
|
before do
|
320
356
|
existing_pull_request.description = ''
|
321
|
-
github.
|
322
|
-
GitReflow.
|
323
|
-
existing_pull_request.
|
324
|
-
end
|
325
|
-
|
326
|
-
it "includes the first commit message for the new branch in the commit message of the merge" do
|
327
|
-
squash_message = "#{first_commit_message}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance, @Simon\n"
|
328
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).with(squash_message)
|
329
|
-
subject
|
357
|
+
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
358
|
+
allow(GitReflow).to receive(:get_first_commit_message).and_return(first_commit_message)
|
359
|
+
allow(existing_pull_request).to receive(:reviewers).and_return(lgtm_comment_authors)
|
330
360
|
end
|
331
361
|
end
|
332
362
|
|
333
|
-
it "
|
334
|
-
GitReflow.
|
335
|
-
|
336
|
-
pull_request_number: existing_pull_request.number,
|
337
|
-
lgtm_authors: ['nhance', 'Simon'],
|
338
|
-
message: existing_pull_request.body
|
339
|
-
})
|
340
|
-
|
341
|
-
expect { subject }.to have_output "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'"
|
363
|
+
it "doesn't always deliver" do
|
364
|
+
expect(GitReflow::Config).to receive(:get).with("reflow.always-deliver").and_return("false")
|
365
|
+
expect { subject }.to have_said "Merge aborted", :deliver_halted
|
342
366
|
end
|
343
367
|
|
344
|
-
it "
|
345
|
-
|
346
|
-
subject
|
368
|
+
it "notifies user of the merge and performs it" do
|
369
|
+
expect { subject }.to have_said "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'", :notice
|
347
370
|
end
|
348
371
|
|
349
372
|
it "commits the changes for the squash merge" do
|
350
|
-
expect{ subject }.to have_said
|
373
|
+
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
351
374
|
end
|
352
375
|
|
353
376
|
context "and cleaning up feature branch" do
|
354
377
|
before do
|
355
|
-
HighLine.
|
378
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
356
379
|
values = {
|
357
380
|
"Please enter your GitHub username: " => user,
|
358
381
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
359
382
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
360
383
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
361
384
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'yes',
|
362
|
-
"Would you like to open it in your browser?" => 'no'
|
385
|
+
"Would you like to open it in your browser?" => 'no',
|
386
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
387
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
388
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
363
389
|
}
|
364
390
|
return_value = values[question] || values[terminal]
|
365
391
|
question = ""
|
@@ -369,11 +395,11 @@ describe GitReflow do
|
|
369
395
|
|
370
396
|
context "not always" do
|
371
397
|
before do
|
372
|
-
GitReflow::Config.
|
398
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("false")
|
373
399
|
end
|
374
400
|
|
375
|
-
it "
|
376
|
-
expect { subject }.to have_run_command("git
|
401
|
+
it "pulls changes from remote repo to local branch" do
|
402
|
+
expect { subject }.to have_run_command("git pull origin master")
|
377
403
|
end
|
378
404
|
|
379
405
|
it "deletes the remote feature branch" do
|
@@ -387,11 +413,15 @@ describe GitReflow do
|
|
387
413
|
|
388
414
|
context "always" do
|
389
415
|
before do
|
390
|
-
GitReflow::Config.
|
416
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
417
|
+
end
|
418
|
+
|
419
|
+
it "checks out the base branch" do
|
420
|
+
expect { subject }.to have_run_command("git checkout master")
|
391
421
|
end
|
392
422
|
|
393
|
-
it "
|
394
|
-
expect { subject }.to have_run_command("git
|
423
|
+
it "pulls changes from remote repo to local branch" do
|
424
|
+
expect { subject }.to have_run_command("git pull origin master")
|
395
425
|
end
|
396
426
|
|
397
427
|
it "deletes the remote feature branch" do
|
@@ -406,14 +436,17 @@ describe GitReflow do
|
|
406
436
|
|
407
437
|
context "and not cleaning up feature branch" do
|
408
438
|
before do
|
409
|
-
HighLine.
|
439
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
410
440
|
values = {
|
411
441
|
"Please enter your GitHub username: " => user,
|
412
442
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
413
443
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
414
444
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
415
445
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'no',
|
416
|
-
"Would you like to open it in your browser?" => 'no'
|
446
|
+
"Would you like to open it in your browser?" => 'no',
|
447
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
448
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
449
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
417
450
|
}
|
418
451
|
return_value = values[question] || values[terminal]
|
419
452
|
question = ""
|
@@ -421,8 +454,8 @@ describe GitReflow do
|
|
421
454
|
end
|
422
455
|
end
|
423
456
|
|
424
|
-
it "
|
425
|
-
expect { subject }.
|
457
|
+
it "does update the local repo with the new squash merge" do
|
458
|
+
expect { subject }.to have_run_command('git pull origin master')
|
426
459
|
end
|
427
460
|
|
428
461
|
it "doesn't delete the feature branch on the remote repo" do
|
@@ -434,22 +467,14 @@ describe GitReflow do
|
|
434
467
|
end
|
435
468
|
|
436
469
|
it "provides instructions to undo the steps taken" do
|
437
|
-
expect { subject }.to
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
context "and there were issues commiting the squash merge to the base branch" do
|
442
|
-
before { stub_with_fallback(GitReflow, :run_command_with_label).with('git commit', {with_system: true}).and_return false }
|
443
|
-
it "notifies user of issues commiting the squash merge of the feature branch" do
|
444
|
-
expect { subject }.to have_said("There were problems commiting your feature... please check the errors above and try again.", :error)
|
470
|
+
expect { subject }.to have_said("To reset and go back to your branch run \`git reset --hard origin/master && git checkout new-feature\`")
|
445
471
|
end
|
446
472
|
end
|
447
|
-
|
448
473
|
end
|
449
474
|
|
450
475
|
context 'but there are still unaddressed comments' do
|
451
476
|
let(:open_comment_authors) { ['nhance', 'codenamev'] }
|
452
|
-
before { existing_pull_request.
|
477
|
+
before { allow(existing_pull_request).to receive(:reviewers_pending_response).and_return(open_comment_authors) }
|
453
478
|
it "notifies the user to get their code reviewed" do
|
454
479
|
expect { subject }.to have_said "You still need a LGTM from: #{open_comment_authors.join(', ')}", :deliver_halted
|
455
480
|
end
|
@@ -458,35 +483,36 @@ describe GitReflow do
|
|
458
483
|
|
459
484
|
context 'but has no comments' do
|
460
485
|
before do
|
461
|
-
existing_pull_request.
|
462
|
-
existing_pull_request.
|
463
|
-
existing_pull_request.
|
464
|
-
existing_pull_request.
|
486
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(false)
|
487
|
+
allow(existing_pull_request).to receive(:approvals).and_return(['John', 'Simon'])
|
488
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
489
|
+
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
465
490
|
end
|
466
491
|
|
467
492
|
it "notifies the user to get their code reviewed" do
|
468
|
-
expect { subject }.to have_said "
|
493
|
+
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
469
494
|
end
|
470
495
|
end
|
471
496
|
|
472
497
|
it "successfully finds a pull request for the current feature branch" do
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
GitReflow.should_receive(:update_destination)
|
478
|
-
subject
|
498
|
+
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
499
|
+
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
500
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
501
|
+
expect { subject }.to have_said "Merging pull request #1: 'new-feature', from 'new-feature' into 'master'", :notice
|
479
502
|
end
|
480
503
|
|
481
504
|
it "merges and squashes the feature branch into the master branch" do
|
482
|
-
|
505
|
+
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
506
|
+
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
507
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
508
|
+
expect(existing_pull_request).to receive(:merge!).and_return(true)
|
483
509
|
subject
|
484
510
|
end
|
485
511
|
end
|
486
512
|
end
|
487
513
|
|
488
514
|
context "and no pull request exists for the feature branch to the destination branch" do
|
489
|
-
before { github.
|
515
|
+
before { allow(github).to receive(:find_open_pull_request).and_return(nil) }
|
490
516
|
|
491
517
|
it "notifies the user of a missing pull request" do
|
492
518
|
expect { subject }.to have_said "No pull request exists for #{user}:#{branch}\nPlease submit your branch for review first with \`git reflow review\`", :deliver_halted
|