Commit 977ea357 authored by Matija Čupić's avatar Matija Čupić

Separate bridge and DAG needs

Separates bridge and DAG needs into two separate entities to avoid any
ambiguity.
parent 2f1f43ae
......@@ -8,17 +8,60 @@ module EE
##
# Entry that represents a cross-project needs dependency.
#
class Needs < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
class Needs < ::Gitlab::Config::Entry::Simplifiable
strategy :BridgeNeeds, if: -> (config) { config.is_a?(Hash) }
strategy :ComplexNeeds, if: -> (config) { config.is_a?(Array) }
ALLOWED_KEYS = %i[pipeline].freeze
attributes :pipeline
class BridgeNeeds < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
validations do
validates :config, presence: true
validates :config, allowed_keys: ALLOWED_KEYS
validates :pipeline, type: String, presence: true
ALLOWED_KEYS = %i[pipeline].freeze
attributes :pipeline
validations do
validates :config, presence: true
validates :config, allowed_keys: ALLOWED_KEYS
validates :pipeline, type: String, presence: true
end
end
class ComplexNeeds < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
validations do
validates :config, presence: true
validates :config, type: Array
validate :one_needs_pipeline
validate :needs_array_elements
end
def one_needs_pipeline
if config.count { |element| element.is_a?(Hash) } > 1
errors.add(:needs, 'needs hash element needs to have a pipeline key')
end
end
def needs_array_elements
config.each do |element|
next if element.is_a?(String)
unless element.is_a?(Hash) && element[:pipeline]
errors.add(:needs, 'needs hash element needs to have a pipeline key')
end
end
end
def value
bridge, pipeline = config.partition { |element| element.is_a?(Hash) }
{ bridge: bridge.first, pipeline: pipeline }
end
end
class UnknownStrategy < ::Gitlab::Config::Entry::Node
def errors
["#{location} has to be either an array of conditions or a hash"]
end
end
end
end
......
......@@ -6,37 +6,22 @@ require_dependency 'active_model'
describe EE::Gitlab::Ci::Config::Entry::Needs do
subject { described_class.new(config) }
context 'when upstream config is a non-empty string' do
let(:config) { { pipeline: 'some/project' } }
context 'when needs is a bridge needs' do
context 'when upstream config is a non-empty string' do
let(:config) { { pipeline: 'some/project' } }
describe '#valid?' do
it { is_expected.to be_valid }
end
describe '#value' do
it 'is returns a upstream configuration hash' do
expect(subject.value).to eq(pipeline: 'some/project')
describe '#valid?' do
it { is_expected.to be_valid }
end
end
end
context 'when upstream config an empty string' do
let(:config) { '' }
describe '#valid?' do
it { is_expected.not_to be_valid }
end
describe '#errors' do
it 'is returns an error about an empty config' do
expect(subject.errors.first)
.to eq("needs config can't be blank")
describe '#value' do
it 'is returns a upstream configuration hash' do
expect(subject.value).to eq(pipeline: 'some/project')
end
end
end
end
context 'when upstream configuration is not valid' do
context 'when branch is not provided' do
context 'when upstream config is not a string' do
let(:config) { { pipeline: 123 } }
describe '#valid?' do
......@@ -46,9 +31,32 @@ describe EE::Gitlab::Ci::Config::Entry::Needs do
describe '#errors' do
it 'returns an error message' do
expect(subject.errors.first)
.to eq('needs pipeline should be a string')
.to eq('bridge needs pipeline should be a string')
end
end
end
end
context 'when needs is a complex needs' do
let(:config) { ['test', { pipeline: 'test' }] }
it 'test' do
subject
end
end
context 'when needs is empty' do
let(:config) { '' }
describe '#valid?' do
it { is_expected.not_to be_valid }
end
describe '#errors' do
it 'is returns an error about an empty config' do
expect(subject.errors.first)
.to end_with('has to be either an array of conditions or a hash')
end
end
end
end
......@@ -40,7 +40,7 @@ module Gitlab
environment: job[:environment_name],
coverage_regex: job[:coverage],
yaml_variables: yaml_variables(name),
needs_attributes: job[:needs]&.map { |need| { name: need } },
needs_attributes: job[:needs][:pipeline]&.map { |need| { name: need } },
interruptible: job[:interruptible],
rules: job[:rules],
options: {
......@@ -59,7 +59,7 @@ module Gitlab
instance: job[:instance],
start_in: job[:start_in],
trigger: job[:trigger],
bridge_needs: job[:needs]
bridge_needs: job[:needs][:bridge]
}.compact }.compact
end
......@@ -159,11 +159,11 @@ module Gitlab
end
def validate_job_needs!(name, job)
return unless job[:needs]
return unless job[:needs][:pipeline]
stage_index = @stages.index(job[:stage])
job[:needs].each do |need|
job[:needs][:pipeline].each do |need|
raise ValidationError, "#{name} job: undefined need: #{need}" unless @jobs[need.to_sym]
needs_stage_index = @stages.index(@jobs[need.to_sym][:stage])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment