git_reflow 0.8.3 → 0.8.4
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/CHANGELOG.md +16 -1
- data/Gemfile.lock +6 -5
- data/git_reflow.gemspec +4 -0
- data/lib/git_reflow/commands/deliver.rb +1 -6
- data/lib/git_reflow/commands/refresh.rb +2 -5
- data/lib/git_reflow/commands/review.rb +2 -10
- data/lib/git_reflow/commands/setup.rb +1 -23
- data/lib/git_reflow/commands/stage.rb +1 -23
- data/lib/git_reflow/commands/start.rb +3 -8
- data/lib/git_reflow/commands/status.rb +1 -2
- data/lib/git_reflow/config.rb +1 -1
- data/lib/git_reflow/git_server/git_hub/pull_request.rb +3 -3
- data/lib/git_reflow/rspec/command_line_helpers.rb +5 -0
- data/lib/git_reflow/version.rb +1 -1
- data/lib/git_reflow/workflow.rb +54 -0
- data/lib/git_reflow/workflows/core.rb +240 -0
- data/lib/git_reflow.rb +18 -117
- data/spec/lib/git_reflow/workflow_spec.rb +56 -0
- data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
- data/spec/lib/git_reflow_spec.rb +17 -526
- metadata +28 -4
- data/spec/lgtm_git_reflow_spec.rb +0 -522
data/spec/lib/git_reflow_spec.rb
CHANGED
@@ -1,547 +1,38 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe GitReflow do
|
4
|
-
let(:git_server) { GitReflow::GitServer::GitHub.new {} }
|
5
|
-
let!(:github) { Github.new basic_auth: "#{user}:#{password}" }
|
6
|
-
let(:user) { 'reenhanced' }
|
7
|
-
let(:password) { 'shazam' }
|
8
|
-
let(:oauth_token_hash) { Hashie::Mash.new({ token: 'a1b2c3d4e5f6g7h8i9j0', note: 'hostname.local git-reflow'}) }
|
9
|
-
let(:repo) { 'repo' }
|
10
|
-
let(:base_branch) { 'master' }
|
11
|
-
let(:feature_branch) { 'new-feature' }
|
12
|
-
let(:enterprise_site) { 'https://github.reenhanced.com' }
|
13
|
-
let(:enterprise_api) { 'https://github.reenhanced.com' }
|
14
|
-
let(:hostname) { 'hostname.local' }
|
15
4
|
|
16
|
-
|
17
|
-
|
18
|
-
let(:existing_pull_request) { GitReflow::GitServer::GitHub::PullRequest.new existing_pull_requests.first }
|
5
|
+
describe ".default_editor" do
|
6
|
+
subject { GitReflow.default_editor }
|
19
7
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
allow(GitReflow::Config).to receive(:get).with("constants.minimumApprovals").and_return('')
|
24
|
-
allow(GitReflow::Config).to receive(:get).and_call_original
|
25
|
-
|
26
|
-
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
27
|
-
values = {
|
28
|
-
"Please enter your GitHub username: " => user,
|
29
|
-
"Please enter your GitHub password (we do NOT store this): " => password,
|
30
|
-
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
31
|
-
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
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',
|
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'
|
37
|
-
}
|
38
|
-
return_value = values[question] || values[terminal]
|
39
|
-
question = ""
|
40
|
-
return_value
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context :status do
|
45
|
-
subject { GitReflow.status(base_branch) }
|
46
|
-
|
47
|
-
before do
|
48
|
-
allow(GitReflow).to receive(:current_branch).and_return(feature_branch)
|
49
|
-
allow(GitReflow).to receive(:destination_branch).and_return(base_branch)
|
50
|
-
|
51
|
-
allow(Github::Client).to receive(:new).and_return(github)
|
52
|
-
allow(GitReflow).to receive(:git_server).and_return(git_server)
|
53
|
-
allow(git_server).to receive(:connection).and_return(github)
|
54
|
-
allow(git_server).to receive(:get_build_status).and_return(Struct.new(:state, :description, :target_url).new())
|
8
|
+
context "when the environment has EDITOR set" do
|
9
|
+
before { allow(ENV).to receive(:[]).with('EDITOR').and_return('emacs') }
|
10
|
+
specify { expect( subject ).to eql('emacs') }
|
55
11
|
end
|
56
12
|
|
57
|
-
context
|
58
|
-
before
|
59
|
-
|
60
|
-
it { expect{ subject }.to have_said "Run 'git reflow review #{base_branch}' to start the review process", :notice }
|
61
|
-
end
|
62
|
-
|
63
|
-
context 'with an existing pull request' do
|
64
|
-
before do
|
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)
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'displays a summary of the pull request and asks to open it in the browser' do
|
70
|
-
expect{ subject }.to have_said "Here's the status of your review:"
|
71
|
-
end
|
13
|
+
context "when the environment has no EDITOR set" do
|
14
|
+
before { allow(ENV).to receive(:[]).with('EDITOR').and_return(nil) }
|
15
|
+
specify { expect( subject ).to eql('vi') }
|
72
16
|
end
|
73
17
|
end
|
74
18
|
|
75
|
-
|
76
|
-
|
77
|
-
context :review do
|
78
|
-
let(:branch) { 'new-feature' }
|
79
|
-
let(:inputs) {
|
80
|
-
{
|
81
|
-
:title => "Amazing new feature",
|
82
|
-
:body => "Please pull this in!",
|
83
|
-
:head => "reenhanced:new-feature",
|
84
|
-
:base => "master",
|
85
|
-
:state => "open"
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
let(:github) do
|
90
|
-
allow_any_instance_of(GitReflow::GitServer::GitHub::PullRequest).to receive(:build).and_return(Struct.new(:state, :description, :url).new)
|
91
|
-
stub_github_with({
|
92
|
-
:user => user,
|
93
|
-
:password => password,
|
94
|
-
:repo => repo,
|
95
|
-
:branch => branch,
|
96
|
-
:pull => Hashie::Mash.new(inputs)
|
97
|
-
})
|
98
|
-
end
|
99
|
-
|
100
|
-
subject { GitReflow.review inputs }
|
101
|
-
|
102
|
-
it "fetches the latest changes to the destination branch" do
|
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)
|
106
|
-
subject
|
107
|
-
end
|
108
|
-
|
109
|
-
it "pushes the latest current branch to the origin repo" do
|
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)
|
113
|
-
subject
|
114
|
-
end
|
115
|
-
|
116
|
-
context "pull request doesn't exist" do
|
117
|
-
before do
|
118
|
-
allow(github).to receive(:find_open_pull_request).and_return(nil)
|
119
|
-
end
|
120
|
-
|
121
|
-
it "successfully creates a pull request if I do not provide one" do
|
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
|
125
|
-
end
|
126
|
-
|
127
|
-
context "when providing only a title" do
|
128
|
-
before do
|
129
|
-
inputs[:body] = nil
|
130
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
131
|
-
end
|
132
|
-
|
133
|
-
it "successfully creates a pull request with only the provided title" do
|
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
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context "when providing only a message" do
|
140
|
-
before do
|
141
|
-
inputs[:title] = nil
|
142
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[:body])
|
143
|
-
end
|
144
|
-
|
145
|
-
it "successfully creates a pull request with only the provided title" do
|
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
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
context "pull request exists" do
|
155
|
-
before do
|
156
|
-
allow(GitReflow).to receive(:push_current_branch)
|
157
|
-
github_error = Github::Error::UnprocessableEntity.new( eval(Fixture.new('pull_requests/pull_request_exists_error.json').to_s) )
|
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)
|
160
|
-
end
|
161
|
-
|
162
|
-
subject { GitReflow.review inputs }
|
163
|
-
|
164
|
-
it "displays a pull request summary for the existing pull request" do
|
165
|
-
expect(existing_pull_request).to receive(:display_pull_request_summary)
|
166
|
-
subject
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context :deliver do
|
172
|
-
let(:branch) { 'new-feature' }
|
173
|
-
let(:inputs) {
|
174
|
-
{
|
175
|
-
:title => "new-feature",
|
176
|
-
:message => "message",
|
177
|
-
:head => "reenhanced:new-feature"
|
178
|
-
}
|
179
|
-
}
|
180
|
-
let(:merge_response) { {} }
|
181
|
-
let!(:github) do
|
182
|
-
allow_any_instance_of(GitReflow::GitServer::GitHub::PullRequest).to receive(:build).and_return(Struct.new(:state, :description, :url).new)
|
183
|
-
stub_github_with({
|
184
|
-
:user => user,
|
185
|
-
:password => password,
|
186
|
-
:repo => repo,
|
187
|
-
:branch => branch,
|
188
|
-
:pull => existing_pull_request
|
189
|
-
})
|
190
|
-
end
|
19
|
+
describe ".git_server" do
|
20
|
+
subject { GitReflow.git_server }
|
191
21
|
|
192
22
|
before do
|
193
|
-
allow(GitReflow::
|
194
|
-
allow(merge_response).to receive(:success?).and_return(true)
|
195
|
-
|
196
|
-
module Kernel
|
197
|
-
def system(cmd)
|
198
|
-
"call #{cmd}"
|
199
|
-
end
|
200
|
-
end
|
23
|
+
allow(GitReflow::Config).to receive(:get).with('reflow.git-server').and_return('GitHub ')
|
201
24
|
end
|
202
25
|
|
203
|
-
|
204
|
-
|
205
|
-
it "looks for a pull request matching the feature branch and destination branch" do
|
206
|
-
expect(github).to receive(:find_open_pull_request).with(from: branch, to: 'master')
|
26
|
+
it "attempts to connect to the provider" do
|
27
|
+
expect(GitReflow::GitServer).to receive(:connect).with(provider: 'GitHub', silent: true)
|
207
28
|
subject
|
208
29
|
end
|
209
|
-
|
210
|
-
context "and a base branch is provided" do
|
211
|
-
let(:inputs) { { title: "new-feature", message: "message", head: "reenhanced:new-feature", base: 'live'}}
|
212
|
-
it "looks for a pull request with the custom base branch" do
|
213
|
-
expect(github).to receive(:find_open_pull_request).with(from: branch, to: inputs[:base])
|
214
|
-
subject
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
context "and pull request exists for the feature branch to the destination branch" do
|
219
|
-
before do
|
220
|
-
allow(github).to receive(:build_status).and_return(build_status)
|
221
|
-
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
222
|
-
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
223
|
-
allow(GitReflow::Config).to receive(:get).with("reflow.always-deliver").and_return("true")
|
224
|
-
allow(GitReflow).to receive(:status)
|
225
|
-
|
226
|
-
allow(github).to receive(:reviewers).and_return(['codenamev'])
|
227
|
-
end
|
228
|
-
|
229
|
-
context 'and build status is not "success"' do
|
230
|
-
let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)' }) }
|
231
|
-
|
232
|
-
before do
|
233
|
-
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
234
|
-
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
235
|
-
end
|
236
|
-
|
237
|
-
it "halts delivery and notifies user of a failed build" do
|
238
|
-
expect { subject }.to have_said "#{build_status.description}: #{build_status.target_url}", :deliver_halted
|
239
|
-
end
|
240
|
-
|
241
|
-
context 'forces a merge' do
|
242
|
-
let(:lgtm_comment_authors) { ['nhance'] }
|
243
|
-
before do
|
244
|
-
inputs[:skip_lgtm] = true
|
245
|
-
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
246
|
-
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
247
|
-
allow(GitReflow).to receive(:append_to_squashed_commit_message)
|
248
|
-
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
249
|
-
end
|
250
|
-
|
251
|
-
it "checks out the base branch" do
|
252
|
-
expect { subject }.to have_run_command("git checkout master")
|
253
|
-
end
|
254
|
-
|
255
|
-
it "pulls changes from remote repo to local branch" do
|
256
|
-
expect { subject }.to have_run_command("git pull origin master")
|
257
|
-
end
|
258
|
-
|
259
|
-
it "pushes the changes to remote repo" do
|
260
|
-
expect { subject }.to have_run_command("git push origin master")
|
261
|
-
end
|
262
|
-
|
263
|
-
it "deletes the remote feature branch" do
|
264
|
-
expect { subject }.to have_run_command("git push origin :new-feature")
|
265
|
-
end
|
266
|
-
|
267
|
-
it "deletes the local feature branch" do
|
268
|
-
expect { subject }.to have_run_command("git branch -D new-feature")
|
269
|
-
end
|
270
|
-
|
271
|
-
it "forces a merge" do
|
272
|
-
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
|
273
|
-
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
context 'and build status is nil' do
|
279
|
-
let(:build_status) { nil }
|
280
|
-
let(:lgtm_comment_authors) { ['nhance'] }
|
281
|
-
|
282
|
-
before do
|
283
|
-
# stubbing unrelated results so we can just test that it made it insdide the conditional block
|
284
|
-
inputs[:skip_lgtm] = false
|
285
|
-
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
286
|
-
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
287
|
-
end
|
288
|
-
|
289
|
-
it "ignores build status when not setup" do
|
290
|
-
expect { subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
context 'and build status is "success"' do
|
295
|
-
let(:build_status) { Hashie::Mash.new({ state: 'success' }) }
|
296
|
-
|
297
|
-
context 'and has comments' do
|
298
|
-
before do
|
299
|
-
inputs[:skip_lgtm] = false
|
300
|
-
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
301
|
-
end
|
302
|
-
|
303
|
-
context 'but there is a LGTM' do
|
304
|
-
let(:lgtm_comment_authors) { ['nhance'] }
|
305
|
-
before do
|
306
|
-
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
307
|
-
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
308
|
-
end
|
309
|
-
|
310
|
-
context "build status failure, testing description and target_url" do
|
311
|
-
let(:build_status) { Hashie::Mash.new({ state: 'failure', description: 'Build resulted in failed test(s)', target_url: "www.error.com" }) }
|
312
|
-
|
313
|
-
before do
|
314
|
-
allow(existing_pull_request).to receive(:build).and_return(build_status)
|
315
|
-
allow(existing_pull_request).to receive(:reviewers).and_return(lgtm_comment_authors)
|
316
|
-
allow(existing_pull_request).to receive(:has_comments?).and_return(true)
|
317
|
-
end
|
318
|
-
|
319
|
-
it "halts delivery and notifies user of a failed build" do
|
320
|
-
expect { subject }.to have_said "#{build_status.description}: #{build_status.url}", :deliver_halted
|
321
|
-
end
|
322
|
-
end
|
323
|
-
|
324
|
-
context "build status nil" do
|
325
|
-
let(:build_status) { nil }
|
326
|
-
|
327
|
-
before do
|
328
|
-
allow(github).to receive(:build).and_return(build_status)
|
329
|
-
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
330
|
-
allow(existing_pull_request).to receive(:has_comments_or_approvals).and_return(true)
|
331
|
-
end
|
332
|
-
|
333
|
-
it "commits the changes if the build status is nil but has comments/approvals and no pending response" do
|
334
|
-
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
context "and the pull request has no body" do
|
339
|
-
let(:first_commit_message) { "We'll do it live." }
|
340
|
-
|
341
|
-
before do
|
342
|
-
existing_pull_request.description = ''
|
343
|
-
allow(github).to receive(:find_open_pull_request).and_return(existing_pull_request)
|
344
|
-
allow(GitReflow).to receive(:get_first_commit_message).and_return(first_commit_message)
|
345
|
-
allow(existing_pull_request).to receive(:approvals).and_return(lgtm_comment_authors)
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
it "notifies user of the merge and performs it" do
|
350
|
-
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
|
351
|
-
end
|
352
|
-
|
353
|
-
it "commits the changes for the squash merge" do
|
354
|
-
expect{ subject }.to have_said "Pull request ##{existing_pull_request.number} successfully merged.", :success
|
355
|
-
end
|
356
|
-
|
357
|
-
context "and cleaning up feature branch" do
|
358
|
-
before do
|
359
|
-
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
360
|
-
values = {
|
361
|
-
"Please enter your GitHub username: " => user,
|
362
|
-
"Please enter your GitHub password (we do NOT store this): " => password,
|
363
|
-
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
364
|
-
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
365
|
-
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'yes',
|
366
|
-
"Would you like to open it in your browser?" => 'no',
|
367
|
-
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
368
|
-
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
369
|
-
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
370
|
-
}
|
371
|
-
return_value = values[question] || values[terminal]
|
372
|
-
question = ""
|
373
|
-
return_value
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
context "not always" do
|
378
|
-
before do
|
379
|
-
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("false")
|
380
|
-
end
|
381
|
-
|
382
|
-
it "checks out the base branch" do
|
383
|
-
expect { subject }.to have_run_command("git checkout master")
|
384
|
-
end
|
385
|
-
|
386
|
-
it "pulls changes from remote repo to local branch" do
|
387
|
-
expect { subject }.to have_run_command("git pull origin master")
|
388
|
-
end
|
389
|
-
|
390
|
-
it "deletes the remote feature branch" do
|
391
|
-
expect { subject }.to have_run_command("git push origin :new-feature")
|
392
|
-
end
|
393
|
-
|
394
|
-
it "deletes the local feature branch" do
|
395
|
-
expect { subject }.to have_run_command("git branch -D new-feature")
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
context "always" do
|
400
|
-
before do
|
401
|
-
allow(GitReflow::Config).to receive(:get).with("reflow.always-cleanup").and_return("true")
|
402
|
-
end
|
403
|
-
|
404
|
-
it "checks out the base branch" do
|
405
|
-
expect { subject }.to have_run_command("git checkout master")
|
406
|
-
end
|
407
|
-
|
408
|
-
it "pulls changes from remote repo to local branch" do
|
409
|
-
expect { subject }.to have_run_command("git pull origin master")
|
410
|
-
end
|
411
|
-
|
412
|
-
it "deletes the remote feature branch" do
|
413
|
-
expect { subject }.to have_run_command("git push origin :new-feature")
|
414
|
-
end
|
415
|
-
|
416
|
-
it "deletes the local feature branch" do
|
417
|
-
expect { subject }.to have_run_command("git branch -D new-feature")
|
418
|
-
end
|
419
|
-
end
|
420
|
-
|
421
|
-
end
|
422
|
-
|
423
|
-
context "and not cleaning up feature branch" do
|
424
|
-
before do
|
425
|
-
allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
|
426
|
-
values = {
|
427
|
-
"Please enter your GitHub username: " => user,
|
428
|
-
"Please enter your GitHub password (we do NOT store this): " => password,
|
429
|
-
"Please enter your Enterprise site URL (e.g. https://github.company.com):" => enterprise_site,
|
430
|
-
"Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):" => enterprise_api,
|
431
|
-
"Would you like to push this branch to your remote repo and cleanup your feature branch? " => 'no',
|
432
|
-
"Would you like to open it in your browser?" => 'no',
|
433
|
-
"This is the current status of your Pull Request. Are you sure you want to deliver? " => 'y',
|
434
|
-
"Please enter your delivery commit title: (leaving blank will use default)" => 'title',
|
435
|
-
"Please enter your delivery commit message: (leaving blank will use default)" => 'message'
|
436
|
-
}
|
437
|
-
return_value = values[question] || values[terminal]
|
438
|
-
question = ""
|
439
|
-
return_value
|
440
|
-
end
|
441
|
-
end
|
442
|
-
|
443
|
-
it "does checkout the local base branch" do
|
444
|
-
expect { subject }.to have_run_command("git checkout master")
|
445
|
-
end
|
446
|
-
|
447
|
-
it "does update the local repo with the new squash merge" do
|
448
|
-
expect { subject }.to have_run_command('git pull origin master')
|
449
|
-
end
|
450
|
-
|
451
|
-
it "doesn't delete the feature branch on the remote repo" do
|
452
|
-
expect { subject }.to_not have_run_command('git push origin :new-feature')
|
453
|
-
end
|
454
|
-
|
455
|
-
it "doesn't delete the local feature branch" do
|
456
|
-
expect { subject }.to_not have_run_command('git branch -D new-feature')
|
457
|
-
end
|
458
|
-
|
459
|
-
it "provides instructions to undo the steps taken" do
|
460
|
-
expect { subject }.to have_said("To reset and go back to your branch run \`git reset --hard origin/master && git checkout new-feature\`")
|
461
|
-
end
|
462
|
-
end
|
463
|
-
end
|
464
|
-
|
465
|
-
context 'but there are still unaddressed comments' do
|
466
|
-
let(:open_comment_authors) { ['nhance', 'codenamev'] }
|
467
|
-
before { allow(existing_pull_request).to receive(:reviewers_pending_response).and_return(open_comment_authors) }
|
468
|
-
it "notifies the user to get their code reviewed" do
|
469
|
-
expect { subject }.to have_said "You still need a LGTM from: #{open_comment_authors.join(', ')}", :deliver_halted
|
470
|
-
end
|
471
|
-
end
|
472
|
-
end
|
473
|
-
|
474
|
-
context 'but has no comments' do
|
475
|
-
before do
|
476
|
-
allow(existing_pull_request).to receive(:has_comments?).and_return(false)
|
477
|
-
allow(existing_pull_request).to receive(:approvals).and_return([])
|
478
|
-
allow(existing_pull_request).to receive(:reviewers_pending_response).and_return([])
|
479
|
-
end
|
480
|
-
|
481
|
-
it "notifies the user to get their code reviewed" do
|
482
|
-
expect { subject }.to have_said "Your code has not been reviewed yet.", :deliver_halted
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
it "successfully finds a pull request for the current feature branch" do
|
487
|
-
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
488
|
-
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
489
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
490
|
-
expect { subject }.to have_said "Merging pull request #1: 'new-feature', from 'new-feature' into 'master'", :notice
|
491
|
-
end
|
492
|
-
|
493
|
-
it "merges and squashes the feature branch into the master branch" do
|
494
|
-
allow(existing_pull_request).to receive(:good_to_merge?).and_return(true)
|
495
|
-
allow(existing_pull_request).to receive(:approvals).and_return(["Simon"])
|
496
|
-
allow(existing_pull_request).to receive(:title).and_return(inputs[:title])
|
497
|
-
expect(existing_pull_request).to receive(:merge!).and_return(true)
|
498
|
-
subject
|
499
|
-
end
|
500
|
-
end
|
501
|
-
end
|
502
|
-
|
503
|
-
context "and no pull request exists for the feature branch to the destination branch" do
|
504
|
-
before { allow(github).to receive(:find_open_pull_request).and_return(nil) }
|
505
|
-
|
506
|
-
it "notifies the user of a missing pull request" do
|
507
|
-
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
|
508
|
-
end
|
509
|
-
end
|
510
30
|
end
|
511
31
|
|
512
|
-
context "
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
before do
|
517
|
-
stub_command_line_inputs({
|
518
|
-
"Enter the command you use to deploy to #{destination} (leaving blank will skip deployment)" => "bundle exec cap #{destination} deploy"
|
519
|
-
})
|
520
|
-
end
|
521
|
-
|
522
|
-
context "staging" do
|
523
|
-
let(:destination) { "staging" }
|
524
|
-
|
525
|
-
it "sets the local git-config for reflow.deploy-to-staging-command" do
|
526
|
-
expect(GitReflow::Config).to receive(:set).with('reflow.deploy-to-staging-command', deploy_command, local: true)
|
527
|
-
subject
|
528
|
-
end
|
529
|
-
|
530
|
-
it "runs the staging deploy command" do
|
531
|
-
expect { subject }.to have_run_command(deploy_command)
|
532
|
-
end
|
533
|
-
end
|
534
|
-
|
535
|
-
context "production" do
|
536
|
-
let(:destination) { "production" }
|
537
|
-
|
538
|
-
it "sets the local git-config for reflow.deploy-to-staging-command" do
|
539
|
-
expect(GitReflow::Config).to receive(:set).with('reflow.deploy-to-production-command', deploy_command, local: true)
|
540
|
-
subject
|
541
|
-
end
|
542
|
-
|
543
|
-
it "runs the staging deploy command" do
|
544
|
-
expect { subject }.to have_run_command(deploy_command)
|
32
|
+
context "aliases workflow commands" do
|
33
|
+
%w{deliver refresh review setup stage start status}.each do |command|
|
34
|
+
it "aliases the command to the workflow" do
|
35
|
+
expect( subject.respond_to?(command.to_sym) ).to be_truthy
|
545
36
|
end
|
546
37
|
end
|
547
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_reflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valentino Stoll
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-08-
|
13
|
+
date: 2016-08-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: appraisal
|
@@ -208,6 +208,26 @@ dependencies:
|
|
208
208
|
- - '='
|
209
209
|
- !ruby/object:Gem::Version
|
210
210
|
version: 0.14.0
|
211
|
+
- !ruby/object:Gem::Dependency
|
212
|
+
name: rack
|
213
|
+
requirement: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - ">="
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '1.2'
|
218
|
+
- - "<"
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '2'
|
221
|
+
type: :runtime
|
222
|
+
prerelease: false
|
223
|
+
version_requirements: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - ">="
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: '1.2'
|
228
|
+
- - "<"
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: '2'
|
211
231
|
- !ruby/object:Gem::Dependency
|
212
232
|
name: reenhanced_bitbucket_api
|
213
233
|
requirement: !ruby/object:Gem::Requirement
|
@@ -269,6 +289,8 @@ files:
|
|
269
289
|
- lib/git_reflow/rspec/stub_helpers.rb
|
270
290
|
- lib/git_reflow/sandbox.rb
|
271
291
|
- lib/git_reflow/version.rb
|
292
|
+
- lib/git_reflow/workflow.rb
|
293
|
+
- lib/git_reflow/workflows/core.rb
|
272
294
|
- spec/fixtures/git/git_config
|
273
295
|
- spec/fixtures/issues/comment.json.erb
|
274
296
|
- spec/fixtures/issues/comments.json
|
@@ -286,10 +308,11 @@ files:
|
|
286
308
|
- spec/fixtures/repositories/commit.json.erb
|
287
309
|
- spec/fixtures/repositories/commits.json.erb
|
288
310
|
- spec/fixtures/repositories/statuses.json
|
289
|
-
- spec/lgtm_git_reflow_spec.rb
|
290
311
|
- spec/lib/git_reflow/config_spec.rb
|
291
312
|
- spec/lib/git_reflow/git_helpers_spec.rb
|
292
313
|
- spec/lib/git_reflow/git_server_spec.rb
|
314
|
+
- spec/lib/git_reflow/workflow_spec.rb
|
315
|
+
- spec/lib/git_reflow/workflows/core_spec.rb
|
293
316
|
- spec/lib/git_reflow_spec.rb
|
294
317
|
- spec/lib/git_server/bit_bucket_spec.rb
|
295
318
|
- spec/lib/git_server/git_hub/pull_request_spec.rb
|
@@ -349,10 +372,11 @@ test_files:
|
|
349
372
|
- spec/fixtures/repositories/commit.json.erb
|
350
373
|
- spec/fixtures/repositories/commits.json.erb
|
351
374
|
- spec/fixtures/repositories/statuses.json
|
352
|
-
- spec/lgtm_git_reflow_spec.rb
|
353
375
|
- spec/lib/git_reflow/config_spec.rb
|
354
376
|
- spec/lib/git_reflow/git_helpers_spec.rb
|
355
377
|
- spec/lib/git_reflow/git_server_spec.rb
|
378
|
+
- spec/lib/git_reflow/workflow_spec.rb
|
379
|
+
- spec/lib/git_reflow/workflows/core_spec.rb
|
356
380
|
- spec/lib/git_reflow_spec.rb
|
357
381
|
- spec/lib/git_server/bit_bucket_spec.rb
|
358
382
|
- spec/lib/git_server/git_hub/pull_request_spec.rb
|