From c1918fb10b333593837c15bf4a6fa161ca502b4b Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Mon, 17 Jul 2017 12:05:07 +0200 Subject: [PATCH] Add a new `retry` CI/CD configuration keyword --- lib/ci/gitlab_ci_yaml_processor.rb | 3 +- lib/gitlab/ci/config/entry/job.rb | 10 +++-- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 22 +++++++++++ spec/lib/gitlab/ci/config/entry/job_spec.rb | 39 ++++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index cf3a0336792..3a4911b23b0 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -83,7 +83,8 @@ module Ci before_script: job[:before_script], script: job[:script], after_script: job[:after_script], - environment: job[:environment] + environment: job[:environment], + retry: job[:retry] }.compact } end diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb index 176301bcca1..5f1144894b5 100644 --- a/lib/gitlab/ci/config/entry/job.rb +++ b/lib/gitlab/ci/config/entry/job.rb @@ -11,7 +11,7 @@ module Gitlab ALLOWED_KEYS = %i[tags script only except type image services allow_failure type stage when artifacts cache dependencies before_script - after_script variables environment coverage].freeze + after_script variables environment coverage retry].freeze validations do validates :config, allowed_keys: ALLOWED_KEYS @@ -23,6 +23,9 @@ 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: 10 } validates :when, inclusion: { in: %w[on_success on_failure always manual], message: 'should be on_success, on_failure, ' \ @@ -76,9 +79,9 @@ module Gitlab helpers :before_script, :script, :stage, :type, :after_script, :cache, :image, :services, :only, :except, :variables, - :artifacts, :commands, :environment, :coverage + :artifacts, :commands, :environment, :coverage, :retry - attributes :script, :tags, :allow_failure, :when, :dependencies + attributes :script, :tags, :allow_failure, :when, :dependencies, :retry def compose!(deps = nil) super do @@ -142,6 +145,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, artifacts: artifacts_value, after_script: after_script_value, ignore: ignored? } diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index ea79389e67e..e50f799a6e9 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -32,6 +32,28 @@ module Ci end end + describe 'retry entry' do + context 'when retry count is specified' do + let(:config) do + YAML.dump(rspec: { script: 'rspec', retry: 3 }) + end + + it 'includes retry count in build options attribute' do + expect(subject[:options]).to include(retry: 3) + end + end + + context 'when retry count is not specified' do + let(:config) do + YAML.dump(rspec: { script: 'rspec' }) + end + + it 'does not persist retry count in the database' do + expect(subject[:options]).not_to have_key(:retry) + end + end + end + describe 'allow failure entry' do context 'when job is a manual action' do context 'when allow_failure is defined' do diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index c5cad887b64..f8ed59a3a44 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -80,6 +80,45 @@ describe Gitlab::Ci::Config::Entry::Job do expect(entry.errors).to include "job script can't be blank" end end + + context 'when retry value is not correct' do + context 'when it is not a numeric value' do + let(:config) { { retry: true } } + + it 'returns error about invalid type' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry is not a number' + end + end + + context 'when it is lower than zero' do + let(:config) { { retry: -1 } } + + it 'returns error about value too low' do + expect(entry).not_to be_valid + expect(entry.errors) + .to include 'job retry must be greater than or equal to 0' + end + end + + context 'when it is not an integer' do + let(:config) { { retry: 1.5 } } + + it 'returns error about wrong value' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry must be an integer' + end + end + + context 'when the value is too high' do + let(:config) { { retry: 10 } } + + it 'returns error about value too high' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job retry must be less than 10' + end + end + end end end