summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2017-09-05 22:37:28 +0900
committerShinya Maeda <shinya@gitlab.com>2017-12-06 15:53:59 +0900
commitc3e0731d2efc777018b668d9e0b7f8aa2377d9fc (patch)
treefcfbec6c06c4a4052716120f58dd140363339ae0
parent6e343b27bfb993b2c19dd4b4fd8d2b48747fbac3 (diff)
downloadgitlab-ce-c3e0731d2efc777018b668d9e0b7f8aa2377d9fc.tar.gz
Add case when artifacts have not existed on dependencies
-rw-r--r--app/models/ci/build.rb20
-rw-r--r--doc/ci/yaml/README.md2
-rw-r--r--spec/models/ci/build_spec.rb21
-rw-r--r--spec/services/ci/register_job_service_spec.rb25
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