summaryrefslogtreecommitdiff
path: root/app/services/ci/create_pipeline_service.rb
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-08-11 15:22:35 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2016-08-11 15:22:35 +0200
commit39203f1adfc6fee3eca50f0cab99ffc597865200 (patch)
tree74a06153802ebb0161e3cd5dbeb6195efac89440 /app/services/ci/create_pipeline_service.rb
parent2facade8f0700a5832dca94c86e512c1c276d601 (diff)
downloadgitlab-ce-39203f1adfc6fee3eca50f0cab99ffc597865200.tar.gz
Pre-create all builds for Pipeline when a trigger is received
This change simplifies a Pipeline processing by introducing a special new status: created. This status is used for all builds that are created for a pipeline. We are then processing next stages and queueing some of the builds (created -> pending) or skipping them (created -> skipped). This makes it possible to simplify and solve a few ordering problems with how previously builds were scheduled. This also allows us to visualise a full pipeline (with created builds). This also removes an after_touch used for updating a pipeline state parameters. Right now in various places we explicitly call a reload_status! on pipeline to force it to be updated and saved.
Diffstat (limited to 'app/services/ci/create_pipeline_service.rb')
-rw-r--r--app/services/ci/create_pipeline_service.rb95
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