refs.rb 1.58 KB
Newer Older
1 2
# frozen_string_literal: true

3 4 5 6 7 8 9 10 11
module Gitlab
  module Ci
    module Build
      module Policy
        class Refs < Policy::Specification
          def initialize(refs)
            @patterns = Array(refs)
          end

12
          def satisfied_by?(pipeline, seed = nil)
13
            @patterns.any? do |pattern|
14
              pattern, path = pattern.split('@', 2)
15

16
              matches_path?(path, pipeline) &&
17 18 19 20 21 22
                matches_pattern?(pattern, pipeline)
            end
          end

          private

23 24
          def matches_path?(path, pipeline)
            return true unless path
25

26
            pipeline.project_full_path == path
27 28 29 30
          end

          def matches_pattern?(pattern, pipeline)
            return true if pipeline.tag? && pattern == 'tags'
31
            return true if pipeline.branch? && pattern == 'branches'
32 33
            return true if sanitized_source_name(pipeline) == pattern
            return true if sanitized_source_name(pipeline)&.pluralize == pattern
34

35 36 37
            # patterns can be matched only when branch or tag is used
            # the pattern matching does not work for merge requests pipelines
            if pipeline.branch? || pipeline.tag?
38
              if regexp = Gitlab::UntrustedRegexp::RubySyntax.fabricate(pattern, fallback: true)
39
                regexp.match?(pipeline.ref)
40 41 42
              else
                pattern == pipeline.ref
              end
43 44
            end
          end
45 46 47 48

          def sanitized_source_name(pipeline)
            @sanitized_source_name ||= pipeline&.source&.delete_suffix('_event')
          end
49 50 51 52 53
        end
      end
    end
  end
end