summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb25
-rw-r--r--lib/gitlab/ci/config.rb2
-rw-r--r--lib/gitlab/ci/config/node/configurable.rb12
-rw-r--r--lib/gitlab/ci/config/node/entry.rb4
-rw-r--r--lib/gitlab/ci/config/node/factory.rb2
-rw-r--r--lib/gitlab/ci/config/node/global.rb10
-rw-r--r--lib/gitlab/ci/config/node/stages.rb22
-rw-r--r--lib/gitlab/ci/config/node/undefined.rb4
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/node/global_spec.rb35
-rw-r--r--spec/lib/gitlab/ci/config/node/stages_spec.rb46
-rw-r--r--spec/lib/gitlab/ci/config/node/undefined_spec.rb6
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