diff --git a/CHANGELOG b/CHANGELOG index 5866330fe6..abdbcbea88 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ v 8.7.1 (unreleased) - Use the `can?` helper instead of `current_user.can?`. !3882 - Prevent users from deleting Webhooks via API they do not own - Fix Error 500 due to stale cache when projects are renamed or transferred + - Fix .gitlab-ci.yml parsing issue when hidde job is a template without script definition v 8.7.0 - Gitlab::GitAccess and Gitlab::GitAccessWiki are now instrumented diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index ff9887cba1..504d3df9d3 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -61,23 +61,21 @@ module Ci @stages = @config[:stages] || @config[:types] @variables = @config[:variables] || {} @cache = @config[:cache] - @config.except!(*ALLOWED_YAML_KEYS) - - # anything that doesn't have script is considered as unknown - @config.each do |name, param| - raise ValidationError, "Unknown parameter: #{name}" unless param.is_a?(Hash) && param.has_key?(:script) - end - - unless @config.values.any?{|job| job.is_a?(Hash)} - raise ValidationError, "Please define at least one job" - end - @jobs = {} - @config.each do |key, job| - next if key.to_s.start_with?('.') - stage = job[:stage] || job[:type] || DEFAULT_STAGE - @jobs[key] = { stage: stage }.merge(job) - end + + @config.except!(*ALLOWED_YAML_KEYS) + @config.each { |name, param| add_job(name, param) } + + raise ValidationError, "Please define at least one job" if @jobs.none? + end + + def add_job(name, job) + return if name.to_s.start_with?('.') + + raise ValidationError, "Unknown parameter: #{name}" unless job.is_a?(Hash) && job.has_key?(:script) + + stage = job[:stage] || job[:type] || DEFAULT_STAGE + @jobs[name] = { stage: stage }.merge(job) end def build_job(name, job) @@ -112,8 +110,6 @@ module Ci true end - private - def validate_global! unless validate_array_of_strings(@before_script) raise ValidationError, "before_script should be an array of strings" diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 643acf0303..c7ab318537 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -648,70 +648,131 @@ module Ci end describe "Hidden jobs" do - let(:config) do - YAML.dump({ - '.hidden_job' => { script: 'test' }, - 'normal_job' => { script: 'test' } - }) - end - let(:config_processor) { GitlabCiYamlProcessor.new(config) } - subject { config_processor.builds_for_stage_and_ref("test", "master") } - it "doesn't create jobs that starts with dot" do - expect(subject.size).to eq(1) - expect(subject.first).to eq({ - except: nil, - stage: "test", - stage_idx: 1, - name: :normal_job, - only: nil, - commands: "test", - tag_list: [], - options: {}, - when: "on_success", - allow_failure: false - }) + shared_examples 'hidden_job_handling' do + it "doesn't create jobs that start with dot" do + expect(subject.size).to eq(1) + expect(subject.first).to eq({ + except: nil, + stage: "test", + stage_idx: 1, + name: :normal_job, + only: nil, + commands: "test", + tag_list: [], + options: {}, + when: "on_success", + allow_failure: false + }) + end + end + + context 'when hidden job have a script definition' do + let(:config) do + YAML.dump({ + '.hidden_job' => { image: 'ruby:2.1', script: 'test' }, + 'normal_job' => { script: 'test' } + }) + end + + it_behaves_like 'hidden_job_handling' + end + + context "when hidden job doesn't have a script definition" do + let(:config) do + YAML.dump({ + '.hidden_job' => { image: 'ruby:2.1' }, + 'normal_job' => { script: 'test' } + }) + end + + it_behaves_like 'hidden_job_handling' end end describe "YAML Alias/Anchor" do - it "is correctly supported for jobs" do - config = <