summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/config/entry/root.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/config/entry/root.rb')
-rw-r--r--lib/gitlab/ci/config/entry/root.rb146
1 files changed, 146 insertions, 0 deletions
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
new file mode 100644
index 00000000000..0589ad3edf9
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -0,0 +1,146 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # This class represents a global entry - root Entry for entire
+ # GitLab CI Configuration file.
+ #
+ class Root < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Configurable
+
+ ALLOWED_KEYS = %i[default include before_script image services
+ after_script variables stages types cache].freeze
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+ end
+
+ # reserved:
+ # defines whether the node name is reserved
+ # the reserved name cannot be used a job name
+ # reserved should not be used as it will make
+ # breaking change to `.gitlab-ci.yml`
+
+ entry :default, Entry::Default,
+ description: 'Default configuration for all jobs.',
+ default: {}
+
+ entry :include, Entry::Includes,
+ description: 'List of external YAML files to include.',
+ reserved: true
+
+ entry :before_script, Entry::Script,
+ description: 'Script that will be executed before each job.',
+ reserved: true
+
+ entry :image, Entry::Image,
+ description: 'Docker image that will be used to execute jobs.',
+ reserved: true
+
+ entry :services, Entry::Services,
+ description: 'Docker images that will be linked to the container.',
+ reserved: true
+
+ entry :after_script, Entry::Script,
+ description: 'Script that will be executed after each job.',
+ reserved: true
+
+ entry :variables, Entry::Variables,
+ description: 'Environment variables that will be used.',
+ reserved: true
+
+ entry :stages, Entry::Stages,
+ description: 'Configuration of stages for this pipeline.',
+ reserved: true
+
+ entry :types, Entry::Stages,
+ description: 'Deprecated: stages for this pipeline.',
+ reserved: true
+
+ entry :cache, Entry::Cache,
+ description: 'Configure caching between build jobs.',
+ reserved: true
+
+ helpers :default, :jobs, :stages, :types, :variables
+
+ delegate :before_script_value,
+ :image_value,
+ :services_value,
+ :after_script_value,
+ :cache_value, to: :default
+
+ attr_reader :jobs_config
+
+ class << self
+ include ::Gitlab::Utils::StrongMemoize
+
+ def reserved_nodes_names
+ strong_memoize(:reserved_nodes_names) do
+ self.nodes.select do |_, node|
+ node.reserved?
+ end.keys
+ end
+ end
+ end
+
+ def initialize(config, **metadata)
+ super do
+ filter_jobs!
+ end
+ end
+
+ def compose!(_deps = nil)
+ super(self) do
+ compose_deprecated_entries!
+ compose_jobs!
+ end
+ end
+
+ def default
+ self[:default]
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def compose_jobs!
+ factory = ::Gitlab::Config::Entry::Factory.new(Entry::Jobs)
+ .value(jobs_config)
+ .with(key: :jobs, parent: self,
+ description: 'Jobs definition for this pipeline')
+
+ @entries[:jobs] = factory.create!
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def compose_deprecated_entries!
+ ##
+ # Deprecated `:types` key workaround - if types are defined and
+ # stages are not defined we use types definition as stages.
+ #
+ if types_defined? && !stages_defined?
+ @entries[:stages] = @entries[:types]
+ end
+
+ @entries.delete(:types)
+ end
+
+ def filter_jobs!
+ return unless @config.is_a?(Hash)
+
+ @jobs_config = @config
+ .except(*self.class.reserved_nodes_names) # rubocop: disable CodeReuse/ActiveRecord
+ .select do |name, config|
+ Entry::Jobs.find_type(name, config).present?
+ end
+
+ @config = @config.except(*@jobs_config.keys) # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+ end
+ end
+ end
+end