diff options
Diffstat (limited to 'lib/gitlab/ci/config/entry')
-rw-r--r-- | lib/gitlab/ci/config/entry/artifacts.rb | 9 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/cache.rb | 16 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/default.rb | 26 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/hooks.rb | 25 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/id_token.rb | 28 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/job.rb | 21 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/reports.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/root.rb | 20 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/trigger.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/variable.rb | 85 | ||||
-rw-r--r-- | lib/gitlab/ci/config/entry/variables.rb | 2 |
11 files changed, 138 insertions, 101 deletions
diff --git a/lib/gitlab/ci/config/entry/artifacts.rb b/lib/gitlab/ci/config/entry/artifacts.rb index 3b0cbc6b69e..27206d7e3a8 100644 --- a/lib/gitlab/ci/config/entry/artifacts.rb +++ b/lib/gitlab/ci/config/entry/artifacts.rb @@ -12,6 +12,7 @@ module Gitlab include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Attributable + ALLOWED_WHEN = %w[on_success on_failure always].freeze ALLOWED_KEYS = %i[name untracked paths reports when expire_in expose_as exclude public].freeze EXPOSE_AS_REGEX = /\A\w[-\w ]*\z/.freeze EXPOSE_AS_ERROR_MESSAGE = "can contain only letters, digits, '-', '_' and spaces" @@ -38,10 +39,10 @@ module Gitlab validates :expose_as, format: { with: EXPOSE_AS_REGEX, message: EXPOSE_AS_ERROR_MESSAGE }, if: :expose_as_present? validates :exclude, array_of_strings: true validates :reports, type: Hash - validates :when, - inclusion: { in: %w[on_success on_failure always], - message: 'should be on_success, on_failure ' \ - 'or always' } + validates :when, type: String, inclusion: { + in: ALLOWED_WHEN, + message: "should be one of: #{ALLOWED_WHEN.join(', ')}" + } validates :expire_in, duration: { parser: ::Gitlab::Ci::Build::DurationParser } end end diff --git a/lib/gitlab/ci/config/entry/cache.rb b/lib/gitlab/ci/config/entry/cache.rb index ab79add688b..a5481071fc5 100644 --- a/lib/gitlab/ci/config/entry/cache.rb +++ b/lib/gitlab/ci/config/entry/cache.rb @@ -17,16 +17,16 @@ module Gitlab validations do validates :config, type: Hash, allowed_keys: ALLOWED_KEYS - validates :policy, - inclusion: { in: ALLOWED_POLICY, message: 'should be pull-push, push, or pull' }, - allow_blank: true + validates :policy, type: String, allow_blank: true, inclusion: { + in: ALLOWED_POLICY, + message: "should be one of: #{ALLOWED_POLICY.join(', ')}" + } with_options allow_nil: true do - validates :when, - inclusion: { - in: ALLOWED_WHEN, - message: 'should be on_success, on_failure or always' - } + validates :when, type: String, inclusion: { + in: ALLOWED_WHEN, + message: "should be one of: #{ALLOWED_WHEN.join(', ')}" + } end end diff --git a/lib/gitlab/ci/config/entry/default.rb b/lib/gitlab/ci/config/entry/default.rb index 12d68b755b3..e996b6b1312 100644 --- a/lib/gitlab/ci/config/entry/default.rb +++ b/lib/gitlab/ci/config/entry/default.rb @@ -13,9 +13,8 @@ module Gitlab include ::Gitlab::Config::Entry::Configurable include ::Gitlab::Config::Entry::Inheritable - ALLOWED_KEYS = %i[before_script image services - after_script cache interruptible - timeout retry tags artifacts].freeze + ALLOWED_KEYS = %i[before_script after_script hooks cache image services + interruptible timeout retry tags artifacts].freeze validations do validates :config, allowed_keys: ALLOWED_KEYS @@ -25,22 +24,27 @@ module Gitlab description: 'Script that will be executed before each job.', inherit: true - entry :image, Entry::Image, - description: 'Docker image that will be used to execute jobs.', - inherit: true - - entry :services, Entry::Services, - description: 'Docker images that will be linked to the container.', - inherit: true - entry :after_script, Entry::Commands, description: 'Script that will be executed after each job.', inherit: true + entry :hooks, Entry::Hooks, + description: 'Commands that will be executed on Runner before/after some events ' \ + 'such as `clone` and `build-script`.', + inherit: false + entry :cache, Entry::Caches, description: 'Configure caching between build jobs.', inherit: true + entry :image, Entry::Image, + description: 'Docker image that will be used to execute jobs.', + inherit: true + + entry :services, Entry::Services, + description: 'Docker images that will be linked to the container.', + inherit: true + entry :interruptible, ::Gitlab::Config::Entry::Boolean, description: 'Set jobs interruptible default value.', inherit: false diff --git a/lib/gitlab/ci/config/entry/hooks.rb b/lib/gitlab/ci/config/entry/hooks.rb new file mode 100644 index 00000000000..28bc2e4e7ce --- /dev/null +++ b/lib/gitlab/ci/config/entry/hooks.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + class Config + module Entry + class Hooks < ::Gitlab::Config::Entry::Node + # `Configurable` alreadys adds `Validatable` + include ::Gitlab::Config::Entry::Configurable + + # NOTE: If a new hook is added, inheriting should be changed because a `job:hooks` overrides all + # `default:hooks` now. We should implement merging; each hook must be overridden individually. + ALLOWED_HOOKS = %i[pre_get_sources_script].freeze + + validations do + validates :config, type: Hash, allowed_keys: ALLOWED_HOOKS + end + + entry :pre_get_sources_script, Entry::Commands, + description: 'Commands that will be executed on Runner before cloning/fetching the Git repository.' + end + end + end + end +end diff --git a/lib/gitlab/ci/config/entry/id_token.rb b/lib/gitlab/ci/config/entry/id_token.rb new file mode 100644 index 00000000000..12e0975d1b1 --- /dev/null +++ b/lib/gitlab/ci/config/entry/id_token.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + class Config + module Entry + ## + # Entry that represents a JWT definition. + # + class IdToken < ::Gitlab::Config::Entry::Node + include ::Gitlab::Config::Entry::Attributable + include ::Gitlab::Config::Entry::Validatable + + attributes %i[aud] + + validations do + validates :config, required_keys: %i[aud], allowed_keys: %i[aud] + validates :aud, array_of_strings_or_string: true + end + + def value + { aud: aud } + end + end + end + end + end +end diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 8e7f6ba4326..7c49b59a7f0 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -12,9 +12,9 @@ module Gitlab ALLOWED_WHEN = %w[on_success on_failure always manual delayed].freeze ALLOWED_KEYS = %i[tags script image services start_in artifacts - cache dependencies before_script after_script + cache dependencies before_script after_script hooks environment coverage retry parallel interruptible timeout - release].freeze + release id_tokens].freeze validations do validates :config, allowed_keys: Gitlab::Ci::Config::Entry::Job.allowed_keys + PROCESSABLE_ALLOWED_KEYS @@ -59,6 +59,10 @@ module Gitlab description: 'Commands that will be executed when finishing job.', inherit: true + entry :hooks, Entry::Hooks, + description: 'Commands that will be executed on Runner before/after some events; clone, build-script.', + inherit: true + entry :cache, Entry::Caches, description: 'Cache definition for this job.', inherit: true @@ -116,6 +120,11 @@ module Gitlab description: 'Indicates whether this job is allowed to fail or not.', inherit: false + entry :id_tokens, ::Gitlab::Config::Entry::ComposableHash, + description: 'Configured JWTs for this job', + inherit: false, + metadata: { composable_class: ::Gitlab::Ci::Config::Entry::IdToken } + attributes :script, :tags, :when, :dependencies, :needs, :retry, :parallel, :start_in, :interruptible, :timeout, @@ -155,10 +164,12 @@ module Gitlab artifacts: artifacts_value, release: release_value, after_script: after_script_value, + hooks: hooks_pre_get_sources_script_enabled? ? hooks_value : nil, ignore: ignored?, allow_failure_criteria: allow_failure_criteria, needs: needs_defined? ? needs_value : nil, - scheduling_type: needs_defined? ? :dag : :stage + scheduling_type: needs_defined? ? :dag : :stage, + id_tokens: id_tokens_value ).compact end @@ -183,6 +194,10 @@ module Gitlab allow_failure_value end + + def hooks_pre_get_sources_script_enabled? + YamlProcessor::FeatureFlags.enabled?(:ci_hooks_pre_get_sources_script) + end end end end diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb index f77876cc926..16844fa88db 100644 --- a/lib/gitlab/ci/config/entry/reports.rb +++ b/lib/gitlab/ci/config/entry/reports.rb @@ -16,8 +16,8 @@ module Gitlab %i[junit codequality sast secret_detection dependency_scanning container_scanning dast performance browser_performance load_performance license_scanning metrics lsif dotenv terraform accessibility - requirements coverage_fuzzing api_fuzzing cluster_image_scanning - coverage_report cyclonedx].freeze + coverage_fuzzing api_fuzzing cluster_image_scanning + requirements requirements_v2 coverage_report cyclonedx].freeze attributes ALLOWED_KEYS @@ -48,6 +48,7 @@ module Gitlab validates :terraform, array_of_strings_or_string: true validates :accessibility, array_of_strings_or_string: true validates :requirements, array_of_strings_or_string: true + validates :requirements_v2, array_of_strings_or_string: true validates :cyclonedx, array_of_strings_or_string: true end end diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb index a30e6a0d9c3..a3d57ab6ac6 100644 --- a/lib/gitlab/ci/config/entry/root.rb +++ b/lib/gitlab/ci/config/entry/root.rb @@ -50,7 +50,7 @@ module Gitlab entry :variables, Entry::Variables, description: 'Environment variables that will be used.', - metadata: { allowed_value_data: %i[value description expand], allow_array_value: true }, + metadata: { allowed_value_data: %i[value description expand options] }, reserved: true entry :stages, Entry::Stages, @@ -103,12 +103,16 @@ module Gitlab # 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') + factory = logger.instrument(:config_root_compose_jobs_factory, once: true) do + ::Gitlab::Config::Entry::Factory.new(Entry::Jobs) + .value(jobs_config) + .with(key: :jobs, parent: self, + description: 'Jobs definition for this pipeline') + end - @entries[:jobs] = factory.create! + @entries[:jobs] = logger.instrument(:config_root_compose_jobs_create, once: true) do + factory.create! + end end # rubocop: enable CodeReuse/ActiveRecord @@ -123,6 +127,10 @@ module Gitlab @config = @config.except(*@jobs_config.keys) end + + def logger + metadata[:logger] + end end end end diff --git a/lib/gitlab/ci/config/entry/trigger.rb b/lib/gitlab/ci/config/entry/trigger.rb index 0f94b3f94fe..4c254a4fa07 100644 --- a/lib/gitlab/ci/config/entry/trigger.rb +++ b/lib/gitlab/ci/config/entry/trigger.rb @@ -41,7 +41,7 @@ module Gitlab validations do validates :config, presence: true validates :config, allowed_keys: ALLOWED_KEYS - validates :project, presence: true + validates :project, type: String, presence: true validates :branch, type: String, allow_nil: true validates :strategy, type: String, inclusion: { in: %w[depend], message: 'should be depend' }, allow_nil: true end diff --git a/lib/gitlab/ci/config/entry/variable.rb b/lib/gitlab/ci/config/entry/variable.rb index 16091758916..decb568ffc9 100644 --- a/lib/gitlab/ci/config/entry/variable.rb +++ b/lib/gitlab/ci/config/entry/variable.rb @@ -10,7 +10,6 @@ module Gitlab class Variable < ::Gitlab::Config::Entry::Simplifiable strategy :SimpleVariable, if: -> (config) { SimpleVariable.applies_to?(config) } strategy :ComplexVariable, if: -> (config) { ComplexVariable.applies_to?(config) } - strategy :ComplexArrayVariable, if: -> (config) { ComplexArrayVariable.applies_to?(config) } class SimpleVariable < ::Gitlab::Config::Entry::Node include ::Gitlab::Config::Entry::Validatable @@ -41,20 +40,24 @@ module Gitlab class ComplexVariable < ::Gitlab::Config::Entry::Node include ::Gitlab::Config::Entry::Validatable + include ::Gitlab::Config::Entry::Attributable class << self def applies_to?(config) - config.is_a?(Hash) && !config[:value].is_a?(Array) + config.is_a?(Hash) end end + attributes :value, :description, :expand, :options, prefix: :config + validations do validates :key, alphanumeric: true - validates :config_value, alphanumeric: true, allow_nil: false, if: :config_value_defined? - validates :config_description, alphanumeric: true, allow_nil: false, if: :config_description_defined? - validates :config_expand, boolean: true, - allow_nil: false, - if: -> { ci_raw_variables_in_yaml_config_enabled? && config_expand_defined? } + validates :config_value, alphanumeric: true, allow_nil: true + validates :config_description, alphanumeric: true, allow_nil: true + validates :config_expand, boolean: true, allow_nil: true, if: -> { + ci_raw_variables_in_yaml_config_enabled? + } + validates :config_options, array_of_strings: true, allow_nil: true validate do allowed_value_data = Array(opt(:allowed_value_data)) @@ -66,91 +69,43 @@ module Gitlab else errors.add(:config, "must be a string") end + + if config_options.present? && config_options.exclude?(config_value) + errors.add(:config, 'value must be present in options') + end end end def value + # Needed since the `Entry::Node` provides `value` (which is current hash) config_value.to_s end def value_with_data if ci_raw_variables_in_yaml_config_enabled? { - value: value, - raw: (!config_expand if config_expand_defined?) + value: config_value.to_s, + raw: (!config_expand if has_config_expand?) }.compact else { - value: value + value: config_value.to_s }.compact end end def value_with_prefill_data value_with_data.merge( - description: config_description + description: config_description, + options: config_options ).compact end - def config_value - @config[:value] - end - - def config_description - @config[:description] - end - - def config_expand - @config[:expand] - end - - def config_value_defined? - config.key?(:value) - end - - def config_description_defined? - config.key?(:description) - end - - def config_expand_defined? - config.key?(:expand) - end - def ci_raw_variables_in_yaml_config_enabled? YamlProcessor::FeatureFlags.enabled?(:ci_raw_variables_in_yaml_config) end end - class ComplexArrayVariable < ComplexVariable - include ::Gitlab::Config::Entry::Validatable - - class << self - def applies_to?(config) - config.is_a?(Hash) && config[:value].is_a?(Array) - end - end - - validations do - validates :config_value, array_of_strings: true, allow_nil: false, if: :config_value_defined? - - validate do - next if opt(:allow_array_value) - - errors.add(:config, 'value must be an alphanumeric string') - end - end - - def value - config_value.first - end - - def value_with_prefill_data - super.merge( - value_options: config_value - ).compact - end - end - class UnknownStrategy < ::Gitlab::Config::Entry::Node def errors ["variable definition must be either a string or a hash"] diff --git a/lib/gitlab/ci/config/entry/variables.rb b/lib/gitlab/ci/config/entry/variables.rb index ef4f74b9f56..e338bce3109 100644 --- a/lib/gitlab/ci/config/entry/variables.rb +++ b/lib/gitlab/ci/config/entry/variables.rb @@ -42,7 +42,7 @@ module Gitlab end def composable_metadata - { allowed_value_data: opt(:allowed_value_data), allow_array_value: opt(:allow_array_value) } + { allowed_value_data: opt(:allowed_value_data) } end end end |