process_pipeline_service.rb 1.99 KB
Newer Older
1
2
3
4
5
6
7
module Ci
  class ProcessPipelineService < BaseService
    attr_reader :pipeline

    def execute(pipeline)
      @pipeline = pipeline

8
9
      ensure_created_builds! # TODO, remove me in 9.0

Kamil Trzcinski's avatar
Kamil Trzcinski committed
10
11
12
13
      new_builds =
        stage_indexes_of_created_builds.map do |index|
          process_stage(index)
        end
14

Kamil Trzcinski's avatar
Kamil Trzcinski committed
15
      @pipeline.update_status
16

Kamil Trzcinski's avatar
Kamil Trzcinski committed
17
      new_builds.flatten.any?
18
19
20
21
22
23
24
    end

    private

    def process_stage(index)
      current_status = status_for_prior_stages(index)

Kamil Trzcinski's avatar
Kamil Trzcinski committed
25
26
      if HasStatus::COMPLETED_STATUSES.include?(current_status)
        created_builds_in_stage(index).select do |build|
27
28
          Gitlab::OptimisticLocking.retry_lock(build) do |subject|
            process_build(subject, current_status)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
29
          end
30
        end
31
32
33
34
35
      end
    end

    def process_build(build, current_status)
      if valid_statuses_for_when(build.when).include?(current_status)
Stan Hu's avatar
Stan Hu committed
36
        build.enqueue
37
38
        true
      else
Stan Hu's avatar
Stan Hu committed
39
        build.skip
40
41
42
43
44
45
46
        false
      end
    end

    def valid_statuses_for_when(value)
      case value
      when 'on_success'
47
        %w[success skipped]
48
49
50
      when 'on_failure'
        %w[failed]
      when 'always'
51
        %w[success failed skipped]
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
      else
        []
      end
    end

    def status_for_prior_stages(index)
      pipeline.builds.where('stage_idx < ?', index).latest.status || 'success'
    end

    def stage_indexes_of_created_builds
      created_builds.order(:stage_idx).pluck('distinct stage_idx')
    end

    def created_builds_in_stage(index)
      created_builds.where(stage_idx: index)
    end

    def created_builds
      pipeline.builds.created
    end
72
73
74
75
76
77
78
79
80

    # This method is DEPRECATED and should be removed in 9.0.
    #
    # We need it to maintain backwards compatibility with  previous versions
    # when builds were not created within one transaction with the pipeline.
    #
    def ensure_created_builds!
      return if created_builds.any?

81
82
83
      Ci::CreatePipelineBuildsService.
        new(project, current_user).
        execute(pipeline)
84
    end
85
86
  end
end