Introduce service for merge request pipeline creation
We don't have a way to create MR pipeline today, this is one of the headaches for users. This change is a preliminary work for the capability.
This commit is contained in:
parent
1bec362138
commit
31afb0e8ad
3 changed files with 109 additions and 25 deletions
|
@ -60,31 +60,7 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def create_pipeline_for(merge_request, user)
|
||||
return unless can_create_pipeline_for?(merge_request)
|
||||
|
||||
create_detached_merge_request_pipeline(merge_request, user)
|
||||
end
|
||||
|
||||
def create_detached_merge_request_pipeline(merge_request, user)
|
||||
if can_use_merge_request_ref?(merge_request)
|
||||
Ci::CreatePipelineService.new(merge_request.source_project, user,
|
||||
ref: merge_request.ref_path)
|
||||
.execute(:merge_request_event, merge_request: merge_request)
|
||||
else
|
||||
Ci::CreatePipelineService.new(merge_request.source_project, user,
|
||||
ref: merge_request.source_branch)
|
||||
.execute(:merge_request_event, merge_request: merge_request)
|
||||
end
|
||||
end
|
||||
|
||||
def can_create_pipeline_for?(merge_request)
|
||||
##
|
||||
# UpdateMergeRequestsWorker could be retried by an exception.
|
||||
# pipelines for merge request should not be recreated in such case.
|
||||
return false if merge_request.find_actual_head_pipeline&.triggered_by_merge_request?
|
||||
return false if merge_request.has_no_commits?
|
||||
|
||||
true
|
||||
MergeRequests::CreatePipelineService.new(project, user).execute(merge_request)
|
||||
end
|
||||
|
||||
def can_use_merge_request_ref?(merge_request)
|
||||
|
|
37
app/services/merge_requests/create_pipeline_service.rb
Normal file
37
app/services/merge_requests/create_pipeline_service.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MergeRequests
|
||||
class CreatePipelineService < MergeRequests::BaseService
|
||||
def execute(merge_request)
|
||||
return unless can_create_pipeline_for?(merge_request)
|
||||
|
||||
create_detached_merge_request_pipeline(merge_request)
|
||||
end
|
||||
|
||||
def create_detached_merge_request_pipeline(merge_request)
|
||||
if can_use_merge_request_ref?(merge_request)
|
||||
Ci::CreatePipelineService.new(merge_request.source_project, current_user,
|
||||
ref: merge_request.ref_path)
|
||||
.execute(:merge_request_event, merge_request: merge_request)
|
||||
else
|
||||
Ci::CreatePipelineService.new(merge_request.source_project, current_user,
|
||||
ref: merge_request.source_branch)
|
||||
.execute(:merge_request_event, merge_request: merge_request)
|
||||
end
|
||||
end
|
||||
|
||||
def can_create_pipeline_for?(merge_request)
|
||||
##
|
||||
# UpdateMergeRequestsWorker could be retried by an exception.
|
||||
# pipelines for merge request should not be recreated in such case.
|
||||
return false if !allow_duplicate && merge_request.find_actual_head_pipeline&.triggered_by_merge_request?
|
||||
return false if merge_request.has_no_commits?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def allow_duplicate
|
||||
params[:allow_duplicate]
|
||||
end
|
||||
end
|
||||
end
|
71
spec/services/merge_requests/create_pipeline_service_spec.rb
Normal file
71
spec/services/merge_requests/create_pipeline_service_spec.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe MergeRequests::CreatePipelineService do
|
||||
set(:project) { create(:project, :repository) }
|
||||
set(:user) { create(:user) }
|
||||
let(:service) { described_class.new(project, user, params) }
|
||||
let(:params) { {} }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
subject { service.execute(merge_request) }
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(YAML.dump(config))
|
||||
end
|
||||
|
||||
let(:config) do
|
||||
{ rspec: { script: 'echo', only: ['merge_requests'] } }
|
||||
end
|
||||
|
||||
let(:merge_request) do
|
||||
create(:merge_request,
|
||||
source_branch: 'feature',
|
||||
source_project: project,
|
||||
target_branch: 'master',
|
||||
target_project: project)
|
||||
end
|
||||
|
||||
it 'creates a detached merge request pipeline' do
|
||||
expect { subject }.to change { Ci::Pipeline.count }.by(1)
|
||||
|
||||
expect(subject).to be_persisted
|
||||
expect(subject).to be_detached_merge_request_pipeline
|
||||
end
|
||||
|
||||
context 'when service is called multiple times' do
|
||||
it 'creates a pipeline once' do
|
||||
expect do
|
||||
service.execute(merge_request)
|
||||
service.execute(merge_request)
|
||||
end.to change { Ci::Pipeline.count }.by(1)
|
||||
end
|
||||
|
||||
context 'when allow_duplicate option is true' do
|
||||
let(:params) { { allow_duplicate: true } }
|
||||
|
||||
it 'creates pipelines multiple times' do
|
||||
expect do
|
||||
service.execute(merge_request)
|
||||
service.execute(merge_request)
|
||||
end.to change { Ci::Pipeline.count }.by(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when .gitlab-ci.yml does not have only: [merge_requests] keyword' do
|
||||
let(:config) do
|
||||
{ rspec: { script: 'echo' } }
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
expect { subject }.not_to change { Ci::Pipeline.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue