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
data/spec/git_reflow_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe GitReflow do
|
4
4
|
let(:git_server) { GitReflow::GitServer::GitHub.new {} }
|
5
|
-
let(:github)
|
5
|
+
let!(:github) { Github.new basic_auth: "#{user}:#{password}" }
|
6
6
|
let(:user) { 'reenhanced' }
|
7
7
|
let(:password) { 'shazam' }
|
8
8
|
let(:oauth_token_hash) { Hashie::Mash.new({ token: 'a1b2c3d4e5f6g7h8i9j0', note: 'hostname.local git-reflow'}) }
|
@@ -23,14 +23,17 @@ describe GitReflow do
|
|
23
23
|
allow(GitReflow::Config).to receive(:get).with("constants.minimumApprovals").and_return('')
|
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? " => 'yes',
|
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 = ""
|
@@ -45,28 +48,26 @@ describe GitReflow do
|
|
45
48
|
allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
|
46
49
|
allow(GitReflow).to receive(:destination_branch).and_return(base_branch)
|
47
50
|
|
48
|
-
allow(Github).to receive(:new).and_return(github)
|
51
|
+
allow(Github::Client).to receive(:new).and_return(github)
|
49
52
|
allow(GitReflow).to receive(:git_server).and_return(git_server)
|
50
53
|
allow(git_server).to receive(:connection).and_return(github)
|
51
54
|
allow(git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :target_url).new())
|
52
55
|
end
|
53
56
|
|
54
57
|
context 'with no existing pull request' do
|
55
|
-
before { git_server.
|
56
|
-
it { expect{ subject }.to
|
57
|
-
it { expect{ subject }.to
|
58
|
+
before { allow(git_server).to receive(:find_open_pull_request).with({from: feature_branch, to: base_branch}).and_return(nil) }
|
59
|
+
it { expect{ subject }.to have_said "\nNo pull request exists for #{feature_branch} -> #{base_branch}", :notice }
|
60
|
+
it { expect{ subject }.to have_said "Run 'git reflow review #{base_branch}' to start the review process", :notice }
|
58
61
|
end
|
59
62
|
|
60
63
|
context 'with an existing pull request' do
|
61
64
|
before do
|
62
|
-
git_server.
|
65
|
+
allow(git_server).to receive(:find_open_pull_request).with({from: feature_branch, to: base_branch}).and_return(existing_pull_request)
|
66
|
+
expect(existing_pull_request).to receive(:display_pull_request_summary)
|
63
67
|
end
|
64
68
|
|
65
69
|
it 'displays a summary of the pull request and asks to open it in the browser' do
|
66
|
-
|
67
|
-
GitReflow.should_receive(:ask_to_open_in_browser).with(existing_pull_request.html_url)
|
68
|
-
subject
|
69
|
-
$output.should include "Here's the status of your review:"
|
70
|
+
expect{ subject }.to have_said "Here's the status of your review:"
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
@@ -77,11 +78,11 @@ describe GitReflow do
|
|
77
78
|
let(:branch) { 'new-feature' }
|
78
79
|
let(:inputs) {
|
79
80
|
{
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
:title => "Amazing new feature",
|
82
|
+
:body => "Please pull this in!",
|
83
|
+
:head => "reenhanced:new-feature",
|
84
|
+
:base => "master",
|
85
|
+
:state => "open"
|
85
86
|
}
|
86
87
|
}
|
87
88
|
|
@@ -99,74 +100,69 @@ describe GitReflow do
|
|
99
100
|
subject { GitReflow.review inputs }
|
100
101
|
|
101
102
|
it "fetches the latest changes to the destination branch" do
|
102
|
-
GitReflow.
|
103
|
-
github.
|
104
|
-
github.
|
103
|
+
expect(GitReflow).to receive(:fetch_destination).with(inputs[:base])
|
104
|
+
expect(github).to receive(:find_open_pull_request).and_return(nil)
|
105
|
+
allow(github).to receive(:create_pull_request).and_return(existing_pull_request)
|
105
106
|
subject
|
106
107
|
end
|
107
108
|
|
108
109
|
it "pushes the latest current branch to the origin repo" do
|
109
|
-
GitReflow.
|
110
|
-
github.
|
111
|
-
github.
|
110
|
+
expect(GitReflow).to receive(:push_current_branch)
|
111
|
+
expect(github).to receive(:find_open_pull_request).and_return(nil)
|
112
|
+
allow(github).to receive(:create_pull_request).and_return(existing_pull_request)
|
112
113
|
subject
|
113
114
|
end
|
114
115
|
|
115
116
|
context "pull request doesn't exist" do
|
116
117
|
before do
|
117
|
-
github.
|
118
|
+
allow(github).to receive(:find_open_pull_request).and_return(nil)
|
118
119
|
end
|
119
120
|
|
120
121
|
it "successfully creates a pull request if I do not provide one" do
|
121
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[
|
122
|
-
github.
|
123
|
-
expect { subject }.to
|
122
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
123
|
+
expect(github).to receive(:create_pull_request).with(inputs.except(:state).symbolize_keys).and_return(existing_pull_request)
|
124
|
+
expect { subject }.to have_said "Successfully created pull request #1: #{inputs[:title]}\nPull Request URL: https://github.com/#{user}/#{repo}/pulls/1\n", :success
|
124
125
|
end
|
125
126
|
|
126
127
|
context "when providing only a title" do
|
127
128
|
before do
|
128
|
-
inputs[
|
129
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[
|
129
|
+
inputs[:body] = nil
|
130
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
130
131
|
end
|
131
132
|
|
132
133
|
it "successfully creates a pull request with only the provided title" do
|
133
|
-
github.
|
134
|
-
expect { subject }.to
|
134
|
+
expect(github).to receive(:create_pull_request).with(inputs.except(:state).symbolize_keys).and_return(existing_pull_request)
|
135
|
+
expect { subject }.to have_said "Successfully created pull request #1: #{inputs[:title]}\nPull Request URL: https://github.com/#{user}/#{repo}/pulls/1\n", :success
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
138
139
|
context "when providing only a message" do
|
139
140
|
before do
|
140
|
-
inputs[
|
141
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[
|
141
|
+
inputs[:title] = nil
|
142
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:body])
|
142
143
|
end
|
143
144
|
|
144
145
|
it "successfully creates a pull request with only the provided title" do
|
145
|
-
expected_options = inputs.except(
|
146
|
-
expected_options[
|
147
|
-
github.
|
148
|
-
expect { subject }.to
|
146
|
+
expected_options = inputs.except(:state)
|
147
|
+
expected_options[:title] = inputs[:body]
|
148
|
+
expect(github).to receive(:create_pull_request).with(expected_options.symbolize_keys).and_return(existing_pull_request)
|
149
|
+
expect { subject }.to have_said "Successfully created pull request #1: #{expected_options[:title]}\nPull Request URL: https://github.com/#{user}/#{repo}/pulls/1\n", :success
|
149
150
|
end
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
154
|
context "pull request exists" do
|
154
155
|
before do
|
155
|
-
GitReflow.
|
156
|
+
allow(GitReflow).to receive(:push_current_branch)
|
156
157
|
github_error = Github::Error::UnprocessableEntity.new( eval(Fixture.new('pull_requests/pull_request_exists_error.json').to_s) )
|
157
|
-
github.
|
158
|
-
existing_pull_request.
|
158
|
+
expect(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
159
|
+
allow(existing_pull_request).to receive(:display_pull_request_summary)
|
159
160
|
end
|
160
161
|
|
161
162
|
subject { GitReflow.review inputs }
|
162
163
|
|
163
164
|
it "displays a pull request summary for the existing pull request" do
|
164
|
-
existing_pull_request.
|
165
|
-
subject
|
166
|
-
end
|
167
|
-
|
168
|
-
it "asks to open the pull request in the browser" do
|
169
|
-
GitReflow.should_receive(:ask_to_open_in_browser).with(existing_pull_request.html_url)
|
165
|
+
expect(existing_pull_request).to receive(:display_pull_request_summary)
|
170
166
|
subject
|
171
167
|
end
|
172
168
|
end
|
@@ -174,7 +170,14 @@ describe GitReflow do
|
|
174
170
|
|
175
171
|
context :deliver do
|
176
172
|
let(:branch) { 'new-feature' }
|
177
|
-
let(:inputs)
|
173
|
+
let(:inputs) {
|
174
|
+
{
|
175
|
+
:title => "new-feature",
|
176
|
+
:message => "message",
|
177
|
+
:head => "reenhanced:new-feature"
|
178
|
+
}
|
179
|
+
}
|
180
|
+
let(:merge_response) { {} }
|
178
181
|
let!(:github) do
|
179
182
|
allow_any_instance_of(GitReflow::GitServer::GitHub::PullRequest).to receive(:build).and_return(Struct.new(:state, :description, :url).new)
|
180
183
|
stub_github_with({
|
@@ -186,9 +189,9 @@ describe GitReflow do
|
|
186
189
|
})
|
187
190
|
end
|
188
191
|
|
189
|
-
|
190
192
|
before do
|
191
|
-
GitReflow.
|
193
|
+
allow(GitReflow::GitServer::GitHub).to receive_message_chain(:connection, :pull_requests, :merge).and_return(merge_response)
|
194
|
+
allow(merge_response).to receive(:success?).and_return(true)
|
192
195
|
|
193
196
|
module Kernel
|
194
197
|
def system(cmd)
|
@@ -199,18 +202,8 @@ describe GitReflow do
|
|
199
202
|
|
200
203
|
subject { GitReflow.deliver inputs }
|
201
204
|
|
202
|
-
it "fetches the latest changes to the current branch" do
|
203
|
-
GitReflow.should_receive(:update_current_branch)
|
204
|
-
subject
|
205
|
-
end
|
206
|
-
|
207
|
-
it "fetches the latest changes to the destination branch" do
|
208
|
-
GitReflow.should_receive(:fetch_destination).with('master')
|
209
|
-
subject
|
210
|
-
end
|
211
|
-
|
212
205
|
it "looks for a pull request matching the feature branch and destination branch" do
|
213
|
-
github.
|
206
|
+
expect(github).to receive(:find_open_pull_request).with(from: branch, to: 'master')
|
214
207
|
subject
|
215
208
|
end
|
216
209
|
|
@@ -219,6 +212,9 @@ describe GitReflow do
|
|
219
212
|
allow(github).to receive(:build_status).and_return(build_status)
|
220
213
|
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
221
214
|
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
215
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-deliver").and_return("true")
|
216
|
+
allow(GitReflow).to receive(:status)
|
217
|
+
|
222
218
|
allow(github).to receive(:reviewers).and_return(['codenamev'])
|
223
219
|
end
|
224
220
|
|
@@ -233,23 +229,57 @@ describe GitReflow do
|
|
233
229
|
it "halts delivery and notifies user of a failed build" do
|
234
230
|
expect { subject }.to have_said "#{build_status.description}: #{build_status.target_url}", :deliver_halted
|
235
231
|
end
|
232
|
+
|
233
|
+
context 'forces a merge' do
|
234
|
+
let(:lgtm_comment_authors) { ['nhance'] }
|
235
|
+
before do
|
236
|
+
inputs[:skip_lgtm] = true
|
237
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
238
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
239
|
+
allow(GitReflow).to receive(:append_to_squashed_commit_message)
|
240
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
241
|
+
end
|
242
|
+
|
243
|
+
it "checks out the base branch" do
|
244
|
+
expect { subject }.to have_run_command("git checkout master")
|
245
|
+
end
|
246
|
+
|
247
|
+
it "pulls changes from remote repo to local branch" do
|
248
|
+
expect { subject }.to have_run_command("git pull origin master")
|
249
|
+
end
|
250
|
+
|
251
|
+
it "pushes the changes to remote repo" do
|
252
|
+
expect { subject }.to have_run_command("git push origin master")
|
253
|
+
end
|
254
|
+
|
255
|
+
it "deletes the remote feature branch" do
|
256
|
+
expect { subject }.to have_run_command("git push origin :new-feature")
|
257
|
+
end
|
258
|
+
|
259
|
+
it "deletes the local feature branch" do
|
260
|
+
expect { subject }.to have_run_command("git branch -D new-feature")
|
261
|
+
end
|
262
|
+
|
263
|
+
it "forces a merge" do
|
264
|
+
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
|
265
|
+
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
266
|
+
end
|
267
|
+
end
|
236
268
|
end
|
237
269
|
|
238
270
|
context 'and build status is nil' do
|
239
271
|
let(:build_status) { nil }
|
240
|
-
let(:
|
272
|
+
let(:lgtm_comment_authors) { ['nhance'] }
|
241
273
|
|
242
274
|
before do
|
243
275
|
# stubbing unrelated results so we can just test that it made it insdide the conditional block
|
244
|
-
|
245
|
-
allow(existing_pull_request).to receive(:
|
246
|
-
|
247
|
-
GitReflow.stub(:merge_feature_branch).and_return(true)
|
248
|
-
GitReflow.stub(:append_to_squashed_commit_message).and_return(true)
|
276
|
+
inputs[:skip_lgtm] = false
|
277
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
278
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
249
279
|
end
|
250
280
|
|
251
281
|
it "ignores build status when not setup" do
|
252
|
-
expect { subject }.to have_said "
|
282
|
+
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
253
283
|
end
|
254
284
|
end
|
255
285
|
|
@@ -258,29 +288,24 @@ describe GitReflow do
|
|
258
288
|
|
259
289
|
context 'and has comments' do
|
260
290
|
before do
|
261
|
-
|
291
|
+
inputs[:skip_lgtm] = false
|
292
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
262
293
|
end
|
263
294
|
|
264
295
|
context 'but there is a LGTM' do
|
265
296
|
let(:lgtm_comment_authors) { ['nhance'] }
|
266
297
|
before do
|
267
|
-
existing_pull_request.
|
268
|
-
existing_pull_request.
|
269
|
-
end
|
270
|
-
|
271
|
-
it "includes the pull request body in the commit message" do
|
272
|
-
squash_message = "#{existing_pull_request.body}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance\n"
|
273
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).with(squash_message)
|
274
|
-
subject
|
298
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
299
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
275
300
|
end
|
276
301
|
|
277
302
|
context "build status failure, testing description and target_url" do
|
278
303
|
let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)', target_url: "www.error.com" }) }
|
279
304
|
|
280
305
|
before do
|
281
|
-
existing_pull_request.
|
282
|
-
existing_pull_request.
|
283
|
-
existing_pull_request.
|
306
|
+
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
307
|
+
allow(existing_pull_request).to receive(:reviewers).and_return(lgtm_comment_authors)
|
308
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
284
309
|
end
|
285
310
|
|
286
311
|
it "halts delivery and notifies user of a failed build" do
|
@@ -292,13 +317,13 @@ describe GitReflow do
|
|
292
317
|
let(:build_status) { nil }
|
293
318
|
|
294
319
|
before do
|
295
|
-
github.
|
296
|
-
existing_pull_request.
|
297
|
-
existing_pull_request.
|
320
|
+
allow(github).to receive(:build).and_return(build_status)
|
321
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
322
|
+
allow(existing_pull_request).to receive(:has_comments_or_approvals).and_return(true)
|
298
323
|
end
|
299
324
|
|
300
325
|
it "commits the changes if the build status is nil but has comments/approvals and no pending response" do
|
301
|
-
expect{ subject }.to have_said
|
326
|
+
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
302
327
|
end
|
303
328
|
end
|
304
329
|
|
@@ -307,48 +332,33 @@ describe GitReflow do
|
|
307
332
|
|
308
333
|
before do
|
309
334
|
existing_pull_request.description = ''
|
310
|
-
github.
|
311
|
-
GitReflow.
|
312
|
-
existing_pull_request.
|
313
|
-
end
|
314
|
-
|
315
|
-
it "includes the first commit message for the new branch in the commit message of the merge" do
|
316
|
-
squash_message = "#{first_commit_message}\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @nhance\n"
|
317
|
-
GitReflow.should_receive(:append_to_squashed_commit_message).with(squash_message)
|
318
|
-
subject
|
335
|
+
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
336
|
+
allow(GitReflow).to receive(:get_first_commit_message).and_return(first_commit_message)
|
337
|
+
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
319
338
|
end
|
320
339
|
end
|
321
340
|
|
322
341
|
it "notifies user of the merge and performs it" do
|
323
|
-
|
324
|
-
destination_branch: 'master',
|
325
|
-
pull_request_number: existing_pull_request.number,
|
326
|
-
lgtm_authors: ['nhance'],
|
327
|
-
message: existing_pull_request.body
|
328
|
-
})
|
329
|
-
|
330
|
-
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}'"
|
331
|
-
end
|
332
|
-
|
333
|
-
it "updates the destination brnach" do
|
334
|
-
GitReflow.should_receive(:update_destination).with('master')
|
335
|
-
subject
|
342
|
+
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
|
336
343
|
end
|
337
344
|
|
338
345
|
it "commits the changes for the squash merge" do
|
339
|
-
expect{ subject }.to have_said
|
346
|
+
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
340
347
|
end
|
341
348
|
|
342
349
|
context "and cleaning up feature branch" do
|
343
350
|
before do
|
344
|
-
HighLine.
|
351
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
345
352
|
values = {
|
346
353
|
"Please enter your GitHub username: " => user,
|
347
354
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
348
355
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
349
356
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
350
357
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'yes',
|
351
|
-
"Would you like to open it in your browser?" => 'no'
|
358
|
+
"Would you like to open it in your browser?" => 'no',
|
359
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
360
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
361
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
352
362
|
}
|
353
363
|
return_value = values[question] || values[terminal]
|
354
364
|
question = ""
|
@@ -358,12 +368,15 @@ describe GitReflow do
|
|
358
368
|
|
359
369
|
context "not always" do
|
360
370
|
before do
|
361
|
-
GitReflow::Config.
|
362
|
-
GitReflow::Config.stub(:get).and_call_original
|
371
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("false")
|
363
372
|
end
|
364
373
|
|
365
|
-
it "
|
366
|
-
expect { subject }.to have_run_command("git
|
374
|
+
it "checks out the base branch" do
|
375
|
+
expect { subject }.to have_run_command("git checkout master")
|
376
|
+
end
|
377
|
+
|
378
|
+
it "pulls changes from remote repo to local branch" do
|
379
|
+
expect { subject }.to have_run_command("git pull origin master")
|
367
380
|
end
|
368
381
|
|
369
382
|
it "deletes the remote feature branch" do
|
@@ -377,12 +390,15 @@ describe GitReflow do
|
|
377
390
|
|
378
391
|
context "always" do
|
379
392
|
before do
|
380
|
-
GitReflow::Config.
|
381
|
-
|
393
|
+
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
394
|
+
end
|
395
|
+
|
396
|
+
it "checks out the base branch" do
|
397
|
+
expect { subject }.to have_run_command("git checkout master")
|
382
398
|
end
|
383
399
|
|
384
|
-
it "
|
385
|
-
expect { subject }.to have_run_command("git
|
400
|
+
it "pulls changes from remote repo to local branch" do
|
401
|
+
expect { subject }.to have_run_command("git pull origin master")
|
386
402
|
end
|
387
403
|
|
388
404
|
it "deletes the remote feature branch" do
|
@@ -398,14 +414,17 @@ describe GitReflow do
|
|
398
414
|
|
399
415
|
context "and not cleaning up feature branch" do
|
400
416
|
before do
|
401
|
-
HighLine.
|
417
|
+
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
402
418
|
values = {
|
403
419
|
"Please enter your GitHub username: " => user,
|
404
420
|
"Please enter your GitHub password (we do NOT store this): " => password,
|
405
421
|
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
406
422
|
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
407
423
|
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'no',
|
408
|
-
"Would you like to open it in your browser?" => 'no'
|
424
|
+
"Would you like to open it in your browser?" => 'no',
|
425
|
+
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
426
|
+
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
427
|
+
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
409
428
|
}
|
410
429
|
return_value = values[question] || values[terminal]
|
411
430
|
question = ""
|
@@ -413,8 +432,12 @@ describe GitReflow do
|
|
413
432
|
end
|
414
433
|
end
|
415
434
|
|
416
|
-
it "
|
417
|
-
expect { subject }.
|
435
|
+
it "does checkout the local base branch" do
|
436
|
+
expect { subject }.to have_run_command("git checkout master")
|
437
|
+
end
|
438
|
+
|
439
|
+
it "does update the local repo with the new squash merge" do
|
440
|
+
expect { subject }.to have_run_command('git pull origin master')
|
418
441
|
end
|
419
442
|
|
420
443
|
it "doesn't delete the feature branch on the remote repo" do
|
@@ -426,22 +449,14 @@ describe GitReflow do
|
|
426
449
|
end
|
427
450
|
|
428
451
|
it "provides instructions to undo the steps taken" do
|
429
|
-
expect { subject }.to
|
452
|
+
expect { subject }.to have_said("To reset and go back to your branch run \`git reset --hard origin/master && git checkout new-feature\`")
|
430
453
|
end
|
431
454
|
end
|
432
|
-
|
433
|
-
context "and there were issues commiting the squash merge to the base branch" do
|
434
|
-
before { stub_with_fallback(GitReflow, :run_command_with_label).with('git commit', {with_system: true}).and_return false }
|
435
|
-
it "notifies user of issues commiting the squash merge of the feature branch" do
|
436
|
-
expect { subject }.to have_said("There were problems commiting your feature... please check the errors above and try again.", :error)
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
455
|
end
|
441
456
|
|
442
457
|
context 'but there are still unaddressed comments' do
|
443
458
|
let(:open_comment_authors) { ['nhance', 'codenamev'] }
|
444
|
-
before { existing_pull_request.
|
459
|
+
before { allow(existing_pull_request).to receive(:reviewers_pending_response).and_return(open_comment_authors) }
|
445
460
|
it "notifies the user to get their code reviewed" do
|
446
461
|
expect { subject }.to have_said "You still need a LGTM from: #{open_comment_authors.join(', ')}", :deliver_halted
|
447
462
|
end
|
@@ -450,9 +465,9 @@ describe GitReflow do
|
|
450
465
|
|
451
466
|
context 'but has no comments' do
|
452
467
|
before do
|
453
|
-
existing_pull_request.
|
454
|
-
existing_pull_request.
|
455
|
-
existing_pull_request.
|
468
|
+
allow(existing_pull_request).to receive(:has_comments?).and_return(false)
|
469
|
+
allow(existing_pull_request).to receive(:approvals).and_return([])
|
470
|
+
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
456
471
|
end
|
457
472
|
|
458
473
|
it "notifies the user to get their code reviewed" do
|
@@ -461,23 +476,24 @@ describe GitReflow do
|
|
461
476
|
end
|
462
477
|
|
463
478
|
it "successfully finds a pull request for the current feature branch" do
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
GitReflow.should_receive(:update_destination)
|
469
|
-
subject
|
479
|
+
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
480
|
+
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
481
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
482
|
+
expect { subject }.to have_said "Merging pull request #1: 'new-feature', from 'new-feature' into 'master'", :notice
|
470
483
|
end
|
471
484
|
|
472
485
|
it "merges and squashes the feature branch into the master branch" do
|
473
|
-
|
486
|
+
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
487
|
+
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
488
|
+
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
489
|
+
expect(existing_pull_request).to receive(:merge!).and_return(true)
|
474
490
|
subject
|
475
491
|
end
|
476
492
|
end
|
477
493
|
end
|
478
494
|
|
479
495
|
context "and no pull request exists for the feature branch to the destination branch" do
|
480
|
-
before { github.
|
496
|
+
before { allow(github).to receive(:find_open_pull_request).and_return(nil) }
|
481
497
|
|
482
498
|
it "notifies the user of a missing pull request" do
|
483
499
|
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
|