diff options
-rw-r--r-- | lib/ci/gitlab_ci_yaml_processor.rb | 25 | ||||
-rw-r--r-- | lib/gitlab/ci/config.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/configurable.rb | 12 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/entry.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/factory.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/global.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/stages.rb | 22 | ||||
-rw-r--r-- | lib/gitlab/ci/config/node/undefined.rb | 4 | ||||
-rw-r--r-- | spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/global_spec.rb | 35 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/stages_spec.rb | 46 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/node/undefined_spec.rb | 6 |
12 files changed, 147 insertions, 29 deletions
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 436b0127c3d..f0c3eae661e 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -4,7 +4,6 @@ module Ci include Gitlab::Ci::Config::Node::LegacyValidationHelpers - DEFAULT_STAGES = %w(build test deploy) DEFAULT_STAGE = 'test' ALLOWED_YAML_KEYS = [:before_script, :after_script, :image, :services, :types, :stages, :variables, :cache] ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, @@ -46,7 +45,7 @@ module Ci end def stages - @stages || DEFAULT_STAGES + @stages end def global_variables @@ -68,8 +67,8 @@ module Ci @after_script = @ci_config.after_script @services = @ci_config.services @variables = @ci_config.variables + @stages = @ci_config.stages - @stages = @config[:stages] || @config[:types] @cache = @config[:cache] @jobs = {} @@ -90,7 +89,7 @@ module Ci def build_job(name, job) { - stage_idx: stages.index(job[:stage]), + stage_idx: @stages.index(job[:stage]), stage: job[:stage], commands: [job[:before_script] || @before_script, job[:script]].flatten.compact.join("\n"), tag_list: job[:tags] || [], @@ -112,7 +111,7 @@ module Ci end def validate! - validate_global! + validate_global_cache! if @cache @jobs.each do |name, job| validate_job!(name, job) @@ -121,14 +120,6 @@ module Ci true end - def validate_global! - unless @stages.nil? || validate_array_of_strings(@stages) - raise ValidationError, "stages should be an array of strings" - end - - validate_global_cache! if @cache - end - def validate_global_cache! @cache.keys.each do |key| unless ALLOWED_CACHE_KEYS.include? key @@ -225,8 +216,8 @@ module Ci end def validate_job_stage!(name, job) - unless job[:stage].is_a?(String) && job[:stage].in?(stages) - raise ValidationError, "#{name} job: stage parameter should be #{stages.join(", ")}" + unless job[:stage].is_a?(String) && job[:stage].in?(@stages) + raise ValidationError, "#{name} job: stage parameter should be #{@stages.join(", ")}" end end @@ -290,12 +281,12 @@ module Ci raise ValidationError, "#{name} job: dependencies parameter should be an array of strings" end - stage_index = stages.index(job[:stage]) + stage_index = @stages.index(job[:stage]) job[:dependencies].each do |dependency| raise ValidationError, "#{name} job: undefined dependency: #{dependency}" unless @jobs[dependency.to_sym] - unless stages.index(@jobs[dependency.to_sym][:stage]) < stage_index + unless @stages.index(@jobs[dependency.to_sym][:stage]) < stage_index raise ValidationError, "#{name} job: dependency #{dependency} is not defined in prior stages" end end diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb index 1bea9c21f6a..61a2d2069a3 100644 --- a/lib/gitlab/ci/config.rb +++ b/lib/gitlab/ci/config.rb @@ -8,7 +8,7 @@ module Gitlab # Temporary delegations that should be removed after refactoring # delegate :before_script, :image, :services, :after_script, :variables, - to: :@global + :stages, to: :@global def initialize(config) @config = Loader.new(config).load! diff --git a/lib/gitlab/ci/config/node/configurable.rb b/lib/gitlab/ci/config/node/configurable.rb index 0fb9092dafa..61e4f1cee2c 100644 --- a/lib/gitlab/ci/config/node/configurable.rb +++ b/lib/gitlab/ci/config/node/configurable.rb @@ -38,14 +38,20 @@ module Gitlab private def node(symbol, entry_class, metadata) - factory = Node::Factory.new(entry_class) - .with(description: metadata[:description]) + define_method("#{symbol}_defined?") do + @nodes[symbol].try(:defined?) + end - define_method(symbol) do + define_method("#{symbol}_value") do raise Entry::InvalidError unless valid? @nodes[symbol].try(:value) end + alias_method symbol.to_sym, "#{symbol}_value".to_sym + + factory = Node::Factory.new(entry_class) + .with(description: metadata[:description]) + (@nodes ||= {}).merge!(symbol => factory) end end diff --git a/lib/gitlab/ci/config/node/entry.rb b/lib/gitlab/ci/config/node/entry.rb index 444a276d5c9..e6f738b1795 100644 --- a/lib/gitlab/ci/config/node/entry.rb +++ b/lib/gitlab/ci/config/node/entry.rb @@ -52,6 +52,10 @@ module Gitlab @config end + def defined? + true + end + def self.default end diff --git a/lib/gitlab/ci/config/node/factory.rb b/lib/gitlab/ci/config/node/factory.rb index 647b0c82a79..39b5784af25 100644 --- a/lib/gitlab/ci/config/node/factory.rb +++ b/lib/gitlab/ci/config/node/factory.rb @@ -22,7 +22,7 @@ module Gitlab raise InvalidFactory unless @attributes.has_key?(:value) ## - # We assume unspecified entry is undefined. + # We assume that unspecified entry is undefined. # See issue #18775. # if @attributes[:value].nil? diff --git a/lib/gitlab/ci/config/node/global.rb b/lib/gitlab/ci/config/node/global.rb index b5d177c5285..88f9bb3f43e 100644 --- a/lib/gitlab/ci/config/node/global.rb +++ b/lib/gitlab/ci/config/node/global.rb @@ -23,6 +23,16 @@ module Gitlab node :variables, Variables, description: 'Environment variables that will be used.' + + node :stages, Stages, + description: 'Configuration of stages for this pipeline.' + + node :types, Stages, + description: 'Stages for this pipeline (deprecated key).' + + def stages + stages_defined? ? stages_value : types_value + end end end end diff --git a/lib/gitlab/ci/config/node/stages.rb b/lib/gitlab/ci/config/node/stages.rb new file mode 100644 index 00000000000..88d88252bce --- /dev/null +++ b/lib/gitlab/ci/config/node/stages.rb @@ -0,0 +1,22 @@ +module Gitlab + module Ci + class Config + module Node + ## + # Entry that represents a configuration for pipeline stages. + # + class Stages < Entry + include Validatable + + validations do + validates :config, array_of_strings: true + end + + def self.default + %w(build test deploy) + end + end + end + end + end +end diff --git a/lib/gitlab/ci/config/node/undefined.rb b/lib/gitlab/ci/config/node/undefined.rb index e8a69b810e0..699605e1e3a 100644 --- a/lib/gitlab/ci/config/node/undefined.rb +++ b/lib/gitlab/ci/config/node/undefined.rb @@ -19,6 +19,10 @@ module Gitlab def value @config.default end + + def defined? + false + end end end end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index eb20f5f4c06..3f732d2ca2a 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -1081,17 +1081,17 @@ EOT end it "returns errors if stages is not an array" do - config = YAML.dump({ types: "test", rspec: { script: "test" } }) + config = YAML.dump({ stages: "test", rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Stages config should be an array of strings") end it "returns errors if stages is not an array of strings" do - config = YAML.dump({ types: [true, "test"], rspec: { script: "test" } }) + config = YAML.dump({ stages: [true, "test"], rspec: { script: "test" } }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "stages should be an array of strings") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Stages config should be an array of strings") end it "returns errors if variables is not a map" do diff --git a/spec/lib/gitlab/ci/config/node/global_spec.rb b/spec/lib/gitlab/ci/config/node/global_spec.rb index 36a5b8041f0..6aef6b913cf 100644 --- a/spec/lib/gitlab/ci/config/node/global_spec.rb +++ b/spec/lib/gitlab/ci/config/node/global_spec.rb @@ -26,7 +26,8 @@ describe Gitlab::Ci::Config::Node::Global do image: 'ruby:2.2', services: ['postgres:9.1', 'mysql:5.5'], variables: { VAR: 'value' }, - after_script: ['make clean'] } + after_script: ['make clean'], + stages: ['build', 'pages'] } end describe '#process!' do @@ -37,7 +38,7 @@ describe Gitlab::Ci::Config::Node::Global do end it 'creates node object for each entry' do - expect(global.nodes.count).to eq 5 + expect(global.nodes.count).to eq 7 end it 'creates node object using valid class' do @@ -101,6 +102,22 @@ describe Gitlab::Ci::Config::Node::Global do expect(global.variables).to eq(VAR: 'value') end end + + describe '#stages' do + context 'when stages key defined' do + it 'returns array of stages' do + expect(global.stages).to eq %w[build pages] + end + end + + context 'when deprecated types key defined' do + let(:hash) { { types: ['test', 'deploy'] } } + + it 'returns array of types as stages' do + expect(global.stages).to eq %w[test deploy] + end + end + end end end @@ -110,7 +127,7 @@ describe Gitlab::Ci::Config::Node::Global do describe '#nodes' do it 'instantizes all nodes' do - expect(global.nodes.count).to eq 5 + expect(global.nodes.count).to eq 7 end it 'contains undefined nodes' do @@ -124,6 +141,12 @@ describe Gitlab::Ci::Config::Node::Global do expect(global.variables).to eq({}) end end + + describe '#stages' do + it 'returns an array of default stages' do + expect(global.stages).to eq %w[build test deploy] + end + end end ## @@ -188,4 +211,10 @@ describe Gitlab::Ci::Config::Node::Global do end end end + + describe '#defined?' do + it 'is concrete entry that is defined' do + expect(global.defined?).to be true + end + end end diff --git a/spec/lib/gitlab/ci/config/node/stages_spec.rb b/spec/lib/gitlab/ci/config/node/stages_spec.rb new file mode 100644 index 00000000000..dbf2eb8993d --- /dev/null +++ b/spec/lib/gitlab/ci/config/node/stages_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Node::Stages do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when entry config value is correct' do + let(:config) { [:stage1, :stage2] } + + describe '#value' do + it 'returns array of stages' do + expect(entry.value).to eq config + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + end + + context 'when entry value is not correct' do + let(:config) { { test: true } } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'Stages config should be an array of strings' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + end + + describe '.default' do + it 'returns default stages' do + expect(described_class.default).to eq %w[build test deploy] + end + end +end diff --git a/spec/lib/gitlab/ci/config/node/undefined_spec.rb b/spec/lib/gitlab/ci/config/node/undefined_spec.rb index 5ded0504a3f..4318dfe6e53 100644 --- a/spec/lib/gitlab/ci/config/node/undefined_spec.rb +++ b/spec/lib/gitlab/ci/config/node/undefined_spec.rb @@ -31,4 +31,10 @@ describe Gitlab::Ci::Config::Node::Undefined do expect(undefined.value).to eq 'some value' end end + + describe '#undefined?' do + it 'is not a concrete entry that is defined' do + expect(undefined.defined?).to be false + end + end end |