diff options
-rw-r--r-- | app/models/ci/build.rb | 20 | ||||
-rw-r--r-- | doc/ci/yaml/README.md | 2 | ||||
-rw-r--r-- | spec/models/ci/build_spec.rb | 21 | ||||
-rw-r--r-- | spec/services/ci/register_job_service_spec.rb | 25 |
4 files changed, 61 insertions, 7 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 965ba35c8b0..9c44e9ef5fd 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -143,9 +143,7 @@ module Ci end before_transition any => [:running] do |build| - if build.specified_dependencies? && build.dependencies.empty? - raise MissingDependenciesError - end + build.validates_dependencies! end end @@ -486,8 +484,20 @@ module Ci options[:dependencies]&.empty? end - def specified_dependencies? - options.has_key?(:dependencies) && options[:dependencies].any? + def validates_dependencies! + dependencies.tap do |deps| + # When `dependencies` keyword is given and depended jobs are skipped by `only` keyword + if options[:dependencies]&.any? && deps.empty? + raise MissingDependenciesError + end + + # When artifacts of depended jobs have not existsed + deps.each do |dep| + if dep.options[:artifacts]&.any? && !dep.artifacts? + raise MissingDependenciesError + end + end + end end def hide_secrets(trace) diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index ef32e7658ee..f5391ff0768 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1107,7 +1107,7 @@ To use this feature, define `dependencies` in context of the job and pass a list of all previous jobs from which the artifacts should be downloaded. You can only define jobs from stages that are executed before the current one. An error will be shown if you define jobs from the current stage or next ones, -or there are no depended jobs in previous stages. +or there are no depended jobs with artifacts in previous stages. Defining an empty array will skip downloading any artifacts for that job. The status of the previous job is not considered when using `dependencies`, so if it failed or it is a manual job that was not run, no error occurs. diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index f8d8b1800b8..230546cf2da 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -1887,9 +1887,28 @@ describe Ci::Build do let(:options) { { dependencies: ['test'] } } context 'when a depended job exists' do - let!(:pre_build) { create(:ci_build, pipeline: pipeline, name: 'test', stage_idx: 0) } + let!(:pre_stage_job) { create(:ci_build, pipeline: pipeline, name: 'test', stage_idx: 0) } it { expect { build.run! }.not_to raise_error } + + context 'when "artifacts" keyword is specified on depended job' do + let!(:pre_stage_job) do + create(:ci_build, :artifacts, pipeline: pipeline, name: 'test', stage_idx: 0, + options: { artifacts: { paths: ['binaries/'] } } ) + end + + context 'when artifacts of depended job has existsed' do + it { expect { build.run! }.not_to raise_error } + end + + context 'when artifacts of depended job has not existsed' do + before do + pre_stage_job.erase_artifacts! + end + + it { expect { build.run! }.to raise_error(Ci::Build::MissingDependenciesError) } + end + end end context 'when depended jobs do not exist' do diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb index e779d02cc52..b5f88d6cdbe 100644 --- a/spec/services/ci/register_job_service_spec.rb +++ b/spec/services/ci/register_job_service_spec.rb @@ -291,6 +291,31 @@ module Ci it "picks the build" do expect(picked_job).to eq(pending_job) end + + context 'when "artifacts" keyword is specified on depended job' do + let!(:pre_stage_job) do + create(:ci_build, :success, :artifacts, pipeline: pipeline, name: job_name, stage_idx: 0, + options: { artifacts: { paths: ['binaries/'] } } ) + end + + context 'when artifacts of depended job has existsed' do + it "picks the build" do + expect(picked_job).to eq(pending_job) + end + end + + context 'when artifacts of depended job has not existsed' do + before do + pre_stage_job.erase_artifacts! + end + + it 'does not pick the build and drops the build' do + expect(picked_job).to be_nil + expect(pending_job.reload).to be_failed + expect(pending_job).to be_missing_dependency_failure + end + end + end end context 'when depended jobs do not exist' do |