2015-11-24 13:59:02 +00:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2016-10-27 12:04:43 +00:00
|
|
|
describe MergeRequests::MergeWhenPipelineSucceedsService do
|
2016-04-26 11:52:18 +00:00
|
|
|
let(:user) { create(:user) }
|
2017-03-27 21:14:01 +00:00
|
|
|
let(:project) { create(:project, :repository) }
|
2015-12-03 09:27:34 +00:00
|
|
|
|
|
|
|
let(:mr_merge_if_green_enabled) do
|
2017-02-17 13:56:13 +00:00
|
|
|
create(:merge_request, merge_when_pipeline_succeeds: true, merge_user: user,
|
2016-01-20 19:38:34 +00:00
|
|
|
source_branch: "master", target_branch: 'feature',
|
2015-12-03 09:27:34 +00:00
|
|
|
source_project: project, target_project: project, state: "opened")
|
|
|
|
end
|
|
|
|
|
2016-10-27 12:04:43 +00:00
|
|
|
let(:pipeline) do
|
|
|
|
create(:ci_pipeline_with_one_job, ref: mr_merge_if_green_enabled.source_branch,
|
|
|
|
project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:service) do
|
|
|
|
described_class.new(project, user, commit_message: 'Awesome message')
|
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
|
|
|
|
describe "#execute" do
|
2016-04-26 11:52:18 +00:00
|
|
|
let(:merge_request) do
|
|
|
|
create(:merge_request, target_project: project, source_project: project,
|
|
|
|
source_branch: "feature", target_branch: 'master')
|
|
|
|
end
|
|
|
|
|
2015-11-24 13:59:02 +00:00
|
|
|
context 'first time enabling' do
|
|
|
|
before do
|
2016-11-28 10:13:32 +00:00
|
|
|
allow(merge_request)
|
|
|
|
.to receive(:head_pipeline)
|
|
|
|
.and_return(pipeline)
|
|
|
|
|
2015-12-03 09:27:34 +00:00
|
|
|
service.execute(merge_request)
|
2015-11-24 13:59:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the params, merge_user, and flag' do
|
|
|
|
expect(merge_request).to be_valid
|
2017-02-17 13:56:13 +00:00
|
|
|
expect(merge_request.merge_when_pipeline_succeeds).to be_truthy
|
2015-11-24 13:59:02 +00:00
|
|
|
expect(merge_request.merge_params).to eq commit_message: 'Awesome message'
|
|
|
|
expect(merge_request.merge_user).to be user
|
2015-12-03 09:27:34 +00:00
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
|
2015-12-03 09:27:34 +00:00
|
|
|
it 'creates a system note' do
|
2015-11-24 13:59:02 +00:00
|
|
|
note = merge_request.notes.last
|
2016-11-25 10:05:34 +00:00
|
|
|
expect(note.note).to match /enabled an automatic merge when the pipeline for (\w+\/\w+@)?\h{8}/
|
2015-11-24 13:59:02 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-12-03 09:27:34 +00:00
|
|
|
context 'already approved' do
|
2016-10-27 12:04:43 +00:00
|
|
|
let(:service) { described_class.new(project, user, new_key: true) }
|
2015-11-24 13:59:02 +00:00
|
|
|
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) }
|
|
|
|
|
|
|
|
before do
|
2016-11-28 10:13:32 +00:00
|
|
|
allow(mr_merge_if_green_enabled).to receive(:head_pipeline)
|
|
|
|
.and_return(pipeline)
|
|
|
|
|
|
|
|
allow(mr_merge_if_green_enabled).to receive(:mergeable?)
|
|
|
|
.and_return(true)
|
|
|
|
|
2016-06-03 13:35:16 +00:00
|
|
|
allow(pipeline).to receive(:success?).and_return(true)
|
2015-11-24 13:59:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'updates the merge params' do
|
2017-02-17 13:56:13 +00:00
|
|
|
expect(SystemNoteService).not_to receive(:merge_when_pipeline_succeeds)
|
2015-11-24 13:59:02 +00:00
|
|
|
|
|
|
|
service.execute(mr_merge_if_green_enabled)
|
|
|
|
expect(mr_merge_if_green_enabled.merge_params).to have_key(:new_key)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#trigger" do
|
2016-10-06 10:19:50 +00:00
|
|
|
let(:merge_request_ref) { mr_merge_if_green_enabled.source_branch }
|
|
|
|
let(:merge_request_head) do
|
|
|
|
project.commit(mr_merge_if_green_enabled.source_branch).id
|
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
|
2016-10-06 10:19:50 +00:00
|
|
|
context 'when triggered by pipeline with valid ref and sha' do
|
|
|
|
let(:triggering_pipeline) do
|
|
|
|
create(:ci_pipeline, project: project, ref: merge_request_ref,
|
|
|
|
sha: merge_request_head, status: 'success')
|
|
|
|
end
|
2016-02-19 19:55:17 +00:00
|
|
|
|
2017-03-22 19:36:14 +00:00
|
|
|
before do
|
|
|
|
mr_merge_if_green_enabled.update(head_pipeline: triggering_pipeline)
|
|
|
|
end
|
|
|
|
|
2017-02-17 13:56:13 +00:00
|
|
|
it "merges all merge requests with merge when the pipeline succeeds enabled" do
|
2016-02-19 19:55:17 +00:00
|
|
|
expect(MergeWorker).to receive(:perform_async)
|
2016-10-06 10:19:50 +00:00
|
|
|
service.trigger(triggering_pipeline)
|
2016-02-19 19:55:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-10-06 10:19:50 +00:00
|
|
|
context 'when triggered by an old pipeline' do
|
|
|
|
let(:old_pipeline) do
|
|
|
|
create(:ci_pipeline, project: project, ref: merge_request_ref,
|
|
|
|
sha: '1234abcdef', status: 'success')
|
|
|
|
end
|
2016-02-22 09:33:34 +00:00
|
|
|
|
2016-10-06 10:19:50 +00:00
|
|
|
it 'it does not merge merge request' do
|
2016-05-23 23:37:59 +00:00
|
|
|
expect(MergeWorker).not_to receive(:perform_async)
|
2016-10-06 10:19:50 +00:00
|
|
|
service.trigger(old_pipeline)
|
2016-02-22 09:33:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-10-06 10:19:50 +00:00
|
|
|
context 'when triggered by pipeline from a different branch' do
|
|
|
|
let(:unrelated_pipeline) do
|
|
|
|
create(:ci_pipeline, project: project, ref: 'feature',
|
|
|
|
sha: merge_request_head, status: 'success')
|
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
|
2016-10-06 10:19:50 +00:00
|
|
|
it 'does not merge request' do
|
2016-05-23 23:37:59 +00:00
|
|
|
expect(MergeWorker).not_to receive(:perform_async)
|
2016-10-06 10:19:50 +00:00
|
|
|
service.trigger(unrelated_pipeline)
|
2016-02-19 19:55:17 +00:00
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
end
|
2017-02-24 15:56:41 +00:00
|
|
|
|
|
|
|
context 'when the merge request is not mergeable' do
|
|
|
|
let(:mr_conflict) do
|
2017-02-17 13:56:13 +00:00
|
|
|
create(:merge_request, merge_when_pipeline_succeeds: true, merge_user: user,
|
2017-02-24 15:56:41 +00:00
|
|
|
source_branch: 'master', target_branch: 'feature-conflict',
|
|
|
|
source_project: project, target_project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:conflict_pipeline) do
|
|
|
|
create(:ci_pipeline, project: project, ref: mr_conflict.source_branch,
|
|
|
|
sha: mr_conflict.diff_head_sha, status: 'success')
|
|
|
|
end
|
|
|
|
|
2017-03-22 19:36:14 +00:00
|
|
|
before { mr_conflict.update(head_pipeline_id: conflict_pipeline.id) }
|
|
|
|
|
2017-02-24 15:56:41 +00:00
|
|
|
it 'does not merge the merge request' do
|
|
|
|
expect(MergeWorker).not_to receive(:perform_async)
|
|
|
|
|
|
|
|
service.trigger(conflict_pipeline)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'creates todos for unmergeability' do
|
|
|
|
expect_any_instance_of(TodoService).to receive(:merge_request_became_unmergeable).with(mr_conflict)
|
|
|
|
|
|
|
|
service.trigger(conflict_pipeline)
|
|
|
|
end
|
|
|
|
end
|
2016-10-12 10:23:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "#cancel" do
|
|
|
|
before do
|
|
|
|
service.cancel(mr_merge_if_green_enabled)
|
|
|
|
end
|
|
|
|
|
2017-02-17 13:56:13 +00:00
|
|
|
it "resets all the pipeline succeeds params" do
|
|
|
|
expect(mr_merge_if_green_enabled.merge_when_pipeline_succeeds).to be_falsey
|
2016-10-12 10:23:52 +00:00
|
|
|
expect(mr_merge_if_green_enabled.merge_params).to eq({})
|
|
|
|
expect(mr_merge_if_green_enabled.merge_user).to be nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'Posts a system note' do
|
|
|
|
note = mr_merge_if_green_enabled.notes.last
|
2016-11-23 06:55:23 +00:00
|
|
|
expect(note.note).to include 'canceled the automatic merge'
|
2016-10-12 10:23:52 +00:00
|
|
|
end
|
|
|
|
end
|
2016-02-19 16:38:47 +00:00
|
|
|
|
2016-10-12 10:23:52 +00:00
|
|
|
describe 'pipeline integration' do
|
2016-10-06 10:31:39 +00:00
|
|
|
context 'when there are multiple stages in the pipeline' do
|
2016-02-19 16:38:47 +00:00
|
|
|
let(:ref) { mr_merge_if_green_enabled.source_branch }
|
2016-10-08 18:24:43 +00:00
|
|
|
let(:sha) { project.commit(ref).id }
|
|
|
|
|
|
|
|
let(:pipeline) do
|
|
|
|
create(:ci_empty_pipeline, ref: ref, sha: sha, project: project)
|
|
|
|
end
|
|
|
|
|
|
|
|
let!(:build) do
|
|
|
|
create(:ci_build, :created, pipeline: pipeline, ref: ref,
|
|
|
|
name: 'build', stage: 'build')
|
|
|
|
end
|
|
|
|
|
|
|
|
let!(:test) do
|
|
|
|
create(:ci_build, :created, pipeline: pipeline, ref: ref,
|
|
|
|
name: 'test', stage: 'test')
|
|
|
|
end
|
2016-02-19 16:38:47 +00:00
|
|
|
|
|
|
|
before do
|
|
|
|
# This behavior of MergeRequest: we instantiate a new object
|
2016-11-28 10:13:32 +00:00
|
|
|
#
|
|
|
|
allow_any_instance_of(MergeRequest)
|
|
|
|
.to receive(:head_pipeline)
|
|
|
|
.and_wrap_original do
|
|
|
|
Ci::Pipeline.find(pipeline.id)
|
|
|
|
end
|
2016-02-19 16:38:47 +00:00
|
|
|
end
|
|
|
|
|
2016-10-08 18:24:43 +00:00
|
|
|
it "doesn't merge if any of stages failed" do
|
2016-05-23 23:37:59 +00:00
|
|
|
expect(MergeWorker).not_to receive(:perform_async)
|
2016-10-08 18:24:43 +00:00
|
|
|
|
2016-02-19 16:38:47 +00:00
|
|
|
build.success
|
2016-10-26 09:34:40 +00:00
|
|
|
test.reload
|
2016-02-19 16:38:47 +00:00
|
|
|
test.drop
|
|
|
|
end
|
|
|
|
|
2016-10-08 18:24:43 +00:00
|
|
|
it 'merges when all stages succeeded' do
|
2016-02-19 16:38:47 +00:00
|
|
|
expect(MergeWorker).to receive(:perform_async)
|
2016-10-08 18:24:43 +00:00
|
|
|
|
2016-02-19 16:38:47 +00:00
|
|
|
build.success
|
2016-10-26 09:34:40 +00:00
|
|
|
test.reload
|
2016-02-19 16:38:47 +00:00
|
|
|
test.success
|
|
|
|
end
|
|
|
|
end
|
2015-11-24 13:59:02 +00:00
|
|
|
end
|
|
|
|
end
|