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
0
Merge Requests
0
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
Tatuya Kamada
gitlab-ce
Commits
0aa6061d
Commit
0aa6061d
authored
Oct 15, 2015
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement when syntax in .gitlab-ci.yml
parent
3d763907
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
279 additions
and
124 deletions
+279
-124
CHANGELOG
CHANGELOG
+1
-0
app/models/ci/build.rb
app/models/ci/build.rb
+1
-4
app/models/ci/commit.rb
app/models/ci/commit.rb
+17
-35
app/models/commit_status.rb
app/models/commit_status.rb
+1
-1
app/services/ci/create_builds_service.rb
app/services/ci/create_builds_service.rb
+13
-1
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+49
-0
lib/ci/gitlab_ci_yaml_processor.rb
lib/ci/gitlab_ci_yaml_processor.rb
+6
-1
lib/ci/status.rb
lib/ci/status.rb
+21
-0
spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+26
-2
spec/models/ci/commit_spec.rb
spec/models/ci/commit_spec.rb
+144
-80
No files found.
CHANGELOG
View file @
0aa6061d
...
@@ -22,6 +22,7 @@ v 8.1.0 (unreleased)
...
@@ -22,6 +22,7 @@ v 8.1.0 (unreleased)
- Add first and last to pagination (Zeger-Jan van de Weg)
- Add first and last to pagination (Zeger-Jan van de Weg)
- Added Commit Status API
- Added Commit Status API
- Added Builds View
- Added Builds View
- Added when to .gitlab-ci.yml
- Show CI status on commit page
- Show CI status on commit page
- Added CI_BUILD_TAG, _STAGE, _NAME and _TRIGGERED to CI builds
- Added CI_BUILD_TAG, _STAGE, _NAME and _TRIGGERED to CI builds
- Show CI status on Your projects page and Starred projects page
- Show CI status on Your projects page and Starred projects page
...
...
app/models/ci/build.rb
View file @
0aa6061d
...
@@ -93,10 +93,7 @@ module Ci
...
@@ -93,10 +93,7 @@ module Ci
Ci
::
WebHookService
.
new
.
build_end
(
build
)
Ci
::
WebHookService
.
new
.
build_end
(
build
)
end
end
if
build
.
commit
.
should_create_next_builds?
(
build
)
build
.
commit
.
create_next_builds
(
build
)
build
.
commit
.
create_next_builds
(
build
.
ref
,
build
.
tag
,
build
.
user
,
build
.
trigger_request
)
end
project
.
execute_services
(
build
)
project
.
execute_services
(
build
)
if
project
.
coverage_enabled?
if
project
.
coverage_enabled?
...
...
app/models/ci/commit.rb
View file @
0aa6061d
...
@@ -91,19 +91,28 @@ module Ci
...
@@ -91,19 +91,28 @@ module Ci
def
create_builds
(
ref
,
tag
,
user
,
trigger_request
=
nil
)
def
create_builds
(
ref
,
tag
,
user
,
trigger_request
=
nil
)
return
unless
config_processor
return
unless
config_processor
config_processor
.
stages
.
any?
do
|
stage
|
config_processor
.
stages
.
any?
do
|
stage
|
CreateBuildsService
.
new
.
execute
(
self
,
stage
,
ref
,
tag
,
user
,
trigger_request
).
present?
CreateBuildsService
.
new
.
execute
(
self
,
stage
,
ref
,
tag
,
user
,
trigger_request
,
'success'
).
present?
end
end
end
end
def
create_next_builds
(
ref
,
tag
,
user
,
trigger_request
)
def
create_next_builds
(
build
)
return
unless
config_processor
return
unless
config_processor
stages
=
builds
.
where
(
ref:
ref
,
tag:
tag
,
trigger_request:
trigger_request
).
group_by
(
&
:stage
)
# don't create other builds if this one is retried
latest_builds
=
builds
.
similar
(
build
).
latest
return
unless
latest_builds
.
exists?
(
build
.
id
)
config_processor
.
stages
.
any?
do
|
stage
|
# get list of stages after this build
unless
stages
.
include?
(
stage
)
next_stages
=
config_processor
.
stages
.
drop_while
{
|
stage
|
stage
!=
build
.
stage
}
CreateBuildsService
.
new
.
execute
(
self
,
stage
,
ref
,
tag
,
user
,
trigger_request
).
present?
next_stages
.
delete
(
build
.
stage
)
end
# get status for all prior builds
prior_builds
=
latest_builds
.
reject
{
|
other_build
|
next_stages
.
include?
(
other_build
.
stage
)
}
status
=
Ci
::
Status
.
get_status
(
prior_builds
)
# create builds for next stages based
next_stages
.
any?
do
|
stage
|
CreateBuildsService
.
new
.
execute
(
self
,
stage
,
build
.
ref
,
build
.
tag
,
build
.
user
,
build
.
trigger_request
,
status
).
present?
end
end
end
end
...
@@ -132,24 +141,7 @@ module Ci
...
@@ -132,24 +141,7 @@ module Ci
return
'failed'
return
'failed'
end
end
@status
||=
begin
@status
||=
Ci
::
Status
.
get_status
(
latest_statuses
)
latest
=
latest_statuses
latest
.
reject!
{
|
status
|
status
.
try
(
&
:allow_failure?
)
}
if
latest
.
none?
'skipped'
elsif
latest
.
all?
(
&
:success?
)
'success'
elsif
latest
.
all?
(
&
:pending?
)
'pending'
elsif
latest
.
any?
(
&
:running?
)
||
latest
.
any?
(
&
:pending?
)
'running'
elsif
latest
.
all?
(
&
:canceled?
)
'canceled'
else
'failed'
end
end
end
end
def
pending?
def
pending?
...
@@ -219,16 +211,6 @@ module Ci
...
@@ -219,16 +211,6 @@ module Ci
update!
(
committed_at:
DateTime
.
now
)
update!
(
committed_at:
DateTime
.
now
)
end
end
def
should_create_next_builds?
(
build
)
# don't create other builds if this one is retried
other_builds
=
builds
.
similar
(
build
).
latest
return
false
unless
other_builds
.
include?
(
build
)
other_builds
.
all?
do
|
build
|
build
.
success?
||
build
.
ignored?
end
end
private
private
def
save_yaml_error
(
error
)
def
save_yaml_error
(
error
)
...
...
app/models/commit_status.rb
View file @
0aa6061d
...
@@ -28,7 +28,7 @@ class CommitStatus < ActiveRecord::Base
...
@@ -28,7 +28,7 @@ class CommitStatus < ActiveRecord::Base
end
end
event
:drop
do
event
:drop
do
transition
running:
:failed
transition
[
:pending
,
:running
]
=>
:failed
end
end
event
:success
do
event
:success
do
...
...
app/services/ci/create_builds_service.rb
View file @
0aa6061d
module
Ci
module
Ci
class
CreateBuildsService
class
CreateBuildsService
def
execute
(
commit
,
stage
,
ref
,
tag
,
user
,
trigger_request
)
def
execute
(
commit
,
stage
,
ref
,
tag
,
user
,
trigger_request
,
status
)
builds_attrs
=
commit
.
config_processor
.
builds_for_stage_and_ref
(
stage
,
ref
,
tag
)
builds_attrs
=
commit
.
config_processor
.
builds_for_stage_and_ref
(
stage
,
ref
,
tag
)
# check when to create next build
builds_attrs
=
builds_attrs
.
select
do
|
build_attrs
|
case
build_attrs
[
:when
]
when
'on_success'
status
==
'success'
when
'on_failure'
status
==
'failed'
when
'always'
%w(success failed)
.
include?
(
status
)
end
end
builds_attrs
.
map
do
|
build_attrs
|
builds_attrs
.
map
do
|
build_attrs
|
# don't create the same build twice
# don't create the same build twice
unless
commit
.
builds
.
find_by
(
ref:
ref
,
tag:
tag
,
trigger_request:
trigger_request
,
name:
build_attrs
[
:name
])
unless
commit
.
builds
.
find_by
(
ref:
ref
,
tag:
tag
,
trigger_request:
trigger_request
,
name:
build_attrs
[
:name
])
...
...
doc/ci/yaml/README.md
View file @
0aa6061d
...
@@ -140,6 +140,7 @@ job_name:
...
@@ -140,6 +140,7 @@ job_name:
| except | optional | Defines a list of git refs for which build is not created |
| except | optional | Defines a list of git refs for which build is not created |
| tags | optional | Defines a list of tags which are used to select runner |
| tags | optional | Defines a list of tags which are used to select runner |
| 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 |
### 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`
.
...
@@ -196,6 +197,54 @@ job:
...
@@ -196,6 +197,54 @@ job:
The above specification will make sure that
`job`
is built by a runner that have
`ruby`
AND
`postgres`
tags defined.
The above specification will make sure that
`job`
is built by a runner that have
`ruby`
AND
`postgres`
tags defined.
### when
`when`
is used to implement jobs that are run in case of failure or despite the failure.
The
`when`
can be set to one of the following values:
1.
`on_success`
- execute build only when all builds from prior stages succeeded. This is default.
1.
`on_failure`
- execute build only when at least one of the build from prior stages failed.
1.
`always`
- execute build despite the status of builds from prior stages.
```
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
build:
stage: build
script:
- make build
cleanup_build:
stage: cleanup_build
script:
- cleanup build when failed
when: on_failure
test:
stage: test
script:
- make test
deploy:
stage: deploy
script:
- make deploy
cleanup:
stage: cleanup
script:
- cleanup after builds
when: always
```
The above script will:
1.
Execute
`cleanup_build`
only when the
`build`
failed,
2.
Always execute
`cleanup`
as the last step in pipeline.
## 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`
.
...
...
lib/ci/gitlab_ci_yaml_processor.rb
View file @
0aa6061d
...
@@ -5,7 +5,7 @@ module Ci
...
@@ -5,7 +5,7 @@ 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
]
ALLOWED_JOB_KEYS
=
[
:tags
,
:script
,
:only
,
:except
,
:type
,
:image
,
:services
,
:allow_failure
,
:type
,
:stage
]
ALLOWED_JOB_KEYS
=
[
:tags
,
:script
,
:only
,
:except
,
:type
,
:image
,
:services
,
:allow_failure
,
:type
,
:stage
,
:when
]
attr_reader
:before_script
,
:image
,
:services
,
:variables
attr_reader
:before_script
,
:image
,
:services
,
:variables
...
@@ -93,6 +93,7 @@ module Ci
...
@@ -93,6 +93,7 @@ module Ci
only:
job
[
:only
],
only:
job
[
:only
],
except:
job
[
:except
],
except:
job
[
:except
],
allow_failure:
job
[
:allow_failure
]
||
false
,
allow_failure:
job
[
:allow_failure
]
||
false
,
when:
job
[
:when
]
||
'on_success'
,
options:
{
options:
{
image:
job
[
:image
]
||
@image
,
image:
job
[
:image
]
||
@image
,
services:
job
[
:services
]
||
@services
services:
job
[
:services
]
||
@services
...
@@ -184,6 +185,10 @@ module Ci
...
@@ -184,6 +185,10 @@ module Ci
if
job
[
:allow_failure
]
&&
!
job
[
:allow_failure
].
in?
([
true
,
false
])
if
job
[
:allow_failure
]
&&
!
job
[
:allow_failure
].
in?
([
true
,
false
])
raise
ValidationError
,
"
#{
name
}
: allow_failure parameter should be an boolean"
raise
ValidationError
,
"
#{
name
}
: allow_failure parameter should be an boolean"
end
end
if
job
[
:when
]
&&
!
job
[
:when
].
in?
(
%w(on_success on_failure always)
)
raise
ValidationError
,
"
#{
name
}
: when should be on_success, on_failure or always"
end
end
end
private
private
...
...
lib/ci/status.rb
0 → 100644
View file @
0aa6061d
module
Ci
class
Status
def
self
.
get_status
(
statuses
)
statuses
.
reject!
{
|
status
|
status
.
try
(
&
:allow_failure?
)
}
if
statuses
.
none?
'skipped'
elsif
statuses
.
all?
(
&
:success?
)
'success'
elsif
statuses
.
all?
(
&
:pending?
)
'pending'
elsif
statuses
.
any?
(
&
:running?
)
||
statuses
.
any?
(
&
:pending?
)
'running'
elsif
statuses
.
all?
(
&
:canceled?
)
'canceled'
else
'failed'
end
end
end
end
\ No newline at end of file
spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
View file @
0aa6061d
...
@@ -125,7 +125,8 @@ module Ci
...
@@ -125,7 +125,8 @@ module Ci
image:
"ruby:2.1"
,
image:
"ruby:2.1"
,
services:
[
"mysql"
]
services:
[
"mysql"
]
},
},
allow_failure:
false
allow_failure:
false
,
when:
"on_success"
})
})
end
end
...
@@ -152,7 +153,8 @@ module Ci
...
@@ -152,7 +153,8 @@ module Ci
image:
"ruby:2.5"
,
image:
"ruby:2.5"
,
services:
[
"postgresql"
]
services:
[
"postgresql"
]
},
},
allow_failure:
false
allow_failure:
false
,
when:
"on_success"
})
})
end
end
end
end
...
@@ -174,6 +176,21 @@ module Ci
...
@@ -174,6 +176,21 @@ module Ci
end
end
end
end
describe
"When"
do
%w(on_success on_failure always)
.
each
do
|
when_state
|
it
"returns
#{
when_state
}
when defined"
do
config
=
YAML
.
dump
({
rspec:
{
script:
"rspec"
,
when:
when_state
}
})
config_processor
=
GitlabCiYamlProcessor
.
new
(
config
)
builds
=
config_processor
.
builds_for_stage_and_ref
(
"test"
,
"master"
)
expect
(
builds
.
size
).
to
eq
(
1
)
expect
(
builds
.
first
[
:when
]).
to
eq
(
when_state
)
end
end
end
describe
"Error handling"
do
describe
"Error handling"
do
it
"indicates that object is invalid"
do
it
"indicates that object is invalid"
do
expect
{
GitlabCiYamlProcessor
.
new
(
"invalid_yaml
\n
!ccdvlf%612334@@@@"
)}.
to
raise_error
(
GitlabCiYamlProcessor
::
ValidationError
)
expect
{
GitlabCiYamlProcessor
.
new
(
"invalid_yaml
\n
!ccdvlf%612334@@@@"
)}.
to
raise_error
(
GitlabCiYamlProcessor
::
ValidationError
)
...
@@ -311,6 +328,13 @@ module Ci
...
@@ -311,6 +328,13 @@ module Ci
GitlabCiYamlProcessor
.
new
(
config
)
GitlabCiYamlProcessor
.
new
(
config
)
end
.
to
raise_error
(
GitlabCiYamlProcessor
::
ValidationError
,
"variables should be a map of key-valued strings"
)
end
.
to
raise_error
(
GitlabCiYamlProcessor
::
ValidationError
,
"variables should be a map of key-valued strings"
)
end
end
it
"returns errors if job when is not on_success, on_failure or always"
do
config
=
YAML
.
dump
({
rspec:
{
script:
"test"
,
when:
false
}
})
expect
do
GitlabCiYamlProcessor
.
new
(
config
)
end
.
to
raise_error
(
GitlabCiYamlProcessor
::
ValidationError
,
"rspec job: when parameter should be on_success, on_failure or always"
)
end
end
end
end
end
end
end
spec/models/ci/commit_spec.rb
View file @
0aa6061d
This diff is collapsed.
Click to expand it.
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