summaryrefslogtreecommitdiff
path: root/lib/gitlab_ci_yaml_processor.rb
blob: 0d893df7b9dba7c478e7f7b446507e457fee775f (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
class GitlabCiYamlProcessor
  attr_reader :before_script, :skip_refs

  def initialize(config)
    @config = YAML.load(config).deep_symbolize_keys
    @skip_refs = @config[:skip_refs] || ""
    @before_script = @config[:before_script] || []
    @jobs = @config[:jobs] || []
    @deploy_jobs = @config[:deploy_jobs] || []
  end

  def builds
    normalized_jobs.map do |job|
      {
        name: job[:name],
        commands: "#{normalized_script(@before_script)}\n#{job[:script]}",
        tag_list: job[:runner],
        branches: job[:branches],
        tags: job[:tag]
      }
    end
  end

  def deploy_builds
    normalized_deploy_jobs.map do |job|
      {
        name: job[:name],
        commands: "#{normalized_script(@before_script)}\n#{job[:script]}",
        deploy: true,
        refs: job[:refs],
        tag_list: job[:runner]
      }
    end
  end

  def create_commit_for_tag?(ref)
    normalized_jobs.any?{|job| job[:tags] == true} ||
    normalized_deploy_jobs.any?{|job| job[:refs].empty? || refs_matches?(job[:refs], ref)}
  end

  def deploy_builds_for_ref(ref)
    deploy_builds.select do |build_attrs|
      refs = build_attrs.delete(:refs)
      refs.empty? || refs_matches?(refs, ref)
    end
  end

  def skip_ref?(ref_name)
    @skip_refs.split(",").each do |ref|
      return true if File.fnmatch(ref, ref_name)
    end

    false
  end

  private

  # refs - list of refs. Glob syntax is supported. Ex. ["feature*", "bug"]
  # ref - ref that should be checked
  def refs_matches?(refs, ref)
    refs.each do |ref_pattern|
      return true if File.fnmatch(ref_pattern, ref)
    end

    false
  end

  def normalized_jobs
    @jobs.map do |job|
      if job.is_a?(String)
        { script: job, runner: "", name: job[0..10], branches: true, tags: true }
      else
        {
          script: normalized_script(job[:script]),
          runner: job[:runner] || "",
          name: job[:name] || job[:script][0..10],
          branches: job[:branches].nil? ? true : job[:branches],
          tags: job[:tags].nil? ? true : job[:tags]
        }
      end
    end
  end

  def normalized_deploy_jobs
    @deploy_jobs.map do |job|
      if job.is_a?(String)
        { script: job, refs: [], name: job[0..10].strip }
      else
        {
          script: normalized_script(job[:script]),
          refs: (job[:refs] || "").split(",").map(&:strip),
          name: job[:name] || job[:script][0..10].strip,
          runner: job[:runner] || "",
        }
      end
    end
  end

  def normalized_script(script)
    if script.is_a? Array
      script.map(&:strip).join("\n")
    else
      script.strip
    end
  end
end