diff --git a/lib/gitlab/ci/config/node/job.rb b/lib/gitlab/ci/config/node/job.rb index 3e6666d751f69ad90f550f5acc70cac944a30965..745f03ae4d5bb06569f118c5d01cdb4d6c0cdf6b 100644 --- a/lib/gitlab/ci/config/node/job.rb +++ b/lib/gitlab/ci/config/node/job.rb @@ -90,6 +90,8 @@ module Gitlab @entries.delete(:type) end + + inherit!(deps) end def name @@ -102,6 +104,19 @@ module Gitlab private + def inherit!(deps) + return unless deps + + self.class.nodes.each_key do |key| + global_entry = deps[key] + job_entry = @entries[key] + + if global_entry.specified? && !job_entry.specified? + @entries[key] = global_entry + end + end + end + def to_hash { name: name, before_script: before_script, diff --git a/spec/lib/gitlab/ci/config/node/global_spec.rb b/spec/lib/gitlab/ci/config/node/global_spec.rb index 4ff2320f1bfd74beaecfdacdf21c0ee43279dbc2..951f5f956d80975e63c872cefa0e7bd46b79b6af 100644 --- a/spec/lib/gitlab/ci/config/node/global_spec.rb +++ b/spec/lib/gitlab/ci/config/node/global_spec.rb @@ -14,7 +14,7 @@ describe Gitlab::Ci::Config::Node::Global do end context 'when hash is valid' do - context 'when all entries defined' do + context 'when some entries defined' do let(:hash) do { before_script: ['ls', 'pwd'], image: 'ruby:2.2', @@ -24,7 +24,7 @@ describe Gitlab::Ci::Config::Node::Global do stages: ['build', 'pages'], cache: { key: 'k', untracked: true, paths: ['public/'] }, rspec: { script: %w[rspec ls] }, - spinach: { script: 'spinach' } } + spinach: { before_script: [], variables: {}, script: 'spinach' } } end describe '#compose!' do @@ -76,6 +76,12 @@ describe Gitlab::Ci::Config::Node::Global do context 'when composed' do before { global.compose! } + describe '#errors' do + it 'has no errors' do + expect(global.errors).to be_empty + end + end + describe '#before_script' do it 'returns correct script' do expect(global.before_script).to eq ['ls', 'pwd'] @@ -135,12 +141,24 @@ describe Gitlab::Ci::Config::Node::Global do describe '#jobs' do it 'returns jobs configuration' do expect(global.jobs).to eq( - rspec: { name: :rspec, - script: %w[rspec ls], - stage: 'test' }, + rspec: { script: %w[rspec ls], + name: :rspec, + before_script: ['ls', 'pwd'], + image: 'ruby:2.2', + services: ['postgres:9.1', 'mysql:5.5'], + stage: 'test', + cache: { key: 'k', untracked: true, paths: ['public/'] }, + variables: { VAR: 'value' }, + after_script: ['make clean'] }, spinach: { name: :spinach, script: %w[spinach], - stage: 'test' } + before_script: [], + image: 'ruby:2.2', + services: ['postgres:9.1', 'mysql:5.5'], + stage: 'test', + cache: { key: 'k', untracked: true, paths: ['public/'] }, + variables: {}, + after_script: ['make clean'] }, ) end end diff --git a/spec/lib/gitlab/ci/config/node/job_spec.rb b/spec/lib/gitlab/ci/config/node/job_spec.rb index 74aa616720e8fa570705c728d4624c51fa69056d..f34a3786a0d4e2752c58b9c9e5c573f07aae0222 100644 --- a/spec/lib/gitlab/ci/config/node/job_spec.rb +++ b/spec/lib/gitlab/ci/config/node/job_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Gitlab::Ci::Config::Node::Job do let(:entry) { described_class.new(config, name: :rspec) } - before { entry.compose! } - describe 'validations' do + before { entry.compose! } + context 'when entry config value is correct' do let(:config) { { script: 'rspec' } } @@ -60,6 +60,8 @@ describe Gitlab::Ci::Config::Node::Job do end describe '#value' do + before { entry.compose! } + context 'when entry is correct' do let(:config) do { before_script: %w[ls pwd], @@ -83,4 +85,41 @@ describe Gitlab::Ci::Config::Node::Job do expect(entry).to be_relevant end end + + describe '#compose!' do + let(:unspecified) { double('unspecified', 'specified?' => false) } + + let(:specified) do + double('specified', 'specified?' => true, value: 'specified') + end + + let(:deps) { spy('deps', '[]' => unspecified) } + + context 'when job config overrides global config' do + before { entry.compose!(deps) } + + let(:config) do + { image: 'some_image', cache: { key: 'test' } } + end + + it 'overrides global config' do + expect(entry[:image].value).to eq 'some_image' + expect(entry[:cache].value).to eq(key: 'test') + end + end + + context 'when job config does not override global config' do + before do + allow(deps).to receive('[]').with(:image).and_return(specified) + entry.compose!(deps) + end + + let(:config) { { script: 'ls', cache: { key: 'test' } } } + + it 'uses config from global entry' do + expect(entry[:image].value).to eq 'specified' + expect(entry[:cache].value).to eq(key: 'test') + end + end + end end