diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index d226ebc3229e863bd0e2b86df4cae54379670804..ab77d4df8419f7dced1b50ccf76b9961e96512df 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -71,8 +71,6 @@ module Ci @ci_config.jobs.each do |name, param| add_job(name, param) end - - raise ValidationError, "Please define at least one job" if @jobs.none? end def add_job(name, job) diff --git a/lib/gitlab/ci/config/node/entry.rb b/lib/gitlab/ci/config/node/entry.rb index fa6569e8bb26faa6008c60fa4fa0cf7b7c88df08..033f9f0e3d1e13b49594e3c9c7dba14d3fa75c5b 100644 --- a/lib/gitlab/ci/config/node/entry.rb +++ b/lib/gitlab/ci/config/node/entry.rb @@ -24,6 +24,7 @@ module Gitlab compose! process_nodes! + @validator.validate(:processed) end def leaf? diff --git a/lib/gitlab/ci/config/node/jobs.rb b/lib/gitlab/ci/config/node/jobs.rb index a76b7a260c424c2a025ee1e6f0c981718aa4f6f7..e8e78e4088d5f4d3e68cfbe304ed68c1fa630b2e 100644 --- a/lib/gitlab/ci/config/node/jobs.rb +++ b/lib/gitlab/ci/config/node/jobs.rb @@ -10,12 +10,27 @@ module Gitlab validations do validates :config, type: Hash + validate :jobs_presence, on: :processed + + def jobs_presence + unless relevant? + errors.add(:config, 'should contain at least one visible job') + end + end end def nodes @config end + def relevant? + @nodes.values.any?(&:relevant?) + end + + def leaf? + false + end + private def create_node(key, essence) diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 49a786191b8dcd02946e486614cb2ec0323e4960..ac058ba159532854f0eaea480e93312e66e1a3a4 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -1061,7 +1061,14 @@ EOT config = YAML.dump({ before_script: ["bundle update"] }) expect do GitlabCiYamlProcessor.new(config, path) - end.to raise_error(GitlabCiYamlProcessor::ValidationError, "Please define at least one job") + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs config should contain at least one visible job") + end + + it "returns errors if there are no visible jobs defined" do + config = YAML.dump({ before_script: ["bundle update"], '.hidden'.to_sym => {} }) + expect do + GitlabCiYamlProcessor.new(config, path) + end.to raise_error(GitlabCiYamlProcessor::ValidationError, "jobs config should contain at least one visible job") end it "returns errors if job allow_failure parameter is not an boolean" do diff --git a/spec/lib/gitlab/ci/config/node/global_spec.rb b/spec/lib/gitlab/ci/config/node/global_spec.rb index 254cb28190ce4e34019390d1df1388f07fa68680..a98de73c06cb54a2de1480626e45479f117ba535 100644 --- a/spec/lib/gitlab/ci/config/node/global_spec.rb +++ b/spec/lib/gitlab/ci/config/node/global_spec.rb @@ -108,7 +108,10 @@ describe Gitlab::Ci::Config::Node::Global do end context 'when deprecated types key defined' do - let(:hash) { { types: ['test', 'deploy'] } } + let(:hash) do + { types: ['test', 'deploy'], + rspec: { script: 'rspec' } } + end it 'returns array of types as stages' do expect(global.stages).to eq %w[test deploy] @@ -174,7 +177,7 @@ describe Gitlab::Ci::Config::Node::Global do # details. # context 'when entires specified but not defined' do - let(:hash) { { variables: nil } } + let(:hash) { { variables: nil, rspec: { script: 'rspec' } } } before { global.process! } describe '#variables' do diff --git a/spec/lib/gitlab/ci/config/node/jobs_spec.rb b/spec/lib/gitlab/ci/config/node/jobs_spec.rb index b2d2a92d9e8df5f1fd2edf046268f2752a14dd28..7ec28b642b47869f54f67cf3aa864921c641cc6d 100644 --- a/spec/lib/gitlab/ci/config/node/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/node/jobs_spec.rb @@ -4,17 +4,9 @@ describe Gitlab::Ci::Config::Node::Jobs do let(:entry) { described_class.new(config) } describe 'validations' do - before { entry.process! } - context 'when entry config value is correct' do let(:config) { { rspec: { script: 'rspec' } } } - describe '#value' do - it 'returns key value' do - expect(entry.value).to eq(rspec: { script: 'rspec' }) - end - end - describe '#valid?' do it 'is valid' do expect(entry).to be_valid @@ -23,15 +15,34 @@ describe Gitlab::Ci::Config::Node::Jobs do end context 'when entry value is not correct' do - context 'incorrect config value type' do - let(:config) { ['incorrect'] } + describe '#errors' do + context 'incorrect config value type' do + let(:config) { ['incorrect'] } - describe '#errors' do - it 'saves errors' do + it 'returns error about incorrect type' do expect(entry.errors) .to include 'jobs config should be a hash' end end + + context 'when no visible jobs present' do + let(:config) { { '.hidden'.to_sym => {} } } + + context 'when not processed' do + it 'is valid' do + expect(entry.errors).to be_empty + end + end + + context 'when processed' do + before { entry.process! } + + it 'returns error about no visible jobs defined' do + expect(entry.errors) + .to include 'jobs config should contain at least one visible job' + end + end + end end end end @@ -45,6 +56,13 @@ describe Gitlab::Ci::Config::Node::Jobs do '.hidden'.to_sym => {} } end + describe '#value' do + it 'returns key value' do + expect(entry.value).to eq(rspec: { script: 'rspec' }, + spinach: { script: 'spinach' }) + end + end + describe '#descendants' do it 'creates valid descendant nodes' do expect(entry.descendants.count).to eq 3