diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/ci/build/rules.rb | 4 | ||||
-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 | ||||
-rw-r--r-- | lib/gitlab/ci/config.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/rules/rule/changes.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/seed/build.rb | 12 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/seed/stage.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/yaml_processor/result.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/git_access.rb | 1 |
9 files changed, 50 insertions, 17 deletions
diff --git a/lib/gitlab/ci/build/rules.rb b/lib/gitlab/ci/build/rules.rb index 2d4f9cf635b..dee95534b07 100644 --- a/lib/gitlab/ci/build/rules.rb +++ b/lib/gitlab/ci/build/rules.rb @@ -6,7 +6,7 @@ module Gitlab class Rules include ::Gitlab::Utils::StrongMemoize - Result = Struct.new(:when, :start_in, :allow_failure, :variables) do + Result = Struct.new(:when, :start_in, :allow_failure, :variables, :errors) do def build_attributes { when: self.when, @@ -38,6 +38,8 @@ module Gitlab else Result.new('never') end + rescue Rule::Clause::ParseError => e + Result.new('never', nil, nil, nil, [e.message]) end private 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 diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb index 15a4ff91c1b..438fa1cb3b2 100644 --- a/lib/gitlab/ci/config.rb +++ b/lib/gitlab/ci/config.rb @@ -81,6 +81,10 @@ module Gitlab root.jobs_value end + def workflow_rules + root.workflow_entry.rules_value + end + def normalized_jobs @normalized_jobs ||= Ci::Config::Normalizer.new(jobs).normalize_jobs end diff --git a/lib/gitlab/ci/config/entry/rules/rule/changes.rb b/lib/gitlab/ci/config/entry/rules/rule/changes.rb index a56b928450a..107e7c228af 100644 --- a/lib/gitlab/ci/config/entry/rules/rule/changes.rb +++ b/lib/gitlab/ci/config/entry/rules/rule/changes.rb @@ -30,7 +30,7 @@ module Gitlab include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Attributable - ALLOWED_KEYS = %i[paths].freeze + ALLOWED_KEYS = %i[paths compare_to].freeze REQUIRED_KEYS = %i[paths].freeze attributes ALLOWED_KEYS @@ -43,6 +43,7 @@ module Gitlab validates :paths, array_of_strings: true, length: { maximum: 50, too_long: "has too many entries (maximum %{count})" } + validates :compare_to, type: String, allow_nil: true end end end diff --git a/lib/gitlab/ci/pipeline/seed/build.rb b/lib/gitlab/ci/pipeline/seed/build.rb index 901208f325a..93106b96af2 100644 --- a/lib/gitlab/ci/pipeline/seed/build.rb +++ b/lib/gitlab/ci/pipeline/seed/build.rb @@ -54,9 +54,11 @@ module Gitlab end def errors - return unless included? - strong_memoize(:errors) do + # We check rules errors before checking "included?" because rules affects its inclusion status. + next rules_errors if rules_errors + next unless included? + [needs_errors, variable_expansion_errors].compact.flatten end end @@ -168,6 +170,12 @@ module Gitlab end end + def rules_errors + strong_memoize(:rules_errors) do + ["Failed to parse rule for #{name}: #{rules_result.errors.join(', ')}"] if rules_result.errors.present? + end + end + def evaluate_context strong_memoize(:evaluate_context) do Gitlab::Ci::Build::Context::Build.new(@pipeline, @seed_attributes) diff --git a/lib/gitlab/ci/pipeline/seed/stage.rb b/lib/gitlab/ci/pipeline/seed/stage.rb index bc56fe9bef9..7cf6466cf4b 100644 --- a/lib/gitlab/ci/pipeline/seed/stage.rb +++ b/lib/gitlab/ci/pipeline/seed/stage.rb @@ -36,7 +36,7 @@ module Gitlab def errors strong_memoize(:errors) do - seeds.flat_map(&:errors).compact + @builds.flat_map(&:errors).compact end end diff --git a/lib/gitlab/ci/yaml_processor/result.rb b/lib/gitlab/ci/yaml_processor/result.rb index 576fb509d47..4bd1ac3b67f 100644 --- a/lib/gitlab/ci/yaml_processor/result.rb +++ b/lib/gitlab/ci/yaml_processor/result.rb @@ -39,7 +39,7 @@ module Gitlab end def workflow_rules - @workflow_rules ||= hash_config.dig(:workflow, :rules) + @workflow_rules ||= @ci_config.workflow_rules end def root_variables @@ -133,10 +133,6 @@ module Gitlab @variables ||= @ci_config.variables end - def hash_config - @hash_config ||= @ci_config.to_hash - end - def release(job) job[:release] end diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 66fd7aaedea..1c5ad650678 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -446,6 +446,7 @@ module Gitlab when Key actor.user when :ci + Gitlab::AppJsonLogger.info(message: 'Actor was :ci', project_id: project.id) nil end end |