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
This commit is contained in:
Kamil Trzciński 2019-07-05 13:16:57 +00:00
commit 882e798caf
12 changed files with 129 additions and 15 deletions

View file

@ -29,7 +29,7 @@ module AutoMerge
end
def cancel(merge_request)
if cancel_auto_merge(merge_request)
if clear_auto_merge_parameters(merge_request)
yield if block_given?
success
@ -38,6 +38,16 @@ module AutoMerge
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
def strategy
@ -46,7 +56,7 @@ module AutoMerge
end
end
def cancel_auto_merge(merge_request)
def clear_auto_merge_parameters(merge_request)
merge_request.auto_merge_enabled = false
merge_request.merge_user = nil

View file

@ -19,7 +19,13 @@ module AutoMerge
def cancel(merge_request)
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

View file

@ -42,6 +42,12 @@ class AutoMergeService < BaseService
get_service_instance(merge_request.auto_merge_strategy).cancel(merge_request)
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)
self.class.all_strategies.select do |strategy|
get_service_instance(strategy).available_for?(merge_request)

View file

@ -68,8 +68,8 @@ module MergeRequests
!merge_request.for_fork?
end
def cancel_auto_merge(merge_request)
AutoMergeService.new(project, current_user).cancel(merge_request)
def abort_auto_merge(merge_request, reason)
AutoMergeService.new(project, current_user).abort(merge_request, reason)
end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.

View file

@ -18,7 +18,7 @@ module MergeRequests
invalidate_cache_counts(merge_request, users: merge_request.assignees)
merge_request.update_project_counter_caches
cleanup_environments(merge_request)
cancel_auto_merge(merge_request)
abort_auto_merge(merge_request, 'merge request was closed')
end
merge_request

View file

@ -24,7 +24,7 @@ module MergeRequests
reload_merge_requests
outdate_suggestions
refresh_pipelines_on_merge_requests
cancel_auto_merges
abort_auto_merges
mark_pending_todos_done
cache_merge_requests_closing_issues
@ -142,9 +142,9 @@ module MergeRequests
end
end
def cancel_auto_merges
def abort_auto_merges
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

View file

@ -44,7 +44,7 @@ module MergeRequests
merge_request.previous_changes['target_branch'].first,
merge_request.target_branch)
cancel_auto_merge(merge_request)
abort_auto_merge(merge_request, 'target branch was changed')
end
if merge_request.assignees != old_assignees

View file

@ -234,6 +234,16 @@ module SystemNoteService
create_note(NoteSummary.new(noteable, project, author, body, action: 'merge'))
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)
prefix = noteable.work_in_progress? ? "marked" : "unmarked"

View file

@ -121,11 +121,7 @@ describe AutoMerge::BaseService do
end
end
describe '#cancel' do
subject { service.cancel(merge_request) }
let(:merge_request) { create(:merge_request, :merge_when_pipeline_succeeds) }
shared_examples_for 'Canceled or Dropped' do
it 'removes properies from the merge request' do
subject
@ -173,6 +169,20 @@ describe AutoMerge::BaseService do
it 'does not yield block' do
expect { |b| service.execute(merge_request, &b) }.not_to yield_control
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
expect(subject[:status]).to eq(:error)
@ -180,4 +190,24 @@ describe AutoMerge::BaseService do
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

View file

@ -177,6 +177,17 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
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
context 'when there are multiple stages in the pipeline' do
let(:ref) { mr_merge_if_green_enabled.source_branch }

View file

@ -161,4 +161,29 @@ describe AutoMergeService do
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

View file

@ -359,6 +359,22 @@ describe SystemNoteService do
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
let(:noteable) { create(:issue, project: project, title: 'Lorem ipsum') }