Commit 882e798c authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch 'make-explicit-endpoint-abort-in-auto-merge-ce' into 'master'

CE Port: Split AutoMergeService interfaces into two `cancel` and `abort`

See merge request gitlab-org/gitlab-ce!30249
parents a816bad9 587ffd11
...@@ -29,7 +29,7 @@ module AutoMerge ...@@ -29,7 +29,7 @@ module AutoMerge
end end
def cancel(merge_request) def cancel(merge_request)
if cancel_auto_merge(merge_request) if clear_auto_merge_parameters(merge_request)
yield if block_given? yield if block_given?
success success
...@@ -38,6 +38,16 @@ module AutoMerge ...@@ -38,6 +38,16 @@ module AutoMerge
end end
end end
def abort(merge_request, reason)
if clear_auto_merge_parameters(merge_request)
yield if block_given?
success
else
error("Can't abort the automatic merge", 406)
end
end
private private
def strategy def strategy
...@@ -46,7 +56,7 @@ module AutoMerge ...@@ -46,7 +56,7 @@ module AutoMerge
end end
end end
def cancel_auto_merge(merge_request) def clear_auto_merge_parameters(merge_request)
merge_request.auto_merge_enabled = false merge_request.auto_merge_enabled = false
merge_request.merge_user = nil merge_request.merge_user = nil
......
...@@ -19,7 +19,13 @@ module AutoMerge ...@@ -19,7 +19,13 @@ module AutoMerge
def cancel(merge_request) def cancel(merge_request)
super do super do
SystemNoteService.cancel_merge_when_pipeline_succeeds(merge_request, @project, @current_user) SystemNoteService.cancel_merge_when_pipeline_succeeds(merge_request, project, current_user)
end
end
def abort(merge_request, reason)
super do
SystemNoteService.abort_merge_when_pipeline_succeeds(merge_request, project, current_user, reason)
end end
end end
......
...@@ -42,6 +42,12 @@ class AutoMergeService < BaseService ...@@ -42,6 +42,12 @@ class AutoMergeService < BaseService
get_service_instance(merge_request.auto_merge_strategy).cancel(merge_request) get_service_instance(merge_request.auto_merge_strategy).cancel(merge_request)
end end
def abort(merge_request, reason)
return error("Can't abort the automatic merge", 406) unless merge_request.auto_merge_enabled?
get_service_instance(merge_request.auto_merge_strategy).abort(merge_request, reason)
end
def available_strategies(merge_request) def available_strategies(merge_request)
self.class.all_strategies.select do |strategy| self.class.all_strategies.select do |strategy|
get_service_instance(strategy).available_for?(merge_request) get_service_instance(strategy).available_for?(merge_request)
......
...@@ -68,8 +68,8 @@ module MergeRequests ...@@ -68,8 +68,8 @@ module MergeRequests
!merge_request.for_fork? !merge_request.for_fork?
end end
def cancel_auto_merge(merge_request) def abort_auto_merge(merge_request, reason)
AutoMergeService.new(project, current_user).cancel(merge_request) AutoMergeService.new(project, current_user).abort(merge_request, reason)
end end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments. # Returns all origin and fork merge requests from `@project` satisfying passed arguments.
......
...@@ -18,7 +18,7 @@ module MergeRequests ...@@ -18,7 +18,7 @@ module MergeRequests
invalidate_cache_counts(merge_request, users: merge_request.assignees) invalidate_cache_counts(merge_request, users: merge_request.assignees)
merge_request.update_project_counter_caches merge_request.update_project_counter_caches
cleanup_environments(merge_request) cleanup_environments(merge_request)
cancel_auto_merge(merge_request) abort_auto_merge(merge_request, 'merge request was closed')
end end
merge_request merge_request
......
...@@ -24,7 +24,7 @@ module MergeRequests ...@@ -24,7 +24,7 @@ module MergeRequests
reload_merge_requests reload_merge_requests
outdate_suggestions outdate_suggestions
refresh_pipelines_on_merge_requests refresh_pipelines_on_merge_requests
cancel_auto_merges abort_auto_merges
mark_pending_todos_done mark_pending_todos_done
cache_merge_requests_closing_issues cache_merge_requests_closing_issues
...@@ -142,9 +142,9 @@ module MergeRequests ...@@ -142,9 +142,9 @@ module MergeRequests
end end
end end
def cancel_auto_merges def abort_auto_merges
merge_requests_for_source_branch.each do |merge_request| merge_requests_for_source_branch.each do |merge_request|
cancel_auto_merge(merge_request) abort_auto_merge(merge_request, 'source branch was updated')
end end
end end
......
...@@ -44,7 +44,7 @@ module MergeRequests ...@@ -44,7 +44,7 @@ module MergeRequests
merge_request.previous_changes['target_branch'].first, merge_request.previous_changes['target_branch'].first,
merge_request.target_branch) merge_request.target_branch)
cancel_auto_merge(merge_request) abort_auto_merge(merge_request, 'target branch was changed')
end end
if merge_request.assignees != old_assignees if merge_request.assignees != old_assignees
......
...@@ -234,6 +234,16 @@ module SystemNoteService ...@@ -234,6 +234,16 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'merge')) create_note(NoteSummary.new(noteable, project, author, body, action: 'merge'))
end end
# Called when 'merge when pipeline succeeds' is aborted
def abort_merge_when_pipeline_succeeds(noteable, project, author, reason)
body = "aborted the automatic merge because #{reason}"
##
# TODO: Abort message should be sent by the system, not a particular user.
# See https://gitlab.com/gitlab-org/gitlab-ce/issues/63187.
create_note(NoteSummary.new(noteable, project, author, body, action: 'merge'))
end
def handle_merge_request_wip(noteable, project, author) def handle_merge_request_wip(noteable, project, author)
prefix = noteable.work_in_progress? ? "marked" : "unmarked" prefix = noteable.work_in_progress? ? "marked" : "unmarked"
......
...@@ -121,11 +121,7 @@ describe AutoMerge::BaseService do ...@@ -121,11 +121,7 @@ describe AutoMerge::BaseService do
end end
end end
describe '#cancel' do shared_examples_for 'Canceled or Dropped' do
subject { service.cancel(merge_request) }
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
it 'removes properies from the merge request' do it 'removes properies from the merge request' do
subject subject
...@@ -173,6 +169,20 @@ describe AutoMerge::BaseService do ...@@ -173,6 +169,20 @@ describe AutoMerge::BaseService do
it 'does not yield block' do it 'does not yield block' do
expect { |b| service.execute(merge_request, &b) }.not_to yield_control expect { |b| service.execute(merge_request, &b) }.not_to yield_control
end end
end
end
describe '#cancel' do
subject { service.cancel(merge_request) }
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
it_behaves_like 'Canceled or Dropped'
context 'when failed to save' do
before do
allow(merge_request).to receive(:save) { false }
end
it 'returns error status' do it 'returns error status' do
expect(subject[:status]).to eq(:error) expect(subject[:status]).to eq(:error)
...@@ -180,4 +190,24 @@ describe AutoMerge::BaseService do ...@@ -180,4 +190,24 @@ describe AutoMerge::BaseService do
end end
end end
end end
describe '#abort' do
subject { service.abort(merge_request, reason) }
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
let(:reason) { 'an error'}
it_behaves_like 'Canceled or Dropped'
context 'when failed to save' do
before do
allow(merge_request).to receive(:save) { false }
end
it 'returns error status' do
expect(subject[:status]).to eq(:error)
expect(subject[:message]).to eq("Can't abort the automatic merge")
end
end
end
end end
...@@ -177,6 +177,17 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do ...@@ -177,6 +177,17 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
end end
end end
describe "#abort" do
before do
service.abort(mr_merge_if_green_enabled, 'an error')
end
it 'posts a system note' do
note = mr_merge_if_green_enabled.notes.last
expect(note.note).to include 'aborted the automatic merge'
end
end
describe 'pipeline integration' do describe 'pipeline integration' do
context 'when there are multiple stages in the pipeline' do context 'when there are multiple stages in the pipeline' do
let(:ref) { mr_merge_if_green_enabled.source_branch } let(:ref) { mr_merge_if_green_enabled.source_branch }
......
...@@ -161,4 +161,29 @@ describe AutoMergeService do ...@@ -161,4 +161,29 @@ describe AutoMergeService do
end end
end end
end end
describe '#abort' do
subject { service.abort(merge_request, error) }
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
let(:error) { 'an error' }
it 'delegates to a relevant service instance' do
expect_next_instance_of(AutoMerge::MergeWhenPipelineSucceedsService) do |service|
expect(service).to receive(:abort).with(merge_request, error)
end
subject
end
context 'when auto merge is not enabled' do
let(:merge_request) { create(:merge_request) }
it 'returns error' do
expect(subject[:message]).to eq("Can't abort the automatic merge")
expect(subject[:status]).to eq(:error)
expect(subject[:http_status]).to eq(406)
end
end
end
end end
...@@ -359,6 +359,22 @@ describe SystemNoteService do ...@@ -359,6 +359,22 @@ describe SystemNoteService do
end end
end end
describe '.abort_merge_when_pipeline_succeeds' do
let(:noteable) do
create(:merge_request, source_project: project, target_project: project)
end
subject { described_class.abort_merge_when_pipeline_succeeds(noteable, project, author, 'merge request was closed') }
it_behaves_like 'a system note' do
let(:action) { 'merge' }
end
it "posts the 'merge when pipeline succeeds' system note" do
expect(subject.note).to eq "aborted the automatic merge because merge request was closed"
end
end
describe '.change_title' do describe '.change_title' do
let(:noteable) { create(:issue, project: project, title: 'Lorem ipsum') } let(:noteable) { create(:issue, project: project, title: 'Lorem ipsum') }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment