diff options
Diffstat (limited to 'lib/gitlab/ci/build/rules')
-rw-r--r-- | lib/gitlab/ci/build/rules/rule/clause.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/ci/build/rules/rule/clause/changes.rb | 34 |
2 files changed, 28 insertions, 7 deletions
diff --git a/lib/gitlab/ci/build/rules/rule/clause.rb b/lib/gitlab/ci/build/rules/rule/clause.rb index 6d4bbbb8c21..503f2a87361 100644 --- a/lib/gitlab/ci/build/rules/rule/clause.rb +++ b/lib/gitlab/ci/build/rules/rule/clause.rb @@ -11,6 +11,7 @@ module Gitlab # Used for job's inclusion rules configuration. # UnknownClauseError = Class.new(StandardError) + ParseError = Class.new(StandardError) def self.fabricate(type, value) "#{self}::#{type.to_s.camelize}".safe_constantize&.new(value) diff --git a/lib/gitlab/ci/build/rules/rule/clause/changes.rb b/lib/gitlab/ci/build/rules/rule/clause/changes.rb index 1bcd87c9d93..1034f5eacef 100644 --- a/lib/gitlab/ci/build/rules/rule/clause/changes.rb +++ b/lib/gitlab/ci/build/rules/rule/clause/changes.rb @@ -11,10 +11,12 @@ module Gitlab end def satisfied_by?(pipeline, context) - return true unless pipeline&.modified_paths + modified_paths = find_modified_paths(pipeline) + + return true unless modified_paths expanded_globs = expand_globs(context) - pipeline.modified_paths.any? do |path| + modified_paths.any? do |path| expanded_globs.any? do |glob| File.fnmatch?(glob, path, File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB) end @@ -33,13 +35,31 @@ module Gitlab def paths strong_memoize(:paths) do - if @globs.is_a?(Array) - @globs - else - Array(@globs[:paths]) - end + Array(@globs[:paths]) end end + + def find_modified_paths(pipeline) + return unless pipeline + return pipeline.modified_paths unless ::Feature.enabled?(:ci_rules_changes_compare, pipeline.project) + + compare_to_sha = find_compare_to_sha(pipeline) + + if compare_to_sha + pipeline.modified_paths_since(compare_to_sha) + else + pipeline.modified_paths + end + end + + def find_compare_to_sha(pipeline) + return unless @globs.include?(:compare_to) + + commit = pipeline.project.commit(@globs[:compare_to]) + raise Rules::Rule::Clause::ParseError, 'rules:changes:compare_to is not a valid ref' unless commit + + commit.sha + end end end end |