git_reflow 0.7.5 → 0.8.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 +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
|