summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/yaml_processor/result.rb
blob: d867439b10b9d5f6c46d89a3b8325c6fa31b1dc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# frozen_string_literal: true

# A data object that wraps `Ci::Config` and any messages
# (errors, warnings) generated by the YamlProcessor.
module Gitlab
  module Ci
    class YamlProcessor
      class Result
        attr_reader :errors, :warnings,
                    :root_variables, :root_variables_with_prefill_data,
                    :stages, :jobs,
                    :workflow_rules, :workflow_name

        def initialize(ci_config: nil, errors: [], warnings: [])
          @ci_config = ci_config
          @errors = errors || []
          @warnings = warnings || []

          assign_valid_attributes if valid?
        end

        def valid?
          errors.empty?
        end

        def stages_attributes
          stages.uniq.map do |stage|
            seeds = stage_builds_attributes(stage)

            { name: stage, index: stages.index(stage), builds: seeds }
          end
        end

        def builds
          jobs.map do |name, _|
            build_attributes(name)
          end
        end

        def included_templates
          @included_templates ||= @ci_config.included_templates
        end

        def yaml_variables_for(job_name)
          job = jobs[job_name]

          return [] unless job

          Gitlab::Ci::Variables::Helpers.inherit_yaml_variables(
            from: root_variables,
            to: job[:job_variables],
            inheritance: job.fetch(:root_variables_inheritance, true)
          )
        end

        def stage_for(job_name)
          jobs.dig(job_name, :stage)
        end

        def config_metadata
          @ci_config&.metadata || {}
        end

        private

        def assign_valid_attributes
          @root_variables = transform_to_array(@ci_config.variables_with_data)
          @root_variables_with_prefill_data = @ci_config.variables_with_prefill_data

          @stages = @ci_config.stages
          @jobs = @ci_config.normalized_jobs

          @workflow_rules = @ci_config.workflow_rules
          @workflow_name = @ci_config.workflow_name&.strip
        end

        def stage_builds_attributes(stage)
          jobs.values
            .select { |job| job[:stage] == stage }
            .map { |job| build_attributes(job[:name]) }
        end

        def build_attributes(name)
          job = jobs.fetch(name.to_sym, {})

          { stage_idx: stages.index(job[:stage]),
            stage: job[:stage],
            tag_list: job[:tags],
            name: job[:name].to_s,
            allow_failure: job[:ignore],
            when: job[:when] || 'on_success',
            environment: job[:environment_name],
            coverage_regex: job[:coverage],
            # yaml_variables is calculated with using job_variables in Seed::Build
            job_variables: transform_to_array(job[:job_variables]),
            root_variables_inheritance: job[:root_variables_inheritance],
            needs_attributes: job.dig(:needs, :job),
            interruptible: job[:interruptible],
            only: job[:only],
            except: job[:except],
            rules: job[:rules],
            cache: job[:cache],
            resource_group_key: job[:resource_group],
            scheduling_type: job[:scheduling_type],
            id_tokens: job[:id_tokens],
            options: {
              image: job[:image],
              services: job[:services],
              allow_failure_criteria: job[:allow_failure_criteria],
              artifacts: job[:artifacts],
              dependencies: job[:dependencies],
              cross_dependencies: job.dig(:needs, :cross_dependency),
              job_timeout: job[:timeout],
              before_script: job[:before_script],
              script: job[:script],
              after_script: job[:after_script],
              hooks: job[:hooks],
              environment: job[:environment],
              resource_group_key: job[:resource_group],
              retry: job[:retry],
              parallel: job[:parallel],
              instance: job[:instance],
              start_in: job[:start_in],
              trigger: job[:trigger],
              bridge_needs: job.dig(:needs, :bridge)&.first,
              release: job[:release]
            }.compact }.compact
        end

        def transform_to_array(variables)
          ::Gitlab::Ci::Variables::Helpers.transform_to_array(variables)
        end
      end
    end
  end
end

Gitlab::Ci::YamlProcessor::Result.prepend_mod_with('Gitlab::Ci::YamlProcessor::Result')