diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-08-16 15:30:06 +0200 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2018-09-04 14:17:01 +0200 |
commit | 2c41fbb14821c8028e389c270d2f39380e5fbe04 (patch) | |
tree | dd7c4069b7cb05247bb605589388bc2a0320d305 | |
parent | ef26622d62fe37371adf0d66c81f8428ad4bb1b6 (diff) | |
download | gitlab-ce-2c41fbb14821c8028e389c270d2f39380e5fbe04.tar.gz |
Detect circular dependenies in CI/CD `extends:` entry
-rw-r--r-- | lib/gitlab/ci/config/extendable/collection.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/ci/config/extendable/entry.rb | 18 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/extendable/collection_spec.rb | 29 |
3 files changed, 42 insertions, 6 deletions
diff --git a/lib/gitlab/ci/config/extendable/collection.rb b/lib/gitlab/ci/config/extendable/collection.rb index 3a71e06e3e2..e59884439a2 100644 --- a/lib/gitlab/ci/config/extendable/collection.rb +++ b/lib/gitlab/ci/config/extendable/collection.rb @@ -6,6 +6,7 @@ module Gitlab include Enumerable ExtensionError = Class.new(StandardError) + CircularDependencyError = Class.new(ExtensionError) def initialize(hash) @hash = hash diff --git a/lib/gitlab/ci/config/extendable/entry.rb b/lib/gitlab/ci/config/extendable/entry.rb index 5844cb098b9..96b0bd1a2ce 100644 --- a/lib/gitlab/ci/config/extendable/entry.rb +++ b/lib/gitlab/ci/config/extendable/entry.rb @@ -5,9 +5,9 @@ module Gitlab class Entry attr_reader :key - def initialize(key, hash, parent = nil) + def initialize(key, context, parent = nil) @key = key - @hash = hash + @context = context @parent = parent end @@ -16,12 +16,12 @@ module Gitlab end def value - @value ||= @hash.fetch(@key) + @value ||= @context.fetch(@key) end def base Extendable::Entry - .new(extends, @hash, self) + .new(extends, @context, self) .extend! end @@ -33,9 +33,17 @@ module Gitlab value.fetch(:extends).to_sym end + def path + Array(@parent&.path).compact.push(key) + end + def extend! + if path.count(key) > 1 + raise Extendable::Collection::CircularDependencyError + end + if extensible? - @hash[key] = base.deep_merge(value) + @context[key] = base.deep_merge(value) else value end diff --git a/spec/lib/gitlab/ci/config/extendable/collection_spec.rb b/spec/lib/gitlab/ci/config/extendable/collection_spec.rb index 453c7357561..e3be0704f1a 100644 --- a/spec/lib/gitlab/ci/config/extendable/collection_spec.rb +++ b/spec/lib/gitlab/ci/config/extendable/collection_spec.rb @@ -117,6 +117,33 @@ describe Gitlab::Ci::Config::Extendable::Collection do end pending 'when invalid `extends` is specified' - pending 'when circular dependecy has been detected' + context 'when circular dependecy has been detected' do + let(:hash) do + { + test: { + extends: 'something', + script: 'ls', + only: { refs: %w[master] } + }, + + something: { + extends: '.first', + script: 'deploy', + only: { variables: %w[$SOMETHING] } + }, + + '.first': { + extends: 'something', + script: 'run', + only: { kubernetes: 'active' } + } + } + end + + it 'raises an error' do + expect { subject.extend! } + .to raise_error(described_class::CircularDependencyError) + end + end end end |