Allow to define cache in .gitlab-ci.yml
This commit is contained in:
parent
d70f1f35b1
commit
58074ab7da
4 changed files with 175 additions and 4 deletions
|
@ -18,6 +18,7 @@ v 8.2.0 (unreleased)
|
||||||
- Show merge request CI status on merge requests index page
|
- Show merge request CI status on merge requests index page
|
||||||
- Extend yml syntax for only and except to support specifying repository path
|
- Extend yml syntax for only and except to support specifying repository path
|
||||||
- Enable shared runners to all new projects
|
- Enable shared runners to all new projects
|
||||||
|
- Allow to define cache in `.gitlab-ci.yml`
|
||||||
- Fix: 500 error returned if destroy request without HTTP referer (Kazuki Shimizu)
|
- Fix: 500 error returned if destroy request without HTTP referer (Kazuki Shimizu)
|
||||||
- Remove deprecated CI events from project settings page
|
- Remove deprecated CI events from project settings page
|
||||||
- [API] Add ability to fetch the commit ID of the last commit that actually touched a file
|
- [API] Add ability to fetch the commit ID of the last commit that actually touched a file
|
||||||
|
|
|
@ -56,6 +56,7 @@ There are a few `keywords` that can't be used as job names:
|
||||||
| types | optional | Alias for `stages` |
|
| types | optional | Alias for `stages` |
|
||||||
| before_script | optional | Define commands prepended for each job's script |
|
| before_script | optional | Define commands prepended for each job's script |
|
||||||
| variables | optional | Define build variables |
|
| variables | optional | Define build variables |
|
||||||
|
| cache | optional | Define list of files that should be cached between subsequent runs |
|
||||||
|
|
||||||
### image and services
|
### image and services
|
||||||
This allows to specify a custom Docker image and a list of services that can be used for time of the build.
|
This allows to specify a custom Docker image and a list of services that can be used for time of the build.
|
||||||
|
@ -110,6 +111,19 @@ These variables can be later used in all executed commands and scripts.
|
||||||
|
|
||||||
The YAML-defined variables are also set to all created service containers, thus allowing to fine tune them.
|
The YAML-defined variables are also set to all created service containers, thus allowing to fine tune them.
|
||||||
|
|
||||||
|
### cache
|
||||||
|
`cache` is used to specify list of files and directories which should be cached between builds.
|
||||||
|
|
||||||
|
**The global setting allows to specify default cached files for all jobs.**
|
||||||
|
|
||||||
|
To cache all git untracked files and files in `binaries`:
|
||||||
|
```
|
||||||
|
cache:
|
||||||
|
untracked: true
|
||||||
|
paths:
|
||||||
|
- binaries/
|
||||||
|
```
|
||||||
|
|
||||||
## Jobs
|
## Jobs
|
||||||
`.gitlab-ci.yml` allows you to specify an unlimited number of jobs.
|
`.gitlab-ci.yml` allows you to specify an unlimited number of jobs.
|
||||||
Each job has to have a unique `job_name`, which is not one of the keywords mentioned above.
|
Each job has to have a unique `job_name`, which is not one of the keywords mentioned above.
|
||||||
|
@ -142,6 +156,7 @@ job_name:
|
||||||
| allow_failure | optional | Allow build to fail. Failed build doesn't contribute to commit status |
|
| allow_failure | optional | Allow build to fail. Failed build doesn't contribute to commit status |
|
||||||
| when | optional | Define when to run build. Can be `on_success`, `on_failure` or `always` |
|
| when | optional | Define when to run build. Can be `on_success`, `on_failure` or `always` |
|
||||||
| artifacts | optional | Define list build artifacts |
|
| artifacts | optional | Define list build artifacts |
|
||||||
|
| cache | optional | Define list of files that should be cached between subsequent runs |
|
||||||
|
|
||||||
### script
|
### script
|
||||||
`script` is a shell script which is executed by runner. The shell script is prepended with `before_script`.
|
`script` is a shell script which is executed by runner. The shell script is prepended with `before_script`.
|
||||||
|
@ -288,6 +303,57 @@ The artifacts will be send after the build success to GitLab and will be accessi
|
||||||
|
|
||||||
This feature requires GitLab Runner v0.7.0 or higher.
|
This feature requires GitLab Runner v0.7.0 or higher.
|
||||||
|
|
||||||
|
### cache
|
||||||
|
`cache` is used to specify list of files and directories which should be cached between builds.
|
||||||
|
|
||||||
|
1. Cache all files in `binaries` and `.config`:
|
||||||
|
```
|
||||||
|
rspec:
|
||||||
|
script: test
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- binaries/
|
||||||
|
- .config
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Cache all git untracked files:
|
||||||
|
```
|
||||||
|
rspec:
|
||||||
|
script: test
|
||||||
|
cache:
|
||||||
|
untracked: true
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Cache all git untracked files and files in `binaries`:
|
||||||
|
```
|
||||||
|
rspec:
|
||||||
|
script: test
|
||||||
|
cache:
|
||||||
|
untracked: true
|
||||||
|
paths:
|
||||||
|
- binaries/
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Locally defined cache overwrites globally defined options. This will cache only `binaries/`:
|
||||||
|
|
||||||
|
```
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- my/files
|
||||||
|
|
||||||
|
rspec:
|
||||||
|
script: test
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- binaries/
|
||||||
|
```
|
||||||
|
|
||||||
|
The cache is provided on best effort basis, so don't expect that cache will be present.
|
||||||
|
For implementation details please check GitLab Runner.
|
||||||
|
|
||||||
|
This feature requires GitLab Runner v0.7.0 or higher.
|
||||||
|
|
||||||
|
|
||||||
## Validate the .gitlab-ci.yml
|
## Validate the .gitlab-ci.yml
|
||||||
Each instance of GitLab CI has an embedded debug tool called Lint.
|
Each instance of GitLab CI has an embedded debug tool called Lint.
|
||||||
You can find the link to the Lint in the project's settings page or use short url `/lint`.
|
You can find the link to the Lint in the project's settings page or use short url `/lint`.
|
||||||
|
|
|
@ -4,10 +4,10 @@ module Ci
|
||||||
|
|
||||||
DEFAULT_STAGES = %w(build test deploy)
|
DEFAULT_STAGES = %w(build test deploy)
|
||||||
DEFAULT_STAGE = 'test'
|
DEFAULT_STAGE = 'test'
|
||||||
ALLOWED_YAML_KEYS = [:before_script, :image, :services, :types, :stages, :variables]
|
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]
|
ALLOWED_JOB_KEYS = [:tags, :script, :only, :except, :type, :image, :services, :allow_failure, :type, :stage, :when, :artifacts, :cache]
|
||||||
|
|
||||||
attr_reader :before_script, :image, :services, :variables, :path
|
attr_reader :before_script, :image, :services, :variables, :path, :cache
|
||||||
|
|
||||||
def initialize(config, path = nil)
|
def initialize(config, path = nil)
|
||||||
@config = YAML.load(config)
|
@config = YAML.load(config)
|
||||||
|
@ -46,6 +46,7 @@ module Ci
|
||||||
@services = @config[:services]
|
@services = @config[:services]
|
||||||
@stages = @config[:stages] || @config[:types]
|
@stages = @config[:stages] || @config[:types]
|
||||||
@variables = @config[:variables] || {}
|
@variables = @config[:variables] || {}
|
||||||
|
@cache = @config[:cache]
|
||||||
@config.except!(*ALLOWED_YAML_KEYS)
|
@config.except!(*ALLOWED_YAML_KEYS)
|
||||||
|
|
||||||
# anything that doesn't have script is considered as unknown
|
# anything that doesn't have script is considered as unknown
|
||||||
|
@ -78,7 +79,8 @@ module Ci
|
||||||
options: {
|
options: {
|
||||||
image: job[:image] || @image,
|
image: job[:image] || @image,
|
||||||
services: job[:services] || @services,
|
services: job[:services] || @services,
|
||||||
artifacts: job[:artifacts]
|
artifacts: job[:artifacts],
|
||||||
|
cache: job[:cache] || @cache,
|
||||||
}.compact
|
}.compact
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -112,6 +114,16 @@ module Ci
|
||||||
raise ValidationError, "variables should be a map of key-valued strings"
|
raise ValidationError, "variables should be a map of key-valued strings"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if @cache
|
||||||
|
if @cache[:untracked] && !validate_boolean(@cache[:untracked])
|
||||||
|
raise ValidationError, "cache:untracked parameter should be an boolean"
|
||||||
|
end
|
||||||
|
|
||||||
|
if @cache[:paths] && !validate_array_of_strings(@cache[:paths])
|
||||||
|
raise ValidationError, "cache:paths parameter should be an array of strings"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@jobs.each do |name, job|
|
@jobs.each do |name, job|
|
||||||
validate_job!(name, job)
|
validate_job!(name, job)
|
||||||
end
|
end
|
||||||
|
@ -160,6 +172,16 @@ module Ci
|
||||||
raise ValidationError, "#{name} job: except parameter should be an array of strings"
|
raise ValidationError, "#{name} job: except parameter should be an array of strings"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if job[:cache]
|
||||||
|
if job[:cache][:untracked] && !validate_boolean(job[:cache][:untracked])
|
||||||
|
raise ValidationError, "#{name} job: cache:untracked parameter should be an boolean"
|
||||||
|
end
|
||||||
|
|
||||||
|
if job[:cache][:paths] && !validate_array_of_strings(job[:cache][:paths])
|
||||||
|
raise ValidationError, "#{name} job: cache:paths parameter should be an array of strings"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if job[:artifacts]
|
if job[:artifacts]
|
||||||
if job[:artifacts][:untracked] && !validate_boolean(job[:artifacts][:untracked])
|
if job[:artifacts][:untracked] && !validate_boolean(job[:artifacts][:untracked])
|
||||||
raise ValidationError, "#{name} job: artifacts:untracked parameter should be an boolean"
|
raise ValidationError, "#{name} job: artifacts:untracked parameter should be an boolean"
|
||||||
|
|
|
@ -333,6 +333,60 @@ module Ci
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Caches" do
|
||||||
|
it "returns cache when defined globally" do
|
||||||
|
config = YAML.dump({
|
||||||
|
cache: { paths: ["logs/", "binaries/"], untracked: true },
|
||||||
|
rspec: {
|
||||||
|
script: "rspec"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
config_processor = GitlabCiYamlProcessor.new(config)
|
||||||
|
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
|
||||||
|
paths: ["logs/", "binaries/"],
|
||||||
|
untracked: true,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns cache when defined in a job" do
|
||||||
|
config = YAML.dump({
|
||||||
|
rspec: {
|
||||||
|
cache: { paths: ["logs/", "binaries/"], untracked: true },
|
||||||
|
script: "rspec"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
config_processor = GitlabCiYamlProcessor.new(config)
|
||||||
|
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
|
||||||
|
paths: ["logs/", "binaries/"],
|
||||||
|
untracked: true,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "overwrite cache when defined for a job and globally" do
|
||||||
|
config = YAML.dump({
|
||||||
|
cache: { paths: ["logs/", "binaries/"], untracked: true },
|
||||||
|
rspec: {
|
||||||
|
script: "rspec",
|
||||||
|
cache: { paths: ["test/"], untracked: false },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
config_processor = GitlabCiYamlProcessor.new(config)
|
||||||
|
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
|
||||||
|
expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
|
||||||
|
paths: ["test/"],
|
||||||
|
untracked: false,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Artifacts" do
|
describe "Artifacts" do
|
||||||
it "returns artifacts when defined" do
|
it "returns artifacts when defined" do
|
||||||
config = YAML.dump({
|
config = YAML.dump({
|
||||||
|
@ -542,6 +596,34 @@ module Ci
|
||||||
GitlabCiYamlProcessor.new(config)
|
GitlabCiYamlProcessor.new(config)
|
||||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: artifacts:paths parameter should be an array of strings")
|
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: artifacts:paths parameter should be an array of strings")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns errors if cache:untracked is not an array of strings" do
|
||||||
|
config = YAML.dump({ cache: { untracked: "string" }, rspec: { script: "test" } })
|
||||||
|
expect do
|
||||||
|
GitlabCiYamlProcessor.new(config)
|
||||||
|
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:untracked parameter should be an boolean")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns errors if cache:paths is not an array of strings" do
|
||||||
|
config = YAML.dump({ cache: { paths: "string" }, rspec: { script: "test" } })
|
||||||
|
expect do
|
||||||
|
GitlabCiYamlProcessor.new(config)
|
||||||
|
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:paths parameter should be an array of strings")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns errors if job cache:untracked is not an array of strings" do
|
||||||
|
config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { untracked: "string" } } })
|
||||||
|
expect do
|
||||||
|
GitlabCiYamlProcessor.new(config)
|
||||||
|
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:untracked parameter should be an boolean")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns errors if job cache:paths is not an array of strings" do
|
||||||
|
config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { paths: "string" } } })
|
||||||
|
expect do
|
||||||
|
GitlabCiYamlProcessor.new(config)
|
||||||
|
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:paths parameter should be an array of strings")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue