diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-09-25 16:22:00 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2017-09-25 16:22:00 +0200 |
commit | 8f47d484dab12df982655c3c05305bce7624914d (patch) | |
tree | bd4eef75a1714a22377962092f6f0103df49feed /lib | |
parent | 1209f4f671c290ce6c577c0ff16ad7f9ea8b6271 (diff) | |
download | gitlab-ce-8f47d484dab12df982655c3c05305bce7624914d.tar.gz |
Extract pipeline chain builder classes from service
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/base.rb | 27 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/skip.rb | 33 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/validate.rb | 107 |
3 files changed, 167 insertions, 0 deletions
diff --git a/lib/gitlab/ci/pipeline/chain/base.rb b/lib/gitlab/ci/pipeline/chain/base.rb new file mode 100644 index 00000000000..8d82e1b288d --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/base.rb @@ -0,0 +1,27 @@ +module Gitlab + module Ci + module Pipeline + module Chain + class Base + attr_reader :pipeline, :project, :current_user + + def initialize(pipeline, command) + @pipeline = pipeline + @command = command + + @project = command.project + @current_user = command.current_user + end + + def perform! + raise NotImplementedError + end + + def break? + raise NotImplementedError + end + end + end + end + end +end diff --git a/lib/gitlab/ci/pipeline/chain/skip.rb b/lib/gitlab/ci/pipeline/chain/skip.rb new file mode 100644 index 00000000000..3f86275ae15 --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/skip.rb @@ -0,0 +1,33 @@ +module Gitlab + module Ci + module Pipeline + module Chain + class Skip < Chain::Base + SKIP_PATTERN = /\[(ci[ _-]skip|skip[ _-]ci)\]/i + + def perform! + if skipped? + @pipeline.skip if @command.save_incompleted + end + end + + def skipped? + !@command.ignore_skip_ci && commit_message_skips_ci? + end + + def break? + skipped? + end + + private + + def commit_message_skips_ci? + return false unless @pipeline.git_commit_message + + @skipped ||= @pipeline.git_commit_message =~ SKIP_PATTERN + end + end + end + end + end +end diff --git a/lib/gitlab/ci/pipeline/chain/validate.rb b/lib/gitlab/ci/pipeline/chain/validate.rb new file mode 100644 index 00000000000..e7109425d6c --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/validate.rb @@ -0,0 +1,107 @@ +module Gitlab + module Ci + module Pipeline + module Chain + class Validate < Chain::Base + include Gitlab::Allowable + + def perform! + validate_project! || validate_repository! || validate_pipeline! + end + + def break? + @pipeline.errors.any? || @pipeline.persisted? + end + + def allowed_to_trigger_pipeline? + if current_user + allowed_to_create? + else # legacy triggers don't have a corresponding user + !project.protected_for?(@pipeline.ref) + end + end + + def allowed_to_create? + return unless can?(current_user, :create_pipeline, project) + + access = Gitlab::UserAccess.new(current_user, project: project) + + if branch? + access.can_update_branch?(@pipeline.ref) + elsif tag? + access.can_create_tag?(@pipeline.ref) + else + true # Allow it for now and we'll reject when we check ref existence + end + end + + private + + def validate_project! + unless project.builds_enabled? + return error('Pipeline is disabled') + end + + unless allowed_to_trigger_pipeline? + if can?(current_user, :create_pipeline, project) + return error("Insufficient permissions for protected ref '#{pipeline.ref}'") + else + return error('Insufficient permissions to create a new pipeline') + end + end + end + + def validate_repository! + unless branch? || tag? + return error('Reference not found') + end + + unless pipeline.sha + return error('Commit not found') + end + end + + def validate_pipeline! + unless @pipeline.config_processor + unless @pipeline.ci_yaml_file + return error("Missing #{@pipeline.ci_yaml_file_path} file") + end + + if @command.save_incompleted && @pipeline.has_yaml_errors? + @pipeline.drop + end + + return error(@pipeline.yaml_errors) + end + + unless @pipeline.has_stage_seeds? + return error('No stages / jobs for this pipeline.') + end + end + + ## TODO, move to Pipeline as `branch_exists?` + # + def branch? + return @is_branch if defined?(@is_branch) + + @is_branch = project.repository + .ref_exists?(Gitlab::Git::BRANCH_REF_PREFIX + pipeline.ref) + end + + ## TODO, move to pipeline as `tag_exists?` + # + def tag? + return @is_tag if defined?(@is_tag) + + @is_tag = project.repository + .ref_exists?(Gitlab::Git::TAG_REF_PREFIX + pipeline.ref) + end + + def error(message) + pipeline.errors.add(:base, message) + end + end + end + end + end +end |