summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--doc/ci/yaml/README.md55
-rw-r--r--lib/ci/gitlab_ci_yaml_processor.rb21
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb45
4 files changed, 121 insertions, 1 deletions
diff --git a/CHANGELOG b/CHANGELOG
index c171d662b8d..fa634cc20db 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@ v 8.6.0 (unreleased)
- Add support for cross-project label references
- Update documentation to reflect Guest role not being enforced on internal projects
- Allow search for logged out users
+ - Allow to define on which builds the current one depends on
- Fix bug where Bitbucket `closed` issues were imported as `opened` (Iuri de Silvio)
- Don't show Issues/MRs from archived projects in Groups view
- Increase the notes polling timeout over time (Roberto Dip)
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 9a1f86cec45..fb62ed25d64 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -241,6 +241,7 @@ job_name:
| tags | no | Defines a list of tags which are used to select runner |
| allow_failure | no | Allow build to fail. Failed build doesn't contribute to commit status |
| when | no | Define when to run build. Can be `on_success`, `on_failure` or `always` |
+| dependencies | no | Define a builds that this build depends on |
| artifacts | no | Define list build artifacts |
| cache | no | Define list of files that should be cached between subsequent runs |
@@ -514,6 +515,60 @@ job:
untracked: true
```
+### dependencies
+
+_**Note:** Introduced in GitLab 8.6 and GitLab Runner v1.1.1._
+
+This feature should be used with `artifacts` and allows to define artifacts passing between different builds.
+
+`artifacts` from previous stages are passed by default.
+
+To use a feature define `dependencies` in context of the build and pass
+a list of all previous builds from which the artifacts should be downloaded.
+You can only define a builds from stages that are executed before this one.
+Error will be shown if you define builds from current stage or next stages.
+
+How to use artifacts passing between stages:
+
+```
+build:osx:
+ stage: build
+ script: ...
+ artifacts:
+ paths:
+ - binaries/
+
+build:linux:
+ stage: build
+ script: ...
+ artifacts:
+ paths:
+ - binaries/
+
+test:osx:
+ stage: test
+ script: ...
+ dependencies:
+ - build:osx
+
+test:linux:
+ stage: test
+ script: ...
+ dependencies:
+ - build:linux
+
+deploy:
+ stage: deploy
+ script: ...
+```
+
+The above will create a build artifacts for two jobs: `build:osx` and `build:linux`.
+When executing the `test:osx` the artifacts for `build:osx` will be downloaded and extracted in context of the build.
+The same happens for `test:linux` and artifacts from `build:linux`.
+
+The job `deploy` will download artifacts from all previous builds.
+However, only the `build:osx` and `build:linux` exports artifacts so only these will be downloaded.
+
### cache
_**Note:** Introduced in GitLab Runner v0.7.0._
diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb
index ce3d0138268..04b58cf1cd3 100644
--- a/lib/ci/gitlab_ci_yaml_processor.rb
+++ b/lib/ci/gitlab_ci_yaml_processor.rb
@@ -5,7 +5,9 @@ module Ci
DEFAULT_STAGES = %w(build test deploy)
DEFAULT_STAGE = 'test'
ALLOWED_YAML_KEYS = [:before_script, :image, :services, :types, :stages, :variables, :cache]
- ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, :allow_failure, :type, :stage, :when, :artifacts, :cache]
+ ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services,
+ :allow_failure, :type, :stage, :when, :artifacts, :cache,
+ :dependencies]
attr_reader :before_script, :image, :services, :variables, :path, :cache
@@ -145,6 +147,7 @@ module Ci
validate_job_stage!(name, job) if job[:stage]
validate_job_cache!(name, job) if job[:cache]
validate_job_artifacts!(name, job) if job[:artifacts]
+ validate_job_dependencies!(name, job) if job[:dependencies]
end
private
@@ -231,6 +234,22 @@ module Ci
end
end
+ def validate_job_dependencies!(name, job)
+ if !validate_array_of_strings(job[:dependencies])
+ raise ValidationError, "#{name} job: dependencies parameter should be an array of strings"
+ end
+
+ stage_index = stages.index(job[:stage])
+
+ job[:dependencies].each do |dependency|
+ raise ValidationError, "#{name} job: undefined dependency: #{dependency}" unless @jobs[dependency]
+
+ unless stages.index(@jobs[dependency][:stage]) < stage_index
+ raise ValidationError, "#{name} job: dependency #{dependency} is not defined in prior stages"
+ end
+ end
+ end
+
def validate_array_of_strings(values)
values.is_a?(Array) && values.all? { |value| validate_string(value) }
end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index 44d2b9eb1f7..fe5096989b2 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -428,6 +428,44 @@ module Ci
end
end
+ describe "Dependencies" do
+ let(:config) do
+ {
+ build1: { stage: 'build', script: 'test' },
+ build2: { stage: 'build', script: 'test' },
+ test1: { stage: 'test', script: 'test', dependencies: dependencies },
+ test2: { stage: 'test', script: 'test' },
+ deploy: { stage: 'test', script: 'test' }
+ }
+ end
+
+ subject { GitlabCiYamlProcessor.new(YAML.dump(config)) }
+
+ context 'no dependencies' do
+ let(:dependencies) { }
+
+ it { expect { subject }.to_not raise_error }
+ end
+
+ context 'dependencies to builds' do
+ let(:dependencies) { [:build1, :build2] }
+
+ it { expect { subject }.to_not raise_error }
+ end
+
+ context 'undefined dependency' do
+ let(:dependencies) { [:undefined] }
+
+ it { expect { subject }.to raise_error(GitlabCiYamlProcessor::ValidationError, 'test1 job: undefined dependency: undefined') }
+ end
+
+ context 'dependencies to deploy' do
+ let(:dependencies) { [:deploy] }
+
+ it { expect { subject }.to raise_error(GitlabCiYamlProcessor::ValidationError, 'test1 job: dependency deploy is not defined in prior stages') }
+ end
+ end
+
describe "Hidden jobs" do
let(:config) do
YAML.dump({
@@ -682,6 +720,13 @@ module Ci
GitlabCiYamlProcessor.new(config)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:paths parameter should be an array of strings")
end
+
+ it "returns errors if job dependencies is not an array of strings" do
+ config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", dependencies: "string" } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: dependencies parameter should be an array of strings")
+ end
end
end
end