create_pipeline_service.rb 2.8 KB
Newer Older
K
Kamil Trzcinski 已提交
1 2
module Ci
  class CreatePipelineService < BaseService
3
    attr_reader :pipeline
4

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
    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')
K
Kamil Trzcinski 已提交
22 23
      end

24 25
      unless branch? || tag?
        return error('Reference not found')
K
Kamil Trzcinski 已提交
26 27
      end

28 29
      unless commit
        return error('Commit not found')
K
Kamil Trzcinski 已提交
30 31
      end

32
      unless pipeline.config_processor
33 34 35 36
        unless pipeline.ci_yaml_file
          return error('Missing .gitlab-ci.yml file')
        end
        return error(pipeline.yaml_errors, save: save_on_errors)
37
      end
K
Kamil Trzcinski 已提交
38

39
      if !ignore_skip_ci && skip_ci?
40 41
        pipeline.skip if save_on_errors
        return pipeline
42
      end
K
Kamil Trzcinski 已提交
43

44 45
      unless pipeline.config_builds_attributes.present?
        return error('No builds for this pipeline.')
K
Kamil Trzcinski 已提交
46 47
      end

48 49 50 51 52 53 54 55
      Ci::Pipeline.transaction do
        pipeline.save

        Ci::CreatePipelineBuildsService
          .new(project, current_user)
          .execute(pipeline)
      end

56 57
      cancel_pending_pipelines if project.auto_cancel_pending_pipelines?

58
      pipeline.tap(&:process!)
K
Kamil Trzcinski 已提交
59 60 61 62
    end

    private

63
    def skip_ci?
64 65
      return false unless pipeline.git_commit_message
      pipeline.git_commit_message =~ /\[(ci[ _-]skip|skip[ _-]ci)\]/i
K
Kamil Trzcinski 已提交
66 67
    end

68 69 70 71 72 73 74 75 76 77
    def cancel_pending_pipelines
      Gitlab::OptimisticLocking.retry_lock(
        pipeline.auto_cancelable_pipelines) do |cancelables|
        cancelables.find_each do |cancelable|
          cancelable.cancel_running
          cancelable.update_attributes(auto_canceled_by: pipeline.id)
        end
      end
    end

K
Kamil Trzcinski 已提交
78
    def commit
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
      @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)
116
      pipeline.drop if save
117
      pipeline
K
Kamil Trzcinski 已提交
118 119
    end
  end
K
Kamil Trzcinski 已提交
120
end