summaryrefslogtreecommitdiff
path: root/lib/gitlab
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzegorz@gitlab.com>2018-11-07 15:02:18 +0000
committerGrzegorz Bizon <grzegorz@gitlab.com>2018-11-07 15:02:18 +0000
commitf323d6148b7b71609cbd32ab9db4724fc108729d (patch)
tree28762cadb685f35a7a4b70bbf243a3023e999262 /lib/gitlab
parent5dc0577b84b9d41b1e2a6e781dfeaa400e8e2c10 (diff)
parent0c59fdaab69e93e2f00fdf70f2a31bb095e3d8d0 (diff)
downloadgitlab-ce-f323d6148b7b71609cbd32ab9db4724fc108729d.tar.gz
Merge branch 'max_retries_when' into 'master'
Allow to configure when to retry builds Closes gitlab-runner#3515 See merge request gitlab-org/gitlab-ce!21758
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/ci/config/entry/job.rb9
-rw-r--r--lib/gitlab/ci/config/entry/retry.rb90
-rw-r--r--lib/gitlab/ci/config/entry/validators.rb24
3 files changed, 115 insertions, 8 deletions
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 362014b1a09..8e8c979f973 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -26,16 +26,12 @@ module Gitlab
with_options allow_nil: true do
validates :tags, array_of_strings: true
validates :allow_failure, boolean: true
- validates :retry, numericality: { only_integer: true,
- greater_than_or_equal_to: 0,
- less_than_or_equal_to: 2 }
validates :parallel, numericality: { only_integer: true,
greater_than_or_equal_to: 2 }
validates :when,
inclusion: { in: %w[on_success on_failure always manual delayed],
message: 'should be on_success, on_failure, ' \
'always, manual or delayed' }
-
validates :dependencies, array_of_strings: true
validates :extends, type: String
end
@@ -86,6 +82,9 @@ module Gitlab
entry :coverage, Entry::Coverage,
description: 'Coverage configuration for this job.'
+ entry :retry, Entry::Retry,
+ description: 'Retry configuration for this job.'
+
helpers :before_script, :script, :stage, :type, :after_script,
:cache, :image, :services, :only, :except, :variables,
:artifacts, :commands, :environment, :coverage, :retry,
@@ -160,7 +159,7 @@ module Gitlab
environment: environment_defined? ? environment_value : nil,
environment_name: environment_defined? ? environment_value[:name] : nil,
coverage: coverage_defined? ? coverage_value : nil,
- retry: retry_defined? ? retry_value.to_i : nil,
+ retry: retry_defined? ? retry_value : nil,
parallel: parallel_defined? ? parallel_value.to_i : nil,
artifacts: artifacts_value,
after_script: after_script_value,
diff --git a/lib/gitlab/ci/config/entry/retry.rb b/lib/gitlab/ci/config/entry/retry.rb
new file mode 100644
index 00000000000..e39cc5de229
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/retry.rb
@@ -0,0 +1,90 @@
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents a retry config for a job.
+ #
+ class Retry < Simplifiable
+ strategy :SimpleRetry, if: -> (config) { config.is_a?(Integer) }
+ strategy :FullRetry, if: -> (config) { config.is_a?(Hash) }
+
+ class SimpleRetry < Entry::Node
+ include Entry::Validatable
+
+ validations do
+ validates :config, numericality: { only_integer: true,
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: 2 }
+ end
+
+ def value
+ {
+ max: config
+ }
+ end
+
+ def location
+ 'retry'
+ end
+ end
+
+ class FullRetry < Entry::Node
+ include Entry::Validatable
+ include Entry::Attributable
+
+ ALLOWED_KEYS = %i[max when].freeze
+ attributes :max, :when
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+
+ with_options allow_nil: true do
+ validates :max, numericality: { only_integer: true,
+ greater_than_or_equal_to: 0,
+ less_than_or_equal_to: 2 }
+
+ validates :when, array_of_strings_or_string: true
+ validates :when,
+ allowed_array_values: { in: FullRetry.possible_retry_when_values },
+ if: -> (config) { config.when.is_a?(Array) }
+ validates :when,
+ inclusion: { in: FullRetry.possible_retry_when_values },
+ if: -> (config) { config.when.is_a?(String) }
+ end
+ end
+
+ def self.possible_retry_when_values
+ @possible_retry_when_values ||= ::Ci::Build.failure_reasons.keys.map(&:to_s) + ['always']
+ end
+
+ def value
+ super.tap do |config|
+ # make sure that `when` is an array, because we allow it to
+ # be passed as a String in config for simplicity
+ config[:when] = Array.wrap(config[:when]) if config[:when]
+ end
+ end
+
+ def location
+ 'retry'
+ end
+ end
+
+ class UnknownStrategy < Entry::Node
+ def errors
+ ["#{location} has to be either an integer or a hash"]
+ end
+
+ def location
+ 'retry config'
+ end
+ end
+
+ def self.default
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/validators.rb b/lib/gitlab/ci/config/entry/validators.rb
index 805d26ca8d8..a1d552fb2e5 100644
--- a/lib/gitlab/ci/config/entry/validators.rb
+++ b/lib/gitlab/ci/config/entry/validators.rb
@@ -7,11 +7,11 @@ module Gitlab
module Validators
class AllowedKeysValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
- unknown_keys = record.config.try(:keys).to_a - options[:in]
+ unknown_keys = value.try(:keys).to_a - options[:in]
if unknown_keys.any?
- record.errors.add(:config, 'contains unknown keys: ' +
- unknown_keys.join(', '))
+ record.errors.add(attribute, "contains unknown keys: " +
+ unknown_keys.join(', '))
end
end
end
@@ -24,6 +24,16 @@ module Gitlab
end
end
+ class AllowedArrayValuesValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unkown_values = value - options[:in]
+ unless unkown_values.empty?
+ record.errors.add(attribute, "contains unknown values: " +
+ unkown_values.join(', '))
+ end
+ end
+ end
+
class ArrayOfStringsValidator < ActiveModel::EachValidator
include LegacyValidationHelpers
@@ -68,6 +78,14 @@ module Gitlab
end
end
+ class HashOrIntegerValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ unless value.is_a?(Hash) || value.is_a?(Integer)
+ record.errors.add(attribute, 'should be a hash or an integer')
+ end
+ end
+ end
+
class KeyValidator < ActiveModel::EachValidator
include LegacyValidationHelpers