Commit 479f4ccc authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch 'after-script' into 'master'

Implement after_script which allows to do cleanups as part of the build process

This implements `after_script` in global context.

The `after_script` will be executed always after the job, even if the job were canceled.

This requires changes on Runner side that will be implemented in 1.2.

cc @tmaczukin @grzesiek 


See merge request !3771
parents 51b777fa 0ce5cc99
......@@ -27,6 +27,7 @@ v 8.7.0 (unreleased)
- Make /profile/keys/new redirect to /profile/keys for back-compat. !3717
- Preserve time notes/comments have been updated at when moving issue
- Make HTTP(s) label consistent on clone bar (Stan Hu)
- Add support for `after_script`, requires Runner 1.2 (Kamil Trzciński)
- Expose label description in API (Mariusz Jachimowicz)
- API: Ability to update a group (Robert Schilling)
- API: Ability to move issues (Robert Schilling)
......
......@@ -15,6 +15,7 @@ If you want a quick introduction to GitLab CI, follow our
- [.gitlab-ci.yml](#gitlab-ci-yml)
- [image and services](#image-and-services)
- [before_script](#before_script)
- [after_script](#after_script)
- [stages](#stages)
- [types](#types)
- [variables](#variables)
......@@ -81,6 +82,9 @@ services:
before_script:
- bundle install
after_script:
- rm secrets
stages:
- build
- test
......@@ -105,6 +109,7 @@ There are a few reserved `keywords` that **cannot** be used as job names:
| stages | no | Define build stages |
| types | no | Alias for `stages` |
| before_script | no | Define commands that run before each job's script |
| after_script | no | Define commands that run after each job's script |
| variables | no | Define build variables |
| cache | no | Define list of files that should be cached between subsequent runs |
......@@ -119,6 +124,14 @@ used for time of the build. The configuration of this feature is covered in
`before_script` is used to define the command that should be run before all
builds, including deploy builds. This can be an array or a multi-line string.
### after_script
>**Note:**
Introduced in GitLab 8.7 and GitLab Runner v1.2.
`after_script` is used to define the command that will be run after for all
builds. This has to be an array or a multi-line string.
### stages
`stages` is used to define build stages that can be used by jobs.
......
......@@ -4,12 +4,12 @@ module Ci
DEFAULT_STAGES = %w(build test deploy)
DEFAULT_STAGE = 'test'
ALLOWED_YAML_KEYS = [:before_script, :image, :services, :types, :stages, :variables, :cache]
ALLOWED_YAML_KEYS = [:before_script, :after_script, :image, :services, :types, :stages, :variables, :cache]
ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services,
:allow_failure, :type, :stage, :when, :artifacts, :cache,
:dependencies, :variables]
attr_reader :before_script, :image, :services, :path, :cache
attr_reader :before_script, :after_script, :image, :services, :path, :cache
def initialize(config, path = nil)
@config = YAML.safe_load(config, [Symbol], [], true)
......@@ -55,6 +55,7 @@ module Ci
def initial_parsing
@before_script = @config[:before_script] || []
@after_script = @config[:after_script]
@image = @config[:image]
@services = @config[:services]
@stages = @config[:stages] || @config[:types]
......@@ -96,6 +97,7 @@ module Ci
artifacts: job[:artifacts],
cache: job[:cache] || @cache,
dependencies: job[:dependencies],
after_script: @after_script,
}.compact
}
end
......@@ -109,10 +111,26 @@ module Ci
end
def validate!
validate_global!
@jobs.each do |name, job|
validate_job!(name, job)
end
true
end
private
def validate_global!
unless validate_array_of_strings(@before_script)
raise ValidationError, "before_script should be an array of strings"
end
unless @after_script.nil? || validate_array_of_strings(@after_script)
raise ValidationError, "after_script should be an array of strings"
end
unless @image.nil? || @image.is_a?(String)
raise ValidationError, "image should be a string"
end
......@@ -129,25 +147,21 @@ module Ci
raise ValidationError, "variables should be a map of key-value strings"
end
if @cache
if @cache[:key] && !validate_string(@cache[:key])
raise ValidationError, "cache:key parameter should be a string"
end
if @cache[:untracked] && !validate_boolean(@cache[:untracked])
raise ValidationError, "cache:untracked parameter should be an boolean"
end
validate_global_cache! if @cache
end
if @cache[:paths] && !validate_array_of_strings(@cache[:paths])
raise ValidationError, "cache:paths parameter should be an array of strings"
end
def validate_global_cache!
if @cache[:key] && !validate_string(@cache[:key])
raise ValidationError, "cache:key parameter should be a string"
end
@jobs.each do |name, job|
validate_job!(name, job)
if @cache[:untracked] && !validate_boolean(@cache[:untracked])
raise ValidationError, "cache:untracked parameter should be an boolean"
end
true
if @cache[:paths] && !validate_array_of_strings(@cache[:paths])
raise ValidationError, "cache:paths parameter should be an array of strings"
end
end
def validate_job!(name, job)
......@@ -162,8 +176,6 @@ module Ci
validate_job_dependencies!(name, job) if job[:dependencies]
end
private
def validate_job_name!(name)
if name.blank? || !validate_string(name)
raise ValidationError, "job name should be non-empty string"
......
......@@ -286,6 +286,28 @@ module Ci
end
end
describe "Scripts handling" do
let(:config_data) { YAML.dump(config) }
let(:config_processor) { GitlabCiYamlProcessor.new(config_data, path) }
subject { config_processor.builds_for_stage_and_ref("test", "master").first }
describe "after_script" do
context "in global context" do
let(:config) do
{
after_script: ["after_script"],
test: { script: ["script"] }
}
end
it "return after_script in options" do
expect(subject[:options][:after_script]).to eq(["after_script"])
end
end
end
end
describe "Image and service handling" do
it "returns image and service when defined" do
......@@ -663,6 +685,13 @@ EOT
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "before_script should be an array of strings")
end
it "returns errors if after_script parameter is invalid" do
config = YAML.dump({ after_script: "bundle update", rspec: { script: "test" } })
expect do
GitlabCiYamlProcessor.new(config, path)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "after_script should be an array of strings")
end
it "returns errors if image parameter is invalid" do
config = YAML.dump({ image: ["test"], rspec: { script: "test" } })
expect do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment