Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
bb6ef418
Commit
bb6ef418
authored
Mar 04, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
074b1e06
4b0036b8
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
379 additions
and
51 deletions
+379
-51
changelogs/unreleased/allow-to-recursively-include.yml
changelogs/unreleased/allow-to-recursively-include.yml
+5
-0
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+66
-5
lib/gitlab/ci/config.rb
lib/gitlab/ci/config.rb
+2
-1
lib/gitlab/ci/config/external/file/base.rb
lib/gitlab/ci/config/external/file/base.rb
+26
-4
lib/gitlab/ci/config/external/file/local.rb
lib/gitlab/ci/config/external/file/local.rb
+7
-0
lib/gitlab/ci/config/external/file/project.rb
lib/gitlab/ci/config/external/file/project.rb
+7
-0
lib/gitlab/ci/config/external/mapper.rb
lib/gitlab/ci/config/external/mapper.rb
+32
-4
lib/gitlab/ci/config/external/processor.rb
lib/gitlab/ci/config/external/processor.rb
+3
-3
spec/lib/gitlab/ci/config/external/file/base_spec.rb
spec/lib/gitlab/ci/config/external/file/base_spec.rb
+17
-1
spec/lib/gitlab/ci/config/external/file/local_spec.rb
spec/lib/gitlab/ci/config/external/file/local_spec.rb
+35
-1
spec/lib/gitlab/ci/config/external/file/project_spec.rb
spec/lib/gitlab/ci/config/external/file/project_spec.rb
+29
-18
spec/lib/gitlab/ci/config/external/file/remote_spec.rb
spec/lib/gitlab/ci/config/external/file/remote_spec.rb
+11
-1
spec/lib/gitlab/ci/config/external/file/template_spec.rb
spec/lib/gitlab/ci/config/external/file/template_spec.rb
+24
-11
spec/lib/gitlab/ci/config/external/mapper_spec.rb
spec/lib/gitlab/ci/config/external/mapper_spec.rb
+34
-1
spec/lib/gitlab/ci/config/external/processor_spec.rb
spec/lib/gitlab/ci/config/external/processor_spec.rb
+81
-1
No files found.
changelogs/unreleased/allow-to-recursively-include.yml
0 → 100644
View file @
bb6ef418
---
title
:
Allow to recursively expand includes
merge_request
:
24356
author
:
type
:
added
doc/ci/yaml/README.md
View file @
bb6ef418
...
@@ -1638,6 +1638,9 @@ You can only use files that are currently tracked by Git on the same branch
...
@@ -1638,6 +1638,9 @@ You can only use files that are currently tracked by Git on the same branch
your configuration file is on. In other words, when using a
`include:local`
, make
your configuration file is on. In other words, when using a
`include:local`
, make
sure that both
`.gitlab-ci.yml`
and the local file are on the same branch.
sure that both
`.gitlab-ci.yml`
and the local file are on the same branch.
All
[
nested includes
](
#nested-includes
)
will be executed in the scope of the same project,
so it is possible to use local, project, remote or template includes.
NOTE:
**Note:**
NOTE:
**Note:**
Including local files through Git submodules paths is not supported.
Including local files through Git submodules paths is not supported.
...
@@ -1650,7 +1653,7 @@ include:
...
@@ -1650,7 +1653,7 @@ include:
### `include:file`
### `include:file`
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53903) in GitLab 11.
7
.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53903) in GitLab 11.
9
.
To include files from another private project under the same GitLab instance,
To include files from another private project under the same GitLab instance,
use
`include:file`
. This file is referenced using full paths relative to the
use
`include:file`
. This file is referenced using full paths relative to the
...
@@ -1679,6 +1682,10 @@ include:
...
@@ -1679,6 +1682,10 @@ include:
file
:
'
/templates/.gitlab-ci-template.yml'
file
:
'
/templates/.gitlab-ci-template.yml'
```
```
All nested includes will be executed in the scope of the target project,
so it is possible to used local (relative to target project), project, remote
or template includes.
### `include:template`
### `include:template`
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53445) in GitLab 11.7.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53445) in GitLab 11.7.
...
@@ -1694,6 +1701,9 @@ include:
...
@@ -1694,6 +1701,9 @@ include:
-
template
:
Auto-DevOps.gitlab-ci.yml
-
template
:
Auto-DevOps.gitlab-ci.yml
```
```
All nested includes will be executed only with the permission of the user,
so it is possible to use project, remote or template includes.
### `include:remote`
### `include:remote`
`include:remote`
can be used to include a file from a different location,
`include:remote`
can be used to include a file from a different location,
...
@@ -1706,10 +1716,16 @@ include:
...
@@ -1706,10 +1716,16 @@ include:
-
remote
:
'
https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'
-
remote
:
'
https://gitlab.com/awesome-project/raw/master/.gitlab-ci-template.yml'
```
```
NOTE:
**Note for GitLab admins:**
All nested includes will be executed without context as public user, so only another remote,
In order to include files from another repository inside your local network,
or public project, or template is allowed.
you may need to enable the
**Allow requests to the local network from hooks and services**
checkbox
located in the
**Admin area > Settings > Network > Outbound requests**
section.
### Nested includes
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/53903) in GitLab 11.7.
Nested includes allow you to compose a set of includes.
A total of 50 includes is allowed.
Duplicate includes are considered a configuration error.
### `include` examples
### `include` examples
...
@@ -1878,6 +1894,51 @@ In this case, if `install_dependencies` and `deploy` were not repeated in
...
@@ -1878,6 +1894,51 @@ In this case, if `install_dependencies` and `deploy` were not repeated in
`.gitlab-ci.yml`
, they would not be part of the script for the
`production`
`.gitlab-ci.yml`
, they would not be part of the script for the
`production`
job in the combined CI configuration.
job in the combined CI configuration.
#### Using nested includes
The examples below show how includes can be nested from different sources
using a combination of different methods.
In this example,
`.gitlab-ci.yml`
includes local the file
`/.gitlab-ci/another-config.yml`
:
```
yaml
includes
:
-
local
:
/.gitlab-ci/another-config.yml
```
The
`/.gitlab-ci/another-config.yml`
includes a template and the
`/templates/docker-workflow.yml`
file
from another project:
```
yaml
includes
:
-
template
:
Bash.gitlab-ci.yml
-
project
:
/group/my-project
file
:
/templates/docker-workflow.yml
```
The
`/templates/docker-workflow.yml`
present in
`/group/my-project`
includes two local files
of the
`/group/my-project`
:
```
yaml
includes
:
-
local
:
:
/templates/docker-build.yml
-
local
:
:
/templates/docker-testing.yml
```
Our
`/templates/docker-build.yml`
present in
`/group/my-project`
adds a
`docker-build`
job:
```
yaml
docker-build
:
script
:
docker build -t my-image .
```
Our second
`/templates/docker-test.yml`
present in
`/group/my-project`
adds a
`docker-test`
job:
```
yaml
docker-test
:
script
:
docker run my-image /run/tests.sh
```
## `extends`
## `extends`
> Introduced in GitLab 11.3.
> Introduced in GitLab 11.3.
...
...
lib/gitlab/ci/config.rb
View file @
bb6ef418
...
@@ -84,7 +84,8 @@ module Gitlab
...
@@ -84,7 +84,8 @@ module Gitlab
Config
::
External
::
Processor
.
new
(
config
,
Config
::
External
::
Processor
.
new
(
config
,
project:
project
,
project:
project
,
sha:
sha
||
project
.
repository
.
root_ref_sha
,
sha:
sha
||
project
.
repository
.
root_ref_sha
,
user:
user
).
perform
user:
user
,
expandset:
Set
.
new
).
perform
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/external/file/base.rb
View file @
bb6ef418
...
@@ -12,7 +12,7 @@ module Gitlab
...
@@ -12,7 +12,7 @@ module Gitlab
YAML_WHITELIST_EXTENSION
=
/.+\.(yml|yaml)$/i
.
freeze
YAML_WHITELIST_EXTENSION
=
/.+\.(yml|yaml)$/i
.
freeze
Context
=
Struct
.
new
(
:project
,
:sha
,
:user
)
Context
=
Struct
.
new
(
:project
,
:sha
,
:user
,
:expandset
)
def
initialize
(
params
,
context
)
def
initialize
(
params
,
context
)
@params
=
params
@params
=
params
...
@@ -43,13 +43,27 @@ module Gitlab
...
@@ -43,13 +43,27 @@ module Gitlab
end
end
def
to_hash
def
to_hash
@hash
||=
Gitlab
::
Config
::
Loader
::
Yaml
.
new
(
content
).
load!
expanded_content_hash
rescue
Gitlab
::
Config
::
Loader
::
FormatError
nil
end
end
protected
protected
def
expanded_content_hash
return
unless
content_hash
strong_memoize
(
:expanded_content_yaml
)
do
expand_includes
(
content_hash
)
end
end
def
content_hash
strong_memoize
(
:content_yaml
)
do
Gitlab
::
Config
::
Loader
::
Yaml
.
new
(
content
).
load!
end
rescue
Gitlab
::
Config
::
Loader
::
FormatError
nil
end
def
validate!
def
validate!
validate_location!
validate_location!
validate_content!
if
errors
.
none?
validate_content!
if
errors
.
none?
...
@@ -73,6 +87,14 @@ module Gitlab
...
@@ -73,6 +87,14 @@ module Gitlab
errors
.
push
(
"Included file `
#{
location
}
` does not have valid YAML syntax!"
)
errors
.
push
(
"Included file `
#{
location
}
` does not have valid YAML syntax!"
)
end
end
end
end
def
expand_includes
(
hash
)
External
::
Processor
.
new
(
hash
,
**
expand_context
).
perform
end
def
expand_context
{
project:
nil
,
sha:
nil
,
user:
nil
,
expandset:
context
.
expandset
}
end
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/external/file/local.rb
View file @
bb6ef418
...
@@ -31,6 +31,13 @@ module Gitlab
...
@@ -31,6 +31,13 @@ module Gitlab
def
fetch_local_content
def
fetch_local_content
context
.
project
.
repository
.
blob_data_at
(
context
.
sha
,
location
)
context
.
project
.
repository
.
blob_data_at
(
context
.
sha
,
location
)
end
end
def
expand_context
super
.
merge
(
project:
context
.
project
,
sha:
context
.
sha
,
user:
context
.
user
)
end
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/external/file/project.rb
View file @
bb6ef418
...
@@ -64,6 +64,13 @@ module Gitlab
...
@@ -64,6 +64,13 @@ module Gitlab
project
.
commit
(
ref_name
).
try
(
:sha
)
project
.
commit
(
ref_name
).
try
(
:sha
)
end
end
end
end
def
expand_context
super
.
merge
(
project:
project
,
sha:
sha
,
user:
context
.
user
)
end
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/external/mapper.rb
View file @
bb6ef418
...
@@ -7,6 +7,8 @@ module Gitlab
...
@@ -7,6 +7,8 @@ module Gitlab
class
Mapper
class
Mapper
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
MAX_INCLUDES
=
50
FILE_CLASSES
=
[
FILE_CLASSES
=
[
External
::
File
::
Remote
,
External
::
File
::
Remote
,
External
::
File
::
Template
,
External
::
File
::
Template
,
...
@@ -14,25 +16,34 @@ module Gitlab
...
@@ -14,25 +16,34 @@ module Gitlab
External
::
File
::
Project
External
::
File
::
Project
].
freeze
].
freeze
AmbigiousSpecificationError
=
Class
.
new
(
StandardError
)
Error
=
Class
.
new
(
StandardError
)
AmbigiousSpecificationError
=
Class
.
new
(
Error
)
DuplicateIncludesError
=
Class
.
new
(
Error
)
TooManyIncludesError
=
Class
.
new
(
Error
)
def
initialize
(
values
,
project
:,
sha
:,
user
:,
expandset
:)
raise
Error
,
'Expanded needs to be `Set`'
unless
expandset
.
is_a?
(
Set
)
def
initialize
(
values
,
project
:,
sha
:,
user
:)
@locations
=
Array
.
wrap
(
values
.
fetch
(
:include
,
[]))
@locations
=
Array
.
wrap
(
values
.
fetch
(
:include
,
[]))
@project
=
project
@project
=
project
@sha
=
sha
@sha
=
sha
@user
=
user
@user
=
user
@expandset
=
expandset
end
end
def
process
def
process
return
[]
if
locations
.
empty?
locations
locations
.
compact
.
compact
.
map
(
&
method
(
:normalize_location
))
.
map
(
&
method
(
:normalize_location
))
.
each
(
&
method
(
:verify_duplicates!
))
.
map
(
&
method
(
:select_first_matching
))
.
map
(
&
method
(
:select_first_matching
))
end
end
private
private
attr_reader
:locations
,
:project
,
:sha
,
:user
attr_reader
:locations
,
:project
,
:sha
,
:user
,
:expandset
# convert location if String to canonical form
# convert location if String to canonical form
def
normalize_location
(
location
)
def
normalize_location
(
location
)
...
@@ -51,6 +62,23 @@ module Gitlab
...
@@ -51,6 +62,23 @@ module Gitlab
end
end
end
end
def
verify_duplicates!
(
location
)
if
expandset
.
count
>=
MAX_INCLUDES
raise
TooManyIncludesError
,
"Maximum of
#{
MAX_INCLUDES
}
nested includes are allowed!"
end
# We scope location to context, as this allows us to properly support
# relative incldues, and similarly looking relative in another project
# does not trigger duplicate error
scoped_location
=
location
.
merge
(
context_project:
project
,
context_sha:
sha
)
unless
expandset
.
add?
(
scoped_location
)
raise
DuplicateIncludesError
,
"Include `
#{
location
.
to_json
}
` was already included!"
end
end
def
select_first_matching
(
location
)
def
select_first_matching
(
location
)
matching
=
FILE_CLASSES
.
map
do
|
file_class
|
matching
=
FILE_CLASSES
.
map
do
|
file_class
|
file_class
.
new
(
location
,
context
)
file_class
.
new
(
location
,
context
)
...
@@ -63,7 +91,7 @@ module Gitlab
...
@@ -63,7 +91,7 @@ module Gitlab
def
context
def
context
strong_memoize
(
:context
)
do
strong_memoize
(
:context
)
do
External
::
File
::
Base
::
Context
.
new
(
project
,
sha
,
user
)
External
::
File
::
Base
::
Context
.
new
(
project
,
sha
,
user
,
expandset
)
end
end
end
end
end
end
...
...
lib/gitlab/ci/config/external/processor.rb
View file @
bb6ef418
...
@@ -7,11 +7,11 @@ module Gitlab
...
@@ -7,11 +7,11 @@ module Gitlab
class
Processor
class
Processor
IncludeError
=
Class
.
new
(
StandardError
)
IncludeError
=
Class
.
new
(
StandardError
)
def
initialize
(
values
,
project
:,
sha
:,
user
:)
def
initialize
(
values
,
project
:,
sha
:,
user
:
,
expandset
:
)
@values
=
values
@values
=
values
@external_files
=
External
::
Mapper
.
new
(
values
,
project:
project
,
sha:
sha
,
user:
user
).
process
@external_files
=
External
::
Mapper
.
new
(
values
,
project:
project
,
sha:
sha
,
user:
user
,
expandset:
expandset
).
process
@content
=
{}
@content
=
{}
rescue
External
::
Mapper
::
AmbigiousSpecification
Error
=>
e
rescue
External
::
Mapper
::
Error
=>
e
raise
IncludeError
,
e
.
message
raise
IncludeError
,
e
.
message
end
end
...
...
spec/lib/gitlab/ci/config/external/file/base_spec.rb
View file @
bb6ef418
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
require
'fast_spec_helper'
require
'fast_spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Base
do
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Base
do
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'HEAD'
,
nil
)
}
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'HEAD'
,
nil
,
Set
.
new
)
}
let
(
:test_class
)
do
let
(
:test_class
)
do
Class
.
new
(
described_class
)
do
Class
.
new
(
described_class
)
do
...
@@ -79,4 +79,20 @@ describe Gitlab::Ci::Config::External::File::Base do
...
@@ -79,4 +79,20 @@ describe Gitlab::Ci::Config::External::File::Base do
end
end
end
end
end
end
describe
'#to_hash'
do
context
'with includes'
do
let
(
:location
)
{
'some/file/config.yml'
}
let
(
:content
)
{
'include: { template: Bash.gitlab-ci.yml }'
}
before
do
allow_any_instance_of
(
test_class
)
.
to
receive
(
:content
).
and_return
(
content
)
end
it
'does expand hash to include the template'
do
expect
(
subject
.
to_hash
).
to
include
(
:before_script
)
end
end
end
end
end
spec/lib/gitlab/ci/config/external/file/local_spec.rb
View file @
bb6ef418
...
@@ -4,8 +4,10 @@ require 'spec_helper'
...
@@ -4,8 +4,10 @@ require 'spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Local
do
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Local
do
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:user
)
{
create
(
:user
)
}
let
(
:context
)
{
described_class
::
Context
.
new
(
project
,
'12345'
,
nil
)
}
let
(
:sha
)
{
'12345'
}
let
(
:context
)
{
described_class
::
Context
.
new
(
project
,
sha
,
user
,
Set
.
new
)
}
let
(
:params
)
{
{
local:
location
}
}
let
(
:params
)
{
{
local:
location
}
}
let
(
:local_file
)
{
described_class
.
new
(
params
,
context
)
}
let
(
:local_file
)
{
described_class
.
new
(
params
,
context
)
}
...
@@ -103,4 +105,36 @@ describe Gitlab::Ci::Config::External::File::Local do
...
@@ -103,4 +105,36 @@ describe Gitlab::Ci::Config::External::File::Local do
expect
(
local_file
.
error_message
).
to
eq
(
"Local file `
#{
location
}
` does not exist!"
)
expect
(
local_file
.
error_message
).
to
eq
(
"Local file `
#{
location
}
` does not exist!"
)
end
end
end
end
describe
'#expand_context'
do
let
(
:location
)
{
'location.yml'
}
subject
{
local_file
.
send
(
:expand_context
)
}
it
'inherits project, user and sha'
do
is_expected
.
to
include
(
user:
user
,
project:
project
,
sha:
sha
)
end
end
describe
'#to_hash'
do
context
'properly includes another local file in the same repository'
do
let
(
:location
)
{
'some/file/config.yml'
}
let
(
:content
)
{
'include: { local: another-config.yml }'
}
let
(
:another_location
)
{
'another-config.yml'
}
let
(
:another_content
)
{
'rspec: JOB'
}
before
do
allow
(
project
.
repository
).
to
receive
(
:blob_data_at
).
with
(
sha
,
location
)
.
and_return
(
content
)
allow
(
project
.
repository
).
to
receive
(
:blob_data_at
).
with
(
sha
,
another_location
)
.
and_return
(
another_content
)
end
it
'does expand hash to include the template'
do
expect
(
local_file
.
to_hash
).
to
include
(
:rspec
)
end
end
end
end
end
spec/lib/gitlab/ci/config/external/file/project_spec.rb
View file @
bb6ef418
...
@@ -3,12 +3,13 @@
...
@@ -3,12 +3,13 @@
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Project
do
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Project
do
set
(
:context_project
)
{
create
(
:project
)
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:user
)
{
create
(
:user
)
}
set
(
:user
)
{
create
(
:user
)
}
let
(
:context_user
)
{
user
}
let
(
:context_user
)
{
user
}
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'12345'
,
context_user
)
}
let
(
:context
)
{
described_class
::
Context
.
new
(
context_project
,
'12345'
,
context_user
,
Set
.
new
)
}
let
(
:
subject
)
{
described_class
.
new
(
params
,
context
)
}
let
(
:
project_file
)
{
described_class
.
new
(
params
,
context
)
}
before
do
before
do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
...
@@ -19,7 +20,7 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -19,7 +20,7 @@ describe Gitlab::Ci::Config::External::File::Project do
let
(
:params
)
{
{
file:
'file.yml'
,
project:
'project'
}
}
let
(
:params
)
{
{
file:
'file.yml'
,
project:
'project'
}
}
it
'should return true'
do
it
'should return true'
do
expect
(
subject
).
to
be_matching
expect
(
project_file
).
to
be_matching
end
end
end
end
...
@@ -27,7 +28,7 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -27,7 +28,7 @@ describe Gitlab::Ci::Config::External::File::Project do
let
(
:params
)
{
{
file:
'file.yml'
}
}
let
(
:params
)
{
{
file:
'file.yml'
}
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_matching
expect
(
project_file
).
not_to
be_matching
end
end
end
end
...
@@ -35,7 +36,7 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -35,7 +36,7 @@ describe Gitlab::Ci::Config::External::File::Project do
let
(
:params
)
{
{
project:
'project'
}
}
let
(
:params
)
{
{
project:
'project'
}
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_matching
expect
(
project_file
).
not_to
be_matching
end
end
end
end
...
@@ -43,7 +44,7 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -43,7 +44,7 @@ describe Gitlab::Ci::Config::External::File::Project do
let
(
:params
)
{
{}
}
let
(
:params
)
{
{}
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_matching
expect
(
project_file
).
not_to
be_matching
end
end
end
end
end
end
...
@@ -61,15 +62,15 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -61,15 +62,15 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return true'
do
it
'should return true'
do
expect
(
subject
).
to
be_valid
expect
(
project_file
).
to
be_valid
end
end
context
'when user does not have permission to access file'
do
context
'when user does not have permission to access file'
do
let
(
:context_user
)
{
create
(
:user
)
}
let
(
:context_user
)
{
create
(
:user
)
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
project_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` not found or access denied!"
)
expect
(
project_file
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` not found or access denied!"
)
end
end
end
end
end
end
...
@@ -86,7 +87,7 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -86,7 +87,7 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return true'
do
it
'should return true'
do
expect
(
subject
).
to
be_valid
expect
(
project_file
).
to
be_valid
end
end
end
end
...
@@ -102,8 +103,8 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -102,8 +103,8 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
project_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` file `/file.yml` is empty!"
)
expect
(
project_file
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` file `/file.yml` is empty!"
)
end
end
end
end
...
@@ -113,8 +114,8 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -113,8 +114,8 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
project_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` reference `I-Do-Not-Exist` does not exist!"
)
expect
(
project_file
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` reference `I-Do-Not-Exist` does not exist!"
)
end
end
end
end
...
@@ -124,8 +125,8 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -124,8 +125,8 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
project_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` file `/invalid-file.yml` does not exist!"
)
expect
(
project_file
.
error_message
).
to
include
(
"Project `
#{
project
.
full_path
}
` file `/invalid-file.yml` does not exist!"
)
end
end
end
end
...
@@ -135,12 +136,22 @@ describe Gitlab::Ci::Config::External::File::Project do
...
@@ -135,12 +136,22 @@ describe Gitlab::Ci::Config::External::File::Project do
end
end
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
project_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
'Included file `/invalid-file` does not have YAML extension!'
)
expect
(
project_file
.
error_message
).
to
include
(
'Included file `/invalid-file` does not have YAML extension!'
)
end
end
end
end
end
end
describe
'#expand_context'
do
let
(
:params
)
{
{
file:
'file.yml'
,
project:
project
.
full_path
,
ref:
'master'
}
}
subject
{
project_file
.
send
(
:expand_context
)
}
it
'inherits user, and target project and sha'
do
is_expected
.
to
include
(
user:
user
,
project:
project
,
sha:
project
.
commit
(
'master'
).
id
)
end
end
private
private
def
stub_project_blob
(
ref
,
path
)
def
stub_project_blob
(
ref
,
path
)
...
...
spec/lib/gitlab/ci/config/external/file/remote_spec.rb
View file @
bb6ef418
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Remote
do
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Remote
do
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'12345'
,
nil
)
}
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'12345'
,
nil
,
Set
.
new
)
}
let
(
:params
)
{
{
remote:
location
}
}
let
(
:params
)
{
{
remote:
location
}
}
let
(
:remote_file
)
{
described_class
.
new
(
params
,
context
)
}
let
(
:remote_file
)
{
described_class
.
new
(
params
,
context
)
}
let
(
:location
)
{
'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml'
}
let
(
:location
)
{
'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml'
}
...
@@ -181,4 +181,14 @@ describe Gitlab::Ci::Config::External::File::Remote do
...
@@ -181,4 +181,14 @@ describe Gitlab::Ci::Config::External::File::Remote do
end
end
end
end
end
end
describe
'#expand_context'
do
let
(
:params
)
{
{
remote:
'http://remote'
}
}
subject
{
remote_file
.
send
(
:expand_context
)
}
it
'drops all parameters'
do
is_expected
.
to
include
(
user:
nil
,
project:
nil
,
sha:
nil
)
end
end
end
end
spec/lib/gitlab/ci/config/external/file/template_spec.rb
View file @
bb6ef418
...
@@ -3,18 +3,21 @@
...
@@ -3,18 +3,21 @@
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Template
do
describe
Gitlab
::
Ci
::
Config
::
External
::
File
::
Template
do
let
(
:context
)
{
described_class
::
Context
.
new
(
nil
,
'12345'
)
}
set
(
:project
)
{
create
(
:project
)
}
set
(
:user
)
{
create
(
:user
)
}
let
(
:context
)
{
described_class
::
Context
.
new
(
project
,
'12345'
,
user
,
Set
.
new
)
}
let
(
:template
)
{
'Auto-DevOps.gitlab-ci.yml'
}
let
(
:template
)
{
'Auto-DevOps.gitlab-ci.yml'
}
let
(
:params
)
{
{
template:
template
}
}
let
(
:params
)
{
{
template:
template
}
}
subject
{
described_class
.
new
(
params
,
context
)
}
let
(
:template_file
)
{
described_class
.
new
(
params
,
context
)
}
describe
'#matching?'
do
describe
'#matching?'
do
context
'when a template is specified'
do
context
'when a template is specified'
do
let
(
:params
)
{
{
template:
'some-template'
}
}
let
(
:params
)
{
{
template:
'some-template'
}
}
it
'should return true'
do
it
'should return true'
do
expect
(
subject
).
to
be_matching
expect
(
template_file
).
to
be_matching
end
end
end
end
...
@@ -22,7 +25,7 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -22,7 +25,7 @@ describe Gitlab::Ci::Config::External::File::Template do
let
(
:params
)
{
{
template:
nil
}
}
let
(
:params
)
{
{
template:
nil
}
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_matching
expect
(
template_file
).
not_to
be_matching
end
end
end
end
...
@@ -30,7 +33,7 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -30,7 +33,7 @@ describe Gitlab::Ci::Config::External::File::Template do
let
(
:params
)
{
{}
}
let
(
:params
)
{
{}
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_matching
expect
(
template_file
).
not_to
be_matching
end
end
end
end
end
end
...
@@ -40,7 +43,7 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -40,7 +43,7 @@ describe Gitlab::Ci::Config::External::File::Template do
let
(
:template
)
{
'Auto-DevOps.gitlab-ci.yml'
}
let
(
:template
)
{
'Auto-DevOps.gitlab-ci.yml'
}
it
'should return true'
do
it
'should return true'
do
expect
(
subject
).
to
be_valid
expect
(
template_file
).
to
be_valid
end
end
end
end
...
@@ -48,8 +51,8 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -48,8 +51,8 @@ describe Gitlab::Ci::Config::External::File::Template do
let
(
:template
)
{
'Template.yml'
}
let
(
:template
)
{
'Template.yml'
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
template_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
'Template file `Template.yml` is not a valid location!'
)
expect
(
template_file
.
error_message
).
to
include
(
'Template file `Template.yml` is not a valid location!'
)
end
end
end
end
...
@@ -57,14 +60,14 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -57,14 +60,14 @@ describe Gitlab::Ci::Config::External::File::Template do
let
(
:template
)
{
'I-Do-Not-Have-This-Template.gitlab-ci.yml'
}
let
(
:template
)
{
'I-Do-Not-Have-This-Template.gitlab-ci.yml'
}
it
'should return false'
do
it
'should return false'
do
expect
(
subject
).
not_to
be_valid
expect
(
template_file
).
not_to
be_valid
expect
(
subject
.
error_message
).
to
include
(
'Included file `I-Do-Not-Have-This-Template.gitlab-ci.yml` is empty or does not exist!'
)
expect
(
template_file
.
error_message
).
to
include
(
'Included file `I-Do-Not-Have-This-Template.gitlab-ci.yml` is empty or does not exist!'
)
end
end
end
end
end
end
describe
'#template_name'
do
describe
'#template_name'
do
let
(
:template_name
)
{
subject
.
send
(
:template_name
)
}
let
(
:template_name
)
{
template_file
.
send
(
:template_name
)
}
context
'when template does end with .gitlab-ci.yml'
do
context
'when template does end with .gitlab-ci.yml'
do
let
(
:template
)
{
'my-template.gitlab-ci.yml'
}
let
(
:template
)
{
'my-template.gitlab-ci.yml'
}
...
@@ -90,4 +93,14 @@ describe Gitlab::Ci::Config::External::File::Template do
...
@@ -90,4 +93,14 @@ describe Gitlab::Ci::Config::External::File::Template do
end
end
end
end
end
end
describe
'#expand_context'
do
let
(
:location
)
{
'location.yml'
}
subject
{
template_file
.
send
(
:expand_context
)
}
it
'drops all parameters'
do
is_expected
.
to
include
(
user:
nil
,
project:
nil
,
sha:
nil
)
end
end
end
end
spec/lib/gitlab/ci/config/external/mapper_spec.rb
View file @
bb6ef418
...
@@ -9,6 +9,7 @@ describe Gitlab::Ci::Config::External::Mapper do
...
@@ -9,6 +9,7 @@ describe Gitlab::Ci::Config::External::Mapper do
let
(
:local_file
)
{
'/lib/gitlab/ci/templates/non-existent-file.yml'
}
let
(
:local_file
)
{
'/lib/gitlab/ci/templates/non-existent-file.yml'
}
let
(
:remote_url
)
{
'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml'
}
let
(
:remote_url
)
{
'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml'
}
let
(
:template_file
)
{
'Auto-DevOps.gitlab-ci.yml'
}
let
(
:template_file
)
{
'Auto-DevOps.gitlab-ci.yml'
}
let
(
:expandset
)
{
Set
.
new
}
let
(
:file_content
)
do
let
(
:file_content
)
do
<<~
HEREDOC
<<~
HEREDOC
...
@@ -21,7 +22,7 @@ describe Gitlab::Ci::Config::External::Mapper do
...
@@ -21,7 +22,7 @@ describe Gitlab::Ci::Config::External::Mapper do
end
end
describe
'#process'
do
describe
'#process'
do
subject
{
described_class
.
new
(
values
,
project:
project
,
sha:
'123456'
,
user:
user
).
process
}
subject
{
described_class
.
new
(
values
,
project:
project
,
sha:
'123456'
,
user:
user
,
expandset:
expandset
).
process
}
context
"when single 'include' keyword is defined"
do
context
"when single 'include' keyword is defined"
do
context
'when the string is a local file'
do
context
'when the string is a local file'
do
...
@@ -141,5 +142,37 @@ describe Gitlab::Ci::Config::External::Mapper do
...
@@ -141,5 +142,37 @@ describe Gitlab::Ci::Config::External::Mapper do
expect
(
subject
).
to
be_empty
expect
(
subject
).
to
be_empty
end
end
end
end
context
"when duplicate 'include' is defined"
do
let
(
:values
)
do
{
include:
[
{
'local'
=>
local_file
},
{
'local'
=>
local_file
}
],
image:
'ruby:2.2'
}
end
it
'raises an exception'
do
expect
{
subject
}.
to
raise_error
(
described_class
::
DuplicateIncludesError
)
end
end
context
"when too many 'includes' are defined"
do
let
(
:values
)
do
{
include:
[
{
'local'
=>
local_file
},
{
'remote'
=>
remote_url
}
],
image:
'ruby:2.2'
}
end
before
do
stub_const
(
"
#{
described_class
}
::MAX_INCLUDES"
,
1
)
end
it
'raises an exception'
do
expect
{
subject
}.
to
raise_error
(
described_class
::
TooManyIncludesError
)
end
end
end
end
end
end
spec/lib/gitlab/ci/config/external/processor_spec.rb
View file @
bb6ef418
...
@@ -4,15 +4,20 @@ require 'spec_helper'
...
@@ -4,15 +4,20 @@ require 'spec_helper'
describe
Gitlab
::
Ci
::
Config
::
External
::
Processor
do
describe
Gitlab
::
Ci
::
Config
::
External
::
Processor
do
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:project
)
{
create
(
:project
,
:repository
)
}
set
(
:another_project
)
{
create
(
:project
,
:repository
)
}
set
(
:user
)
{
create
(
:user
)
}
set
(
:user
)
{
create
(
:user
)
}
let
(
:processor
)
{
described_class
.
new
(
values
,
project:
project
,
sha:
'12345'
,
user:
user
)
}
let
(
:expandset
)
{
Set
.
new
}
let
(
:sha
)
{
'12345'
}
let
(
:processor
)
{
described_class
.
new
(
values
,
project:
project
,
sha:
'12345'
,
user:
user
,
expandset:
expandset
)
}
before
do
before
do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
end
end
describe
"#perform"
do
describe
"#perform"
do
subject
{
processor
.
perform
}
context
'when no external files defined'
do
context
'when no external files defined'
do
let
(
:values
)
{
{
image:
'ruby:2.2'
}
}
let
(
:values
)
{
{
image:
'ruby:2.2'
}
}
...
@@ -190,5 +195,80 @@ describe Gitlab::Ci::Config::External::Processor do
...
@@ -190,5 +195,80 @@ describe Gitlab::Ci::Config::External::Processor do
expect
(
processor
.
perform
[
:image
]).
to
eq
(
'ruby:2.2'
)
expect
(
processor
.
perform
[
:image
]).
to
eq
(
'ruby:2.2'
)
end
end
end
end
context
"when a nested includes are defined"
do
let
(
:values
)
do
{
include:
[
{
local:
'/local/file.yml'
}
],
image:
'ruby:2.2'
}
end
before
do
allow
(
project
.
repository
).
to
receive
(
:blob_data_at
).
with
(
'12345'
,
'/local/file.yml'
)
do
<<~
HEREDOC
include:
- template: Ruby.gitlab-ci.yml
- remote: http://my.domain.com/config.yml
- project:
#{
another_project
.
full_path
}
file: /templates/my-workflow.yml
HEREDOC
end
allow_any_instance_of
(
Repository
).
to
receive
(
:blob_data_at
).
with
(
another_project
.
commit
.
id
,
'/templates/my-workflow.yml'
)
do
<<~
HEREDOC
include:
- local: /templates/my-build.yml
HEREDOC
end
allow_any_instance_of
(
Repository
).
to
receive
(
:blob_data_at
).
with
(
another_project
.
commit
.
id
,
'/templates/my-build.yml'
)
do
<<~
HEREDOC
my_build:
script: echo Hello World
HEREDOC
end
WebMock
.
stub_request
(
:get
,
'http://my.domain.com/config.yml'
).
to_return
(
body:
'remote_build: { script: echo Hello World }'
)
end
context
'when project is public'
do
before
do
another_project
.
update!
(
visibility:
'public'
)
end
it
'properly expands all includes'
do
is_expected
.
to
include
(
:my_build
,
:remote_build
,
:rspec
)
end
end
context
'when user is reporter of another project'
do
before
do
another_project
.
add_reporter
(
user
)
end
it
'properly expands all includes'
do
is_expected
.
to
include
(
:my_build
,
:remote_build
,
:rspec
)
end
end
context
'when user is not allowed'
do
it
'raises an error'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Ci
::
Config
::
External
::
Processor
::
IncludeError
,
/not found or access denied/
)
end
end
context
'when too many includes is included'
do
before
do
stub_const
(
'Gitlab::Ci::Config::External::Mapper::MAX_INCLUDES'
,
1
)
end
it
'raises an error'
do
expect
{
subject
}.
to
raise_error
(
Gitlab
::
Ci
::
Config
::
External
::
Processor
::
IncludeError
,
/Maximum of 1 nested/
)
end
end
end
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment