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
d609eaed
Commit
d609eaed
authored
Mar 27, 2018
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement pipeline variables expressions / EE port
parent
1aec54db
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
449 additions
and
106 deletions
+449
-106
app/models/ci/build.rb
app/models/ci/build.rb
+51
-26
changelogs/unreleased/feature-gb-variables-expressions-in-only-except.yml
...eased/feature-gb-variables-expressions-in-only-except.yml
+5
-0
lib/gitlab/ci/build/policy/kubernetes.rb
lib/gitlab/ci/build/policy/kubernetes.rb
+1
-1
lib/gitlab/ci/build/policy/refs.rb
lib/gitlab/ci/build/policy/refs.rb
+1
-1
lib/gitlab/ci/build/policy/specification.rb
lib/gitlab/ci/build/policy/specification.rb
+1
-1
lib/gitlab/ci/build/policy/variables.rb
lib/gitlab/ci/build/policy/variables.rb
+24
-0
lib/gitlab/ci/config/entry/policy.rb
lib/gitlab/ci/config/entry/policy.rb
+18
-2
lib/gitlab/ci/pipeline/chain/populate.rb
lib/gitlab/ci/pipeline/chain/populate.rb
+0
-2
lib/gitlab/ci/pipeline/expression/lexeme/string.rb
lib/gitlab/ci/pipeline/expression/lexeme/string.rb
+1
-1
lib/gitlab/ci/pipeline/expression/lexeme/variable.rb
lib/gitlab/ci/pipeline/expression/lexeme/variable.rb
+1
-1
lib/gitlab/ci/pipeline/expression/statement.rb
lib/gitlab/ci/pipeline/expression/statement.rb
+16
-5
lib/gitlab/ci/pipeline/seed/build.rb
lib/gitlab/ci/pipeline/seed/build.rb
+7
-11
lib/gitlab/ci/pipeline/seed/stage.rb
lib/gitlab/ci/pipeline/seed/stage.rb
+0
-4
lib/gitlab/ci/variables/collection.rb
lib/gitlab/ci/variables/collection.rb
+7
-1
lib/gitlab/ci/variables/collection/item.rb
lib/gitlab/ci/variables/collection/item.rb
+2
-2
spec/lib/gitlab/ci/build/policy/variables_spec.rb
spec/lib/gitlab/ci/build/policy/variables_spec.rb
+68
-0
spec/lib/gitlab/ci/config/entry/policy_spec.rb
spec/lib/gitlab/ci/config/entry/policy_spec.rb
+25
-0
spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
+6
-1
spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
+16
-0
spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
+68
-23
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+0
-10
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
+0
-10
spec/lib/gitlab/ci/variables/collection/item_spec.rb
spec/lib/gitlab/ci/variables/collection/item_spec.rb
+7
-3
spec/lib/gitlab/ci/variables/collection_spec.rb
spec/lib/gitlab/ci/variables/collection_spec.rb
+16
-1
spec/lib/gitlab/ci/yaml_processor_spec.rb
spec/lib/gitlab/ci/yaml_processor_spec.rb
+8
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+86
-0
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+14
-0
No files found.
app/models/ci/build.rb
View file @
d609eaed
...
...
@@ -27,7 +27,9 @@ module Ci
has_one
:job_artifacts_metadata
,
->
{
where
(
file_type:
Ci
::
JobArtifact
.
file_types
[
:metadata
])
},
class_name:
'Ci::JobArtifact'
,
inverse_of: :job
,
foreign_key: :job_id
has_one
:job_artifacts_trace
,
->
{
where
(
file_type:
Ci
::
JobArtifact
.
file_types
[
:trace
])
},
class_name:
'Ci::JobArtifact'
,
inverse_of: :job
,
foreign_key: :job_id
# The "environment" field for builds is a String, and is the unexpanded name
##
# The "environment" field for builds is a String, and is the unexpanded name!
#
def
persisted_environment
@persisted_environment
||=
Environment
.
find_by
(
name:
expanded_environment_name
,
...
...
@@ -203,7 +205,9 @@ module Ci
end
def
expanded_environment_name
ExpandVariables
.
expand
(
environment
,
simple_variables
)
if
environment
if
has_environment?
ExpandVariables
.
expand
(
environment
,
simple_variables
)
end
end
def
has_environment?
...
...
@@ -253,31 +257,44 @@ module Ci
Gitlab
::
Utils
.
slugify
(
ref
.
to_s
)
end
# Variables whose value does not depend on environment
def
simple_variables
variables
(
environment:
nil
)
end
# All variables, including those dependent on environment, which could
# contain unexpanded variables.
def
variables
(
environment:
persisted_environment
)
collection
=
Gitlab
::
Ci
::
Variables
::
Collection
.
new
.
tap
do
|
variables
|
##
# Variables in the environment name scope.
#
def
scoped_variables
(
environment:
expanded_environment_name
)
Gitlab
::
Ci
::
Variables
::
Collection
.
new
.
tap
do
|
variables
|
variables
.
concat
(
predefined_variables
)
variables
.
concat
(
project
.
predefined_variables
)
variables
.
concat
(
pipeline
.
predefined_variables
)
variables
.
concat
(
runner
.
predefined_variables
)
if
runner
variables
.
concat
(
project
.
deployment_variables
(
environment:
environment
))
if
has_environment?
variables
.
concat
(
project
.
deployment_variables
(
environment:
environment
))
if
environment
variables
.
concat
(
yaml_variables
)
variables
.
concat
(
user_variables
)
variables
.
concat
(
project
.
group
.
secret_variables_for
(
ref
,
project
))
if
project
.
group
variables
.
concat
(
secret_variables
(
environment:
environment
))
variables
.
concat
(
secret_group_variables
)
variables
.
concat
(
secret_
project_
variables
(
environment:
environment
))
variables
.
concat
(
trigger_request
.
user_variables
)
if
trigger_request
variables
.
concat
(
pipeline
.
variables
)
variables
.
concat
(
pipeline
.
pipeline_schedule
.
job_variables
)
if
pipeline
.
pipeline_schedule
variables
.
concat
(
persisted_environment_variables
)
if
environment
end
end
##
# Variables that do not depend on the environment name.
#
def
simple_variables
scoped_variables
(
environment:
nil
).
to_runner_variables
end
##
# All variables, including persisted environment variables.
#
def
variables
scoped_variables
.
concat
(
persisted_environment_variables
)
.
to_runner_variables
end
collection
.
to_runner_variables
def
variables_hash
scoped_variables
.
to_hash
end
def
features
...
...
@@ -454,9 +471,14 @@ module Ci
end
end
def
secret_variables
(
environment:
persisted_environment
)
def
secret_group_variables
return
[]
unless
project
.
group
project
.
group
.
secret_variables_for
(
ref
,
project
)
end
def
secret_project_variables
(
environment:
persisted_environment
)
project
.
secret_variables_for
(
ref:
ref
,
environment:
environment
)
.
map
(
&
:to_runner_variable
)
end
def
steps
...
...
@@ -561,16 +583,16 @@ module Ci
variables
.
append
(
key:
'CI_SERVER_NAME'
,
value:
'GitLab'
)
variables
.
append
(
key:
'CI_SERVER_VERSION'
,
value:
Gitlab
::
VERSION
)
variables
.
append
(
key:
'CI_SERVER_REVISION'
,
value:
Gitlab
::
REVISION
)
variables
.
append
(
key:
'CI_JOB_ID'
,
value:
id
.
to_s
)
variables
.
append
(
key:
'CI_JOB_ID'
,
value:
id
.
to_s
)
if
persisted?
variables
.
append
(
key:
'CI_JOB_NAME'
,
value:
name
)
variables
.
append
(
key:
'CI_JOB_STAGE'
,
value:
stage
)
variables
.
append
(
key:
'CI_JOB_TOKEN'
,
value:
token
,
public:
false
)
variables
.
append
(
key:
'CI_JOB_TOKEN'
,
value:
token
,
public:
false
)
if
persisted?
variables
.
append
(
key:
'CI_COMMIT_SHA'
,
value:
sha
)
variables
.
append
(
key:
'CI_COMMIT_REF_NAME'
,
value:
ref
)
variables
.
append
(
key:
'CI_COMMIT_REF_SLUG'
,
value:
ref_slug
)
variables
.
append
(
key:
'CI_REGISTRY_USER'
,
value:
CI_REGISTRY_USER
)
variables
.
append
(
key:
'CI_REGISTRY_PASSWORD'
,
value:
token
,
public:
false
)
variables
.
append
(
key:
'CI_REPOSITORY_URL'
,
value:
repo_url
,
public:
false
)
variables
.
append
(
key:
'CI_REGISTRY_USER'
,
value:
CI_REGISTRY_USER
)
if
persisted?
variables
.
append
(
key:
'CI_REGISTRY_PASSWORD'
,
value:
token
,
public:
false
)
if
persisted?
variables
.
append
(
key:
'CI_REPOSITORY_URL'
,
value:
repo_url
,
public:
false
)
if
persisted?
variables
.
append
(
key:
"CI_COMMIT_TAG"
,
value:
ref
)
if
tag?
variables
.
append
(
key:
"CI_PIPELINE_TRIGGERED"
,
value:
'true'
)
if
trigger_request
variables
.
append
(
key:
"CI_JOB_MANUAL"
,
value:
'true'
)
if
action?
...
...
@@ -580,7 +602,7 @@ module Ci
def
persisted_environment_variables
Gitlab
::
Ci
::
Variables
::
Collection
.
new
.
tap
do
|
variables
|
return
variables
unless
persisted
_environment
return
variables
unless
persisted
?
&&
persisted_environment
.
present?
variables
.
concat
(
persisted_environment
.
predefined_variables
)
...
...
@@ -593,8 +615,11 @@ module Ci
def
legacy_variables
Gitlab
::
Ci
::
Variables
::
Collection
.
new
.
tap
do
|
variables
|
variables
.
append
(
key:
'CI_BUILD_ID'
,
value:
id
.
to_s
)
variables
.
append
(
key:
'CI_BUILD_TOKEN'
,
value:
token
,
public:
false
)
if
persisted?
variables
.
append
(
key:
'CI_BUILD_ID'
,
value:
id
.
to_s
)
variables
.
append
(
key:
'CI_BUILD_TOKEN'
,
value:
token
,
public:
false
)
end
variables
.
append
(
key:
'CI_BUILD_REF'
,
value:
sha
)
variables
.
append
(
key:
'CI_BUILD_BEFORE_SHA'
,
value:
before_sha
)
variables
.
append
(
key:
'CI_BUILD_REF_NAME'
,
value:
ref
)
...
...
changelogs/unreleased/feature-gb-variables-expressions-in-only-except.yml
0 → 100644
View file @
d609eaed
---
title
:
Add support for pipeline variables expressions in only/except
merge_request
:
17316
author
:
type
:
added
lib/gitlab/ci/build/policy/kubernetes.rb
View file @
d609eaed
...
...
@@ -9,7 +9,7 @@ module Gitlab
end
end
def
satisfied_by?
(
pipeline
)
def
satisfied_by?
(
pipeline
,
seed
=
nil
)
pipeline
.
has_kubernetes_active?
end
end
...
...
lib/gitlab/ci/build/policy/refs.rb
View file @
d609eaed
...
...
@@ -7,7 +7,7 @@ module Gitlab
@patterns
=
Array
(
refs
)
end
def
satisfied_by?
(
pipeline
)
def
satisfied_by?
(
pipeline
,
seed
=
nil
)
@patterns
.
any?
do
|
pattern
|
pattern
,
path
=
pattern
.
split
(
'@'
,
2
)
...
...
lib/gitlab/ci/build/policy/specification.rb
View file @
d609eaed
...
...
@@ -15,7 +15,7 @@ module Gitlab
@spec
=
spec
end
def
satisfied_by?
(
pipeline
)
def
satisfied_by?
(
pipeline
,
seed
=
nil
)
raise
NotImplementedError
end
end
...
...
lib/gitlab/ci/build/policy/variables.rb
0 → 100644
View file @
d609eaed
module
Gitlab
module
Ci
module
Build
module
Policy
class
Variables
<
Policy
::
Specification
def
initialize
(
expressions
)
@expressions
=
Array
(
expressions
)
end
def
satisfied_by?
(
pipeline
,
seed
)
variables
=
seed
.
to_resource
.
variables_hash
statements
=
@expressions
.
map
do
|
statement
|
::
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Statement
.
new
(
statement
,
variables
)
end
statements
.
any?
(
&
:truthful?
)
end
end
end
end
end
end
lib/gitlab/ci/config/entry/policy.rb
View file @
d609eaed
...
...
@@ -25,15 +25,31 @@ module Gitlab
include
Entry
::
Validatable
include
Entry
::
Attributable
attributes
:refs
,
:kubernetes
attributes
:refs
,
:kubernetes
,
:variables
validations
do
validates
:config
,
presence:
true
validates
:config
,
allowed_keys:
%i[refs kubernetes]
validates
:config
,
allowed_keys:
%i[refs kubernetes variables]
validate
:variables_expressions_syntax
with_options
allow_nil:
true
do
validates
:refs
,
array_of_strings_or_regexps:
true
validates
:kubernetes
,
allowed_values:
%w[active]
validates
:variables
,
array_of_strings:
true
end
def
variables_expressions_syntax
return
unless
variables
.
is_a?
(
Array
)
statements
=
variables
.
map
do
|
statement
|
::
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Statement
.
new
(
statement
)
end
statements
.
each
do
|
statement
|
unless
statement
.
valid?
errors
.
add
(
:variables
,
"Invalid expression
#{
statement
.
inspect
}
"
)
end
end
end
end
end
...
...
lib/gitlab/ci/pipeline/chain/populate.rb
View file @
d609eaed
...
...
@@ -17,8 +17,6 @@ module Gitlab
# Populate pipeline with all stages and builds from pipeline seeds.
#
pipeline
.
stage_seeds
.
each
do
|
stage
|
stage
.
user
=
current_user
pipeline
.
stages
<<
stage
.
to_resource
stage
.
seeds
.
each
do
|
build
|
...
...
lib/gitlab/ci/pipeline/expression/lexeme/string.rb
View file @
d609eaed
...
...
@@ -4,7 +4,7 @@ module Gitlab
module
Expression
module
Lexeme
class
String
<
Lexeme
::
Value
PATTERN
=
/("(?<string>.
+?)")|('(?<string>.+
?)')/
.
freeze
PATTERN
=
/("(?<string>.
*?)")|('(?<string>.*
?)')/
.
freeze
def
initialize
(
value
)
@value
=
value
...
...
lib/gitlab/ci/pipeline/expression/lexeme/variable.rb
View file @
d609eaed
...
...
@@ -11,7 +11,7 @@ module Gitlab
end
def
evaluate
(
variables
=
{})
HashWithIndifferentAccess
.
new
(
variables
)
.
fetch
(
@name
,
nil
)
variables
.
with_indifferent_access
.
fetch
(
@name
,
nil
)
end
def
self
.
build
(
string
)
...
...
lib/gitlab/ci/pipeline/expression/statement.rb
View file @
d609eaed
...
...
@@ -14,12 +14,9 @@ module Gitlab
%w[variable]
].
freeze
def
initialize
(
statement
,
pipeline
)
def
initialize
(
statement
,
variables
=
{}
)
@lexer
=
Expression
::
Lexer
.
new
(
statement
)
@variables
=
pipeline
.
variables
.
map
do
|
variable
|
[
variable
.
key
,
variable
.
value
]
end
@variables
=
variables
.
with_indifferent_access
end
def
parse_tree
...
...
@@ -35,6 +32,20 @@ module Gitlab
def
evaluate
parse_tree
.
evaluate
(
@variables
.
to_h
)
end
def
truthful?
evaluate
.
present?
end
def
inspect
"syntax:
#{
@lexer
.
lexemes
.
join
(
' '
)
}
"
end
def
valid?
parse_tree
.
is_a?
(
Lexeme
::
Base
)
rescue
StatementError
false
end
end
end
end
...
...
lib/gitlab/ci/pipeline/seed/build.rb
View file @
d609eaed
...
...
@@ -11,21 +11,16 @@ module Gitlab
@pipeline
=
pipeline
@attributes
=
attributes
@only
=
attributes
.
delete
(
:only
)
@except
=
attributes
.
delete
(
:except
)
end
def
user
=
(
current_user
)
@attributes
.
merge!
(
user:
current_user
)
@only
=
Gitlab
::
Ci
::
Build
::
Policy
.
fabricate
(
attributes
.
delete
(
:only
))
@except
=
Gitlab
::
Ci
::
Build
::
Policy
.
fabricate
(
attributes
.
delete
(
:except
))
end
def
included?
strong_memoize
(
:inclusion
)
do
only_specs
=
Gitlab
::
Ci
::
Build
::
Policy
.
fabricate
(
@only
)
except_specs
=
Gitlab
::
Ci
::
Build
::
Policy
.
fabricate
(
@except
)
only_specs
.
all?
{
|
spec
|
spec
.
satisfied_by?
(
@pipeline
)
}
&&
except_specs
.
none?
{
|
spec
|
spec
.
satisfied_by?
(
@pipeline
)
}
@only
.
all?
{
|
spec
|
spec
.
satisfied_by?
(
@pipeline
,
self
)
}
&&
@except
.
none?
{
|
spec
|
spec
.
satisfied_by?
(
@pipeline
,
self
)
}
end
end
...
...
@@ -33,6 +28,7 @@ module Gitlab
@attributes
.
merge
(
pipeline:
@pipeline
,
project:
@pipeline
.
project
,
user:
@pipeline
.
user
,
ref:
@pipeline
.
ref
,
tag:
@pipeline
.
tag
,
trigger_request:
@pipeline
.
legacy_trigger
,
...
...
lib/gitlab/ci/pipeline/seed/stage.rb
View file @
d609eaed
...
...
@@ -17,10 +17,6 @@ module Gitlab
end
end
def
user
=
(
current_user
)
@builds
.
each
{
|
seed
|
seed
.
user
=
current_user
}
end
def
attributes
{
name:
@attributes
.
fetch
(
:name
),
pipeline:
@pipeline
,
...
...
lib/gitlab/ci/variables/collection.rb
View file @
d609eaed
...
...
@@ -30,7 +30,13 @@ module Gitlab
end
def
to_runner_variables
self
.
map
(
&
:to_hash
)
self
.
map
(
&
:to_runner_variable
)
end
def
to_hash
self
.
to_runner_variables
.
map
{
|
env
|
[
env
.
fetch
(
:key
),
env
.
fetch
(
:value
)]
}
.
to_h
.
with_indifferent_access
end
end
end
...
...
lib/gitlab/ci/variables/collection/item.rb
View file @
d609eaed
...
...
@@ -17,7 +17,7 @@ module Gitlab
end
def
==
(
other
)
to_
hash
==
self
.
class
.
fabricate
(
other
).
to_hash
to_
runner_variable
==
self
.
class
.
fabricate
(
other
).
to_runner_variable
end
##
...
...
@@ -25,7 +25,7 @@ module Gitlab
# don't expose `file` attribute at all (stems from what the runner
# expects).
#
def
to_
hash
def
to_
runner_variable
@variable
.
reject
do
|
hash_key
,
hash_value
|
hash_key
==
:file
&&
hash_value
==
false
end
...
...
spec/lib/gitlab/ci/build/policy/variables_spec.rb
0 → 100644
View file @
d609eaed
require
'spec_helper'
describe
Gitlab
::
Ci
::
Build
::
Policy
::
Variables
do
set
(
:project
)
{
create
(
:project
)
}
let
(
:pipeline
)
do
build
(
:ci_empty_pipeline
,
project:
project
,
ref:
'master'
)
end
let
(
:ci_build
)
do
build
(
:ci_build
,
pipeline:
pipeline
,
project:
project
,
ref:
'master'
)
end
let
(
:seed
)
{
double
(
'build seed'
,
to_resource:
ci_build
)
}
before
do
pipeline
.
variables
.
build
(
key:
'CI_PROJECT_NAME'
,
value:
''
)
end
describe
'#satisfied_by?'
do
it
'is satisfied by a defined and existing variable'
do
policy
=
described_class
.
new
([
'$CI_PROJECT_ID'
,
'$UNDEFINED'
])
expect
(
policy
).
to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'is not satisfied by an overriden empty variable'
do
policy
=
described_class
.
new
([
'$CI_PROJECT_NAME'
])
expect
(
policy
).
not_to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'is satisfied by a truthy pipeline expression'
do
policy
=
described_class
.
new
([
%($CI_PIPELINE_SOURCE == "#{pipeline.source}")
])
expect
(
policy
).
to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'is not satisfied by a falsy pipeline expression'
do
policy
=
described_class
.
new
([
%($CI_PIPELINE_SOURCE == "invalid source")
])
expect
(
policy
).
not_to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'is satisfied by a truthy expression using undefined variable'
do
policy
=
described_class
.
new
([
'$UNDEFINED'
,
'$UNDEFINED == null'
])
expect
(
policy
).
to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'allows to evaluate regular secret variables'
do
secret
=
create
(
:ci_variable
,
project:
project
,
key:
'SECRET'
,
value:
'secret value'
)
policy
=
described_class
.
new
([
"$SECRET == 'secret value'"
])
expect
(
policy
).
to
be_satisfied_by
(
pipeline
,
seed
)
end
it
'does not persist neither pipeline nor build'
do
described_class
.
new
(
'$VAR'
).
satisfied_by?
(
pipeline
,
seed
)
expect
(
pipeline
).
not_to
be_persisted
expect
(
seed
.
to_resource
).
not_to
be_persisted
end
end
end
spec/lib/gitlab/ci/config/entry/policy_spec.rb
View file @
d609eaed
...
...
@@ -83,6 +83,31 @@ describe Gitlab::Ci::Config::Entry::Policy do
end
end
context
'when specifying valid variables expressions policy'
do
let
(
:config
)
{
{
variables:
[
'$VAR == null'
]
}
}
it
'is a correct configuraton'
do
expect
(
entry
).
to
be_valid
expect
(
entry
.
value
).
to
eq
(
config
)
end
end
context
'when specifying variables expressions in invalid format'
do
let
(
:config
)
{
{
variables:
'$MY_VAR'
}
}
it
'reports an error about invalid format'
do
expect
(
entry
.
errors
).
to
include
/should be an array of strings/
end
end
context
'when specifying invalid variables expressions statement'
do
let
(
:config
)
{
{
variables:
[
'$MY_VAR =='
]
}
}
it
'reports an error about invalid statement'
do
expect
(
entry
.
errors
).
to
include
/invalid expression syntax: variable equals/
end
end
context
'when specifying unknown policy'
do
let
(
:config
)
{
{
refs:
[
'master'
],
invalid: :something
}
}
...
...
spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
View file @
d609eaed
...
...
@@ -6,7 +6,8 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
let
(
:pipeline
)
do
build
(
:ci_pipeline_with_one_job
,
project:
project
,
ref:
'master'
)
ref:
'master'
,
user:
user
)
end
let
(
:command
)
do
...
...
@@ -42,6 +43,10 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do
expect
(
pipeline
.
stages
.
first
.
builds
).
to
be_one
expect
(
pipeline
.
stages
.
first
.
builds
.
first
).
not_to
be_persisted
end
it
'correctly assigns user'
do
expect
(
pipeline
.
builds
).
to
all
(
have_attributes
(
user:
user
))
end
end
context
'when pipeline is empty'
do
...
...
spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb
View file @
d609eaed
...
...
@@ -73,6 +73,22 @@ describe Gitlab::Ci::Pipeline::Expression::Lexeme::String do
expect
(
token
).
not_to
be_nil
expect
(
token
.
build
.
evaluate
).
to
eq
'some " string'
end
it
'allows to use an empty string inside single quotes'
do
scanner
=
StringScanner
.
new
(
%('')
)
token
=
described_class
.
scan
(
scanner
)
expect
(
token
.
build
.
evaluate
).
to
eq
''
end
it
'allow to use an empty string inside double quotes'
do
scanner
=
StringScanner
.
new
(
%("")
)
token
=
described_class
.
scan
(
scanner
)
expect
(
token
.
build
.
evaluate
).
to
eq
''
end
end
end
...
...
spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb
View file @
d609eaed
require
'spec_helper'
describe
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Statement
do
let
(
:pipeline
)
{
build
(
:ci_pipeline
)
}
subject
do
described_class
.
new
(
text
,
pipeline
)
described_class
.
new
(
text
,
variables
)
end
let
(
:variables
)
do
{
'PRESENT_VARIABLE'
=>
'my variable'
,
EMPTY_VARIABLE
:
''
}
end
before
do
pipeline
.
variables
.
build
([
key:
'VARIABLE'
,
value:
'my variable'
])
describe
'.new'
do
context
'when variables are not provided'
do
it
'allows to properly initializes the statement'
do
statement
=
described_class
.
new
(
'$PRESENT_VARIABLE'
)
expect
(
statement
.
evaluate
).
to
be_nil
end
end
end
describe
'#parse_tree'
do
...
...
@@ -23,18 +32,26 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do
context
'when expression grammar is incorrect'
do
table
=
[
'$VAR "text"'
,
# missing operator
'== "123"'
,
# invalid righ
t side
"'single quotes'"
,
# single quotes string
'$VAR =='
,
# invalid right side
'12345'
,
# unknown syntax
''
# empty statement
'$VAR "text"'
,
# missing operator
'== "123"'
,
# invalid lef
t side
'"some string"'
,
# only string provided
'$VAR =='
,
# invalid right side
'12345'
,
# unknown syntax
''
# empty statement
]
table
.
each
do
|
syntax
|
it
"raises an error when syntax is `
#{
syntax
}
`"
do
expect
{
described_class
.
new
(
syntax
,
pipeline
).
parse_tree
}
.
to
raise_error
described_class
::
StatementError
context
"when expression grammar is
#{
syntax
.
inspect
}
"
do
let
(
:text
)
{
syntax
}
it
'aises a statement error exception'
do
expect
{
subject
.
parse_tree
}
.
to
raise_error
described_class
::
StatementError
end
it
'is an invalid statement'
do
expect
(
subject
).
not_to
be_valid
end
end
end
end
...
...
@@ -47,10 +64,14 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do
expect
(
subject
.
parse_tree
)
.
to
be_a
Gitlab
::
Ci
::
Pipeline
::
Expression
::
Lexeme
::
Equals
end
it
'is a valid statement'
do
expect
(
subject
).
to
be_valid
end
end
context
'when using a single token'
do
let
(
:text
)
{
'$VARIABLE'
}
let
(
:text
)
{
'$
PRESENT_
VARIABLE'
}
it
'returns a single token instance'
do
expect
(
subject
.
parse_tree
)
...
...
@@ -62,14 +83,17 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do
describe
'#evaluate'
do
statements
=
[
[
'$VARIABLE == "my variable"'
,
true
],
[
"$VARIABLE == 'my variable'"
,
true
],
[
'"my variable" == $VARIABLE'
,
true
],
[
'$VARIABLE == null'
,
false
],
[
'$VAR == null'
,
true
],
[
'null == $VAR'
,
true
],
[
'$VARIABLE'
,
'my variable'
],
[
'$VAR'
,
nil
]
[
'$PRESENT_VARIABLE == "my variable"'
,
true
],
[
"$PRESENT_VARIABLE == 'my variable'"
,
true
],
[
'"my variable" == $PRESENT_VARIABLE'
,
true
],
[
'$PRESENT_VARIABLE == null'
,
false
],
[
'$EMPTY_VARIABLE == null'
,
false
],
[
'"" == $EMPTY_VARIABLE'
,
true
],
[
'$EMPTY_VARIABLE'
,
''
],
[
'$UNDEFINED_VARIABLE == null'
,
true
],
[
'null == $UNDEFINED_VARIABLE'
,
true
],
[
'$PRESENT_VARIABLE'
,
'my variable'
],
[
'$UNDEFINED_VARIABLE'
,
nil
]
]
statements
.
each
do
|
expression
,
value
|
...
...
@@ -82,4 +106,25 @@ describe Gitlab::Ci::Pipeline::Expression::Statement do
end
end
end
describe
'#truthful?'
do
statements
=
[
[
'$PRESENT_VARIABLE == "my variable"'
,
true
],
[
"$PRESENT_VARIABLE == 'no match'"
,
false
],
[
'$UNDEFINED_VARIABLE == null'
,
true
],
[
'$PRESENT_VARIABLE'
,
true
],
[
'$UNDEFINED_VARIABLE'
,
false
],
[
'$EMPTY_VARIABLE'
,
false
]
]
statements
.
each
do
|
expression
,
value
|
context
"when using expression `
#{
expression
}
`"
do
let
(
:text
)
{
expression
}
it
"returns `
#{
value
.
inspect
}
`"
do
expect
(
subject
.
truthful?
).
to
eq
value
end
end
end
end
end
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
View file @
d609eaed
...
...
@@ -21,16 +21,6 @@ describe Gitlab::Ci::Pipeline::Seed::Build do
end
end
describe
'#user='
do
let
(
:user
)
{
build
(
:user
)
}
it
'assignes user to a build'
do
subject
.
user
=
user
expect
(
subject
.
attributes
).
to
include
(
user:
user
)
end
end
describe
'#to_resource'
do
it
'returns a valid build resource'
do
expect
(
subject
.
to_resource
).
to
be_a
(
::
Ci
::
Build
)
...
...
spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb
View file @
d609eaed
...
...
@@ -95,16 +95,6 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do
end
end
describe
'#user='
do
let
(
:user
)
{
build
(
:user
)
}
it
'assignes relevant pipeline attributes'
do
subject
.
user
=
user
expect
(
subject
.
seeds
.
map
(
&
:attributes
)).
to
all
(
include
(
user:
user
))
end
end
describe
'#to_resource'
do
it
'builds a valid stage object with all builds'
do
subject
.
to_resource
.
save!
...
...
spec/lib/gitlab/ci/variables/collection/item_spec.rb
View file @
d609eaed
...
...
@@ -46,9 +46,13 @@ describe Gitlab::Ci::Variables::Collection::Item do
end
end
describe
'#to_hash'
do
it
'returns a hash representation of a collection item'
do
expect
(
described_class
.
new
(
**
variable
).
to_hash
).
to
eq
variable
describe
'#to_runner_variable'
do
it
'returns a runner-compatible hash representation'
do
runner_variable
=
described_class
.
new
(
**
variable
)
.
to_runner_variable
expect
(
runner_variable
).
to
eq
variable
end
end
end
spec/lib/gitlab/ci/variables/collection_spec.rb
View file @
d609eaed
...
...
@@ -7,7 +7,7 @@ describe Gitlab::Ci::Variables::Collection do
collection
=
described_class
.
new
([
variable
])
expect
(
collection
.
first
.
to_
hash
).
to
eq
variable
expect
(
collection
.
first
.
to_
runner_variable
).
to
eq
variable
end
it
'can be initialized without an argument'
do
...
...
@@ -96,4 +96,19 @@ describe Gitlab::Ci::Variables::Collection do
.
to
eq
[{
key:
'TEST'
,
value:
1
,
public:
true
}]
end
end
describe
'#to_hash'
do
it
'returns regular hash in valid order without duplicates'
do
collection
=
described_class
.
new
.
append
(
key:
'TEST1'
,
value:
'test-1'
)
.
append
(
key:
'TEST2'
,
value:
'test-2'
)
.
append
(
key:
'TEST1'
,
value:
'test-3'
)
expect
(
collection
.
to_hash
).
to
eq
(
'TEST1'
=>
'test-3'
,
'TEST2'
=>
'test-2'
)
expect
(
collection
.
to_hash
).
to
include
(
TEST1
:
'test-3'
)
expect
(
collection
.
to_hash
).
not_to
include
(
TEST1
:
'test-1'
)
end
end
end
spec/lib/gitlab/ci/yaml_processor_spec.rb
View file @
d609eaed
...
...
@@ -1311,6 +1311,14 @@ module Gitlab
Gitlab
::
Ci
::
YamlProcessor
.
new
(
config
)
end
.
to
raise_error
(
Gitlab
::
Ci
::
YamlProcessor
::
ValidationError
,
"jobs:rspec dependencies should be an array of strings"
)
end
it
'returns errors if pipeline variables expression is invalid'
do
config
=
YAML
.
dump
({
rspec:
{
script:
'test'
,
only:
{
variables:
[
'== null'
]
}
}
})
expect
{
Gitlab
::
Ci
::
YamlProcessor
.
new
(
config
)
}
.
to
raise_error
(
Gitlab
::
Ci
::
YamlProcessor
::
ValidationError
,
'jobs:rspec:only variables invalid expression syntax: equals null'
)
end
end
describe
"Validate configuration templates"
do
...
...
spec/models/ci/build_spec.rb
View file @
d609eaed
...
...
@@ -2019,6 +2019,92 @@ describe Ci::Build do
end
end
end
context
'when build has not been persisted yet'
do
let
(
:build
)
do
described_class
.
new
(
name:
'rspec'
,
stage:
'test'
,
ref:
'feature'
,
project:
project
,
pipeline:
pipeline
)
end
it
'returns static predefined variables'
do
expect
(
build
.
variables
.
size
).
to
be
>=
28
expect
(
build
.
variables
)
.
to
include
(
key:
'CI_COMMIT_REF_NAME'
,
value:
'feature'
,
public:
true
)
expect
(
build
).
not_to
be_persisted
end
end
end
describe
'#scoped_variables'
do
context
'when build has not been persisted yet'
do
let
(
:build
)
do
described_class
.
new
(
name:
'rspec'
,
stage:
'test'
,
ref:
'feature'
,
project:
project
,
pipeline:
pipeline
)
end
it
'does not persist the build'
do
expect
(
build
).
to
be_valid
expect
(
build
).
not_to
be_persisted
build
.
scoped_variables
expect
(
build
).
not_to
be_persisted
end
it
'returns static predefined variables'
do
keys
=
%w[CI_JOB_NAME
CI_COMMIT_SHA
CI_COMMIT_REF_NAME
CI_COMMIT_REF_SLUG
CI_JOB_STAGE]
variables
=
build
.
scoped_variables
variables
.
map
{
|
env
|
env
[
:key
]
}.
tap
do
|
names
|
expect
(
names
).
to
include
(
*
keys
)
end
expect
(
variables
)
.
to
include
(
key:
'CI_COMMIT_REF_NAME'
,
value:
'feature'
,
public:
true
)
end
it
'does not return prohibited variables'
do
keys
=
%w[CI_JOB_ID
CI_JOB_TOKEN
CI_BUILD_ID
CI_BUILD_TOKEN
CI_REGISTRY_USER
CI_REGISTRY_PASSWORD
CI_REPOSITORY_URL
CI_ENVIRONMENT_URL]
build
.
scoped_variables
.
map
{
|
env
|
env
[
:key
]
}.
tap
do
|
names
|
expect
(
names
).
not_to
include
(
*
keys
)
end
end
end
end
describe
'#variables_hash'
do
before
do
project
.
variables
.
create!
(
key:
'MY_VAR'
,
value:
'my value 1'
)
pipeline
.
variables
.
create!
(
key:
'MY_VAR'
,
value:
'my value 2'
)
end
it
'returns a regular hash created in valid order'
do
expect
(
build
.
variables_hash
).
to
include
(
'MY_VAR'
:
'my value 2'
)
expect
(
build
.
variables_hash
).
not_to
include
(
'MY_VAR'
:
'my value 1'
)
end
end
describe
'state transition: any => [:pending]'
do
...
...
spec/models/ci/pipeline_spec.rb
View file @
d609eaed
...
...
@@ -353,6 +353,20 @@ describe Ci::Pipeline, :mailer do
end
end
end
context
'when variables policy is specified'
do
let
(
:config
)
do
{
unit:
{
script:
'minitest'
,
only:
{
variables:
[
'$CI_PIPELINE_SOURCE'
]
}
},
feature:
{
script:
'spinach'
,
only:
{
variables:
[
'$UNDEFINED'
]
}
}
}
end
it
'returns stage seeds only when variables expression is truthy'
do
seeds
=
pipeline
.
stage_seeds
expect
(
seeds
.
size
).
to
eq
1
expect
(
seeds
.
dig
(
0
,
0
,
:name
)).
to
eq
'unit'
end
end
end
describe
'#seeds_size'
do
...
...
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