diff options
Diffstat (limited to 'app/services/ci/create_pipeline_service.rb')
-rw-r--r-- | app/services/ci/create_pipeline_service.rb | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index be91bf0db85..7398fd8e10a 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -1,49 +1,100 @@ module Ci class CreatePipelineService < BaseService - def execute - pipeline = project.pipelines.new(params) - pipeline.user = current_user + attr_reader :pipeline - unless ref_names.include?(params[:ref]) - pipeline.errors.add(:base, 'Reference not found') - return pipeline + def execute(ignore_skip_ci: false, save_on_errors: true, trigger_request: nil) + @pipeline = Ci::Pipeline.new( + project: project, + ref: ref, + sha: sha, + before_sha: before_sha, + tag: tag?, + trigger_requests: Array(trigger_request), + user: current_user + ) + + unless project.builds_enabled? + return error('Pipeline is disabled') + end + + unless trigger_request || can?(current_user, :create_pipeline, project) + return error('Insufficient permissions to create a new pipeline') end - if commit - pipeline.sha = commit.id - else - pipeline.errors.add(:base, 'Commit not found') - return pipeline + unless branch? || tag? + return error('Reference not found') end - unless can?(current_user, :create_pipeline, project) - pipeline.errors.add(:base, 'Insufficient permissions to create a new pipeline') - return pipeline + unless commit + return error('Commit not found') end unless pipeline.config_processor - pipeline.errors.add(:base, pipeline.yaml_errors || 'Missing .gitlab-ci.yml file') - return pipeline + unless pipeline.ci_yaml_file + return error('Missing .gitlab-ci.yml file') + end + return error(pipeline.yaml_errors, save: save_on_errors) end - pipeline.save! + if !ignore_skip_ci && skip_ci? + return error('Creation of pipeline is skipped', save: save_on_errors) + end - unless pipeline.create_builds(current_user) - pipeline.errors.add(:base, 'No builds for this pipeline.') + unless pipeline.config_builds_attributes.present? + return error('No builds for this pipeline.') end pipeline.save + pipeline.process! pipeline end private - def ref_names - @ref_names ||= project.repository.ref_names + def skip_ci? + pipeline.git_commit_message =~ /\[(ci skip|skip ci)\]/i if pipeline.git_commit_message end def commit - @commit ||= project.commit(params[:ref]) + @commit ||= project.commit(origin_sha || origin_ref) + end + + def sha + commit.try(:id) + end + + def before_sha + params[:checkout_sha] || params[:before] || Gitlab::Git::BLANK_SHA + end + + def origin_sha + params[:checkout_sha] || params[:after] + end + + def origin_ref + params[:ref] + end + + def branch? + project.repository.ref_exists?(Gitlab::Git::BRANCH_REF_PREFIX + ref) + end + + def tag? + project.repository.ref_exists?(Gitlab::Git::TAG_REF_PREFIX + ref) + end + + def ref + Gitlab::Git.ref_name(origin_ref) + end + + def valid_sha? + origin_sha && origin_sha != Gitlab::Git::BLANK_SHA + end + + def error(message, save: false) + pipeline.errors.add(:base, message) + pipeline.reload_status! if save + pipeline end end end |