Move CI stages configuration to new CI config

This commit is contained in:
Grzegorz Bizon 2016-06-23 13:51:07 +02:00
parent 2240807c1a
commit 29b96d92c1
12 changed files with 147 additions and 29 deletions

View file

@ -4,7 +4,6 @@ module Ci
include Gitlab::Ci::Config::Node::LegacyValidationHelpers include Gitlab::Ci::Config::Node::LegacyValidationHelpers
DEFAULT_STAGES = %w(build test deploy)
DEFAULT_STAGE = 'test' DEFAULT_STAGE = 'test'
ALLOWED_YAML_KEYS = [:before_script, :after_script, :image, :services, :types, :stages, :variables, :cache] ALLOWED_YAML_KEYS = [:before_script, :after_script, :image, :services, :types, :stages, :variables, :cache]
ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services,
@ -46,7 +45,7 @@ module Ci
end end
def stages def stages
@stages || DEFAULT_STAGES @stages
end end
def global_variables def global_variables
@ -68,8 +67,8 @@ module Ci
@after_script = @ci_config.after_script @after_script = @ci_config.after_script
@services = @ci_config.services @services = @ci_config.services
@variables = @ci_config.variables @variables = @ci_config.variables
@stages = @ci_config.stages
@stages = @config[:stages] || @config[:types]
@cache = @config[:cache] @cache = @config[:cache]
@jobs = {} @jobs = {}
@ -90,7 +89,7 @@ module Ci
def build_job(name, job) def build_job(name, job)
{ {
stage_idx: stages.index(job[:stage]), stage_idx: @stages.index(job[:stage]),
stage: job[:stage], stage: job[:stage],
commands: [job[:before_script] || @before_script, job[:script]].flatten.compact.join("\n"), commands: [job[:before_script] || @before_script, job[:script]].flatten.compact.join("\n"),
tag_list: job[:tags] || [], tag_list: job[:tags] || [],
@ -112,7 +111,7 @@ module Ci
end end
def validate! def validate!
validate_global! validate_global_cache! if @cache
@jobs.each do |name, job| @jobs.each do |name, job|
validate_job!(name, job) validate_job!(name, job)
@ -121,14 +120,6 @@ module Ci
true true
end 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! def validate_global_cache!
@cache.keys.each do |key| @cache.keys.each do |key|
unless ALLOWED_CACHE_KEYS.include? key unless ALLOWED_CACHE_KEYS.include? key
@ -225,8 +216,8 @@ module Ci
end end
def validate_job_stage!(name, job) def validate_job_stage!(name, job)
unless job[:stage].is_a?(String) && job[:stage].in?(stages) unless job[:stage].is_a?(String) && job[:stage].in?(@stages)
raise ValidationError, "#{name} job: stage parameter should be #{stages.join(", ")}" raise ValidationError, "#{name} job: stage parameter should be #{@stages.join(", ")}"
end end
end end
@ -290,12 +281,12 @@ module Ci
raise ValidationError, "#{name} job: dependencies parameter should be an array of strings" raise ValidationError, "#{name} job: dependencies parameter should be an array of strings"
end end
stage_index = stages.index(job[:stage]) stage_index = @stages.index(job[:stage])
job[:dependencies].each do |dependency| job[:dependencies].each do |dependency|
raise ValidationError, "#{name} job: undefined dependency: #{dependency}" unless @jobs[dependency.to_sym] 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" raise ValidationError, "#{name} job: dependency #{dependency} is not defined in prior stages"
end end
end end

View file

@ -8,7 +8,7 @@ module Gitlab
# Temporary delegations that should be removed after refactoring # Temporary delegations that should be removed after refactoring
# #
delegate :before_script, :image, :services, :after_script, :variables, delegate :before_script, :image, :services, :after_script, :variables,
to: :@global :stages, to: :@global
def initialize(config) def initialize(config)
@config = Loader.new(config).load! @config = Loader.new(config).load!

View file

@ -38,14 +38,20 @@ module Gitlab
private private
def node(symbol, entry_class, metadata) def node(symbol, entry_class, metadata)
factory = Node::Factory.new(entry_class) define_method("#{symbol}_defined?") do
.with(description: metadata[:description]) @nodes[symbol].try(:defined?)
end
define_method(symbol) do define_method("#{symbol}_value") do
raise Entry::InvalidError unless valid? raise Entry::InvalidError unless valid?
@nodes[symbol].try(:value) @nodes[symbol].try(:value)
end end
alias_method symbol.to_sym, "#{symbol}_value".to_sym
factory = Node::Factory.new(entry_class)
.with(description: metadata[:description])
(@nodes ||= {}).merge!(symbol => factory) (@nodes ||= {}).merge!(symbol => factory)
end end
end end

View file

@ -52,6 +52,10 @@ module Gitlab
@config @config
end end
def defined?
true
end
def self.default def self.default
end end

View file

@ -22,7 +22,7 @@ module Gitlab
raise InvalidFactory unless @attributes.has_key?(:value) raise InvalidFactory unless @attributes.has_key?(:value)
## ##
# We assume unspecified entry is undefined. # We assume that unspecified entry is undefined.
# See issue #18775. # See issue #18775.
# #
if @attributes[:value].nil? if @attributes[:value].nil?

View file

@ -23,6 +23,16 @@ module Gitlab
node :variables, Variables, node :variables, Variables,
description: 'Environment variables that will be used.' 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 end
end end

View file

@ -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

View file

@ -19,6 +19,10 @@ module Gitlab
def value def value
@config.default @config.default
end end
def defined?
false
end
end end
end end
end end

View file

@ -1081,17 +1081,17 @@ EOT
end end
it "returns errors if stages is not an array" do 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 expect do
GitlabCiYamlProcessor.new(config, path) 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 end
it "returns errors if stages is not an array of strings" do 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 expect do
GitlabCiYamlProcessor.new(config, path) 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 end
it "returns errors if variables is not a map" do it "returns errors if variables is not a map" do

View file

@ -26,7 +26,8 @@ describe Gitlab::Ci::Config::Node::Global do
image: 'ruby:2.2', image: 'ruby:2.2',
services: ['postgres:9.1', 'mysql:5.5'], services: ['postgres:9.1', 'mysql:5.5'],
variables: { VAR: 'value' }, variables: { VAR: 'value' },
after_script: ['make clean'] } after_script: ['make clean'],
stages: ['build', 'pages'] }
end end
describe '#process!' do describe '#process!' do
@ -37,7 +38,7 @@ describe Gitlab::Ci::Config::Node::Global do
end end
it 'creates node object for each entry' do it 'creates node object for each entry' do
expect(global.nodes.count).to eq 5 expect(global.nodes.count).to eq 7
end end
it 'creates node object using valid class' do 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') expect(global.variables).to eq(VAR: 'value')
end end
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
end end
@ -110,7 +127,7 @@ describe Gitlab::Ci::Config::Node::Global do
describe '#nodes' do describe '#nodes' do
it 'instantizes all nodes' do it 'instantizes all nodes' do
expect(global.nodes.count).to eq 5 expect(global.nodes.count).to eq 7
end end
it 'contains undefined nodes' do it 'contains undefined nodes' do
@ -124,6 +141,12 @@ describe Gitlab::Ci::Config::Node::Global do
expect(global.variables).to eq({}) expect(global.variables).to eq({})
end end
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 end
## ##
@ -188,4 +211,10 @@ describe Gitlab::Ci::Config::Node::Global do
end end
end end
end end
describe '#defined?' do
it 'is concrete entry that is defined' do
expect(global.defined?).to be true
end
end
end end

View file

@ -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

View file

@ -31,4 +31,10 @@ describe Gitlab::Ci::Config::Node::Undefined do
expect(undefined.value).to eq 'some value' expect(undefined.value).to eq 'some value'
end end
end end
describe '#undefined?' do
it 'is not a concrete entry that is defined' do
expect(undefined.defined?).to be false
end
end
end end