create_pipeline_service.rb 2.69 KB
Newer Older
1 2
# frozen_string_literal: true

Kamil Trzcinski's avatar
Kamil Trzcinski committed
3 4
module Ci
  class CreatePipelineService < BaseService
5
    attr_reader :pipeline
6

7 8
    SEQUENCE = [Gitlab::Ci::Pipeline::Chain::Build,
                Gitlab::Ci::Pipeline::Chain::Validate::Abilities,
9 10
                Gitlab::Ci::Pipeline::Chain::Validate::Repository,
                Gitlab::Ci::Pipeline::Chain::Validate::Config,
11
                Gitlab::Ci::Pipeline::Chain::Skip,
12
                Gitlab::Ci::Pipeline::Chain::Populate,
13
                Gitlab::Ci::Pipeline::Chain::Create].freeze
14

15
    def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block)
16 17
      @pipeline = Ci::Pipeline.new

18 19 20 21 22 23 24 25 26 27 28
      command = Gitlab::Ci::Pipeline::Chain::Command.new(
        source: source,
        origin_ref: params[:ref],
        checkout_sha: params[:checkout_sha],
        after_sha: params[:after],
        before_sha: params[:before],
        trigger_request: trigger_request,
        schedule: schedule,
        ignore_skip_ci: ignore_skip_ci,
        save_incompleted: save_on_errors,
        seeds_block: block,
29
        variables_attributes: params[:variables_attributes],
30 31
        project: project,
        current_user: current_user)
32

33 34
      sequence = Gitlab::Ci::Pipeline::Chain::Sequence
        .new(pipeline, command, SEQUENCE)
35

36
      sequence.build! do |pipeline, sequence|
37
        schedule_head_pipeline_update
Lin Jen-Shin's avatar
Lin Jen-Shin committed
38

39
        if sequence.complete?
40 41
          cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
          pipeline_created_counter.increment(source: source)
Shinya Maeda's avatar
init  
Shinya Maeda committed
42

43
          pipeline.process!
Shinya Maeda's avatar
init  
Shinya Maeda committed
44
        end
Lin Jen-Shin's avatar
Lin Jen-Shin committed
45
      end
46 47

      pipeline
Lin Jen-Shin's avatar
Lin Jen-Shin committed
48 49 50 51
    end

    private

52 53 54
    def commit
      @commit ||= project.commit(origin_sha || origin_ref)
    end
55

56 57
    def sha
      commit.try(:id)
58 59
    end

60
    def cancel_pending_pipelines
61
      Gitlab::OptimisticLocking.retry_lock(auto_cancelable_pipelines) do |cancelables|
62
        cancelables.find_each do |cancelable|
63
          cancelable.auto_cancel_running(pipeline)
64 65 66 67
        end
      end
    end

68 69 70 71
    def auto_cancelable_pipelines
      project.pipelines
        .where(ref: pipeline.ref)
        .where.not(id: pipeline.id)
72
        .where.not(sha: project.commit(pipeline.ref).try(:id))
73 74 75
        .created_or_pending
    end

76
    def pipeline_created_counter
77 78
      @pipeline_created_counter ||= Gitlab::Metrics
        .counter(:pipelines_created_total, "Counter of pipelines created")
79
    end
80 81 82 83 84 85 86 87

    def schedule_head_pipeline_update
      related_merge_requests.each do |merge_request|
        UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
      end
    end

    def related_merge_requests
88
      pipeline.project.source_of_merge_requests.opened.where(source_branch: pipeline.ref)
89
    end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
90
  end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
91
end