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
6a6a69f4
Commit
6a6a69f4
authored
Aug 11, 2016
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use state machine for pipeline event processing
parent
d983c5bd
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
54 additions
and
71 deletions
+54
-71
app/models/ci/pipeline.rb
app/models/ci/pipeline.rb
+43
-18
app/models/commit_status.rb
app/models/commit_status.rb
+4
-4
app/services/ci/create_pipeline_service.rb
app/services/ci/create_pipeline_service.rb
+3
-2
features/steps/shared/builds.rb
features/steps/shared/builds.rb
+0
-2
spec/features/pipelines_spec.rb
spec/features/pipelines_spec.rb
+0
-4
spec/lib/ci/charts_spec.rb
spec/lib/ci/charts_spec.rb
+0
-1
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+4
-34
spec/requests/api/builds_spec.rb
spec/requests/api/builds_spec.rb
+0
-4
spec/services/ci/image_for_build_service_spec.rb
spec/services/ci/image_for_build_service_spec.rb
+0
-2
No files found.
app/models/ci/pipeline.rb
View file @
6a6a69f4
...
@@ -19,6 +19,37 @@ module Ci
...
@@ -19,6 +19,37 @@ module Ci
after_save
:keep_around_commits
after_save
:keep_around_commits
state_machine
:status
,
initial: :created
do
event
:skip
do
transition
any
=>
:skipped
end
event
:drop
do
transition
any
=>
:failed
end
event
:update_status
do
transition
any
=>
:pending
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'pending'
)
}
transition
any
=>
:running
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'running'
)
}
transition
any
=>
:failed
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'failed'
)
}
transition
any
=>
:success
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'success'
)
}
transition
any
=>
:canceled
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'canceled'
)
}
transition
any
=>
:skipped
,
if:
->
(
pipeline
)
{
pipeline
.
can_transition_to?
(
'skipped'
)
}
end
after_transition
[
:created
,
:pending
]
=>
:running
do
|
pipeline
|
pipeline
.
update
(
started_at:
Time
.
now
)
end
after_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
pipeline
|
pipeline
.
update
(
finished_at:
Time
.
now
)
end
after_transition
do
|
pipeline
|
pipeline
.
update_duration
end
end
# ref can't be HEAD or SHA, can only be branch/tag name
# ref can't be HEAD or SHA, can only be branch/tag name
scope
:latest_successful_for
,
->
(
ref
=
default_branch
)
do
scope
:latest_successful_for
,
->
(
ref
=
default_branch
)
do
where
(
ref:
ref
).
success
.
order
(
id: :desc
).
limit
(
1
)
where
(
ref:
ref
).
success
.
order
(
id: :desc
).
limit
(
1
)
...
@@ -89,16 +120,12 @@ module Ci
...
@@ -89,16 +120,12 @@ module Ci
def
cancel_running
def
cancel_running
builds
.
running_or_pending
.
each
(
&
:cancel
)
builds
.
running_or_pending
.
each
(
&
:cancel
)
reload_status!
end
end
def
retry_failed
(
user
)
def
retry_failed
(
user
)
builds
.
latest
.
failed
.
select
(
&
:retryable?
).
each
do
|
build
|
builds
.
latest
.
failed
.
select
(
&
:retryable?
).
each
do
|
build
|
Ci
::
Build
.
retry
(
build
,
user
)
Ci
::
Build
.
retry
(
build
,
user
)
end
end
reload_status!
end
end
def
latest?
def
latest?
...
@@ -185,8 +212,6 @@ module Ci
...
@@ -185,8 +212,6 @@ module Ci
def
process!
def
process!
Ci
::
ProcessPipelineService
.
new
(
project
,
user
).
execute
(
self
)
Ci
::
ProcessPipelineService
.
new
(
project
,
user
).
execute
(
self
)
reload_status!
end
end
def
predefined_variables
def
predefined_variables
...
@@ -195,22 +220,22 @@ module Ci
...
@@ -195,22 +220,22 @@ module Ci
]
]
end
end
def
reload_status!
def
can_transition_to?
(
expected_status
)
reload
latest_status
==
expected_status
self
.
status
=
end
if
yaml_errors
.
blank?
statuses
.
latest
.
status
||
'skipped'
def
update_duration
else
update
(
duration:
statuses
.
latest
.
duration
)
'failed'
end
self
.
started_at
=
statuses
.
started_at
self
.
finished_at
=
statuses
.
finished_at
self
.
duration
=
statuses
.
latest
.
duration
save
end
end
private
private
def
latest_status
return
'failed'
unless
yaml_errors
.
blank?
statuses
.
latest
.
status
||
'skipped'
end
def
keep_around_commits
def
keep_around_commits
return
unless
project
return
unless
project
...
...
app/models/commit_status.rb
View file @
6a6a69f4
...
@@ -74,13 +74,13 @@ class CommitStatus < ActiveRecord::Base
...
@@ -74,13 +74,13 @@ class CommitStatus < ActiveRecord::Base
around_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
commit_status
,
block
|
around_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
commit_status
,
block
|
block
.
call
block
.
call
commit_status
.
pipeline
.
process!
if
commit_status
.
pipeline
commit_status
.
pipeline
.
try
(
:process!
)
end
end
around_transition
any
=>
[
:pending
,
:running
]
do
|
commit_status
,
block
|
# Try to update the pipeline status
block
.
call
commit_status
.
pipeline
.
reload_status!
if
commit_status
.
pipeline
after_transition
do
|
commit_status
,
transition
|
commit_status
.
pipeline
.
try
(
:update_status
)
unless
transition
.
loopback?
end
end
end
end
...
...
app/services/ci/create_pipeline_service.rb
View file @
6a6a69f4
...
@@ -37,7 +37,8 @@ module Ci
...
@@ -37,7 +37,8 @@ module Ci
end
end
if
!
ignore_skip_ci
&&
skip_ci?
if
!
ignore_skip_ci
&&
skip_ci?
return
error
(
'Creation of pipeline is skipped'
,
save:
save_on_errors
)
pipeline
.
skip
if
save_on_errors
return
pipeline
end
end
unless
pipeline
.
config_builds_attributes
.
present?
unless
pipeline
.
config_builds_attributes
.
present?
...
@@ -93,7 +94,7 @@ module Ci
...
@@ -93,7 +94,7 @@ module Ci
def
error
(
message
,
save:
false
)
def
error
(
message
,
save:
false
)
pipeline
.
errors
.
add
(
:base
,
message
)
pipeline
.
errors
.
add
(
:base
,
message
)
pipeline
.
reload_status!
if
save
pipeline
.
drop
if
save
pipeline
pipeline
end
end
end
end
...
...
features/steps/shared/builds.rb
View file @
6a6a69f4
...
@@ -12,7 +12,6 @@ module SharedBuilds
...
@@ -12,7 +12,6 @@ module SharedBuilds
step
'project has a recent build'
do
step
'project has a recent build'
do
@pipeline
=
create
(
:ci_empty_pipeline
,
project:
@project
,
sha:
@project
.
commit
.
sha
,
ref:
'master'
)
@pipeline
=
create
(
:ci_empty_pipeline
,
project:
@project
,
sha:
@project
.
commit
.
sha
,
ref:
'master'
)
@build
=
create
(
:ci_build_with_coverage
,
pipeline:
@pipeline
)
@build
=
create
(
:ci_build_with_coverage
,
pipeline:
@pipeline
)
@pipeline
.
reload_status!
end
end
step
'recent build is successful'
do
step
'recent build is successful'
do
...
@@ -25,7 +24,6 @@ module SharedBuilds
...
@@ -25,7 +24,6 @@ module SharedBuilds
step
'project has another build that is running'
do
step
'project has another build that is running'
do
create
(
:ci_build
,
pipeline:
@pipeline
,
name:
'second build'
,
status:
'running'
)
create
(
:ci_build
,
pipeline:
@pipeline
,
name:
'second build'
,
status:
'running'
)
@pipeline
.
reload_status!
end
end
step
'I visit recent build details page'
do
step
'I visit recent build details page'
do
...
...
spec/features/pipelines_spec.rb
View file @
6a6a69f4
...
@@ -34,7 +34,6 @@ describe "Pipelines" do
...
@@ -34,7 +34,6 @@ describe "Pipelines" do
let!
(
:running
)
{
create
(
:ci_build
,
:running
,
pipeline:
pipeline
,
stage:
'test'
,
commands:
'test'
)
}
let!
(
:running
)
{
create
(
:ci_build
,
:running
,
pipeline:
pipeline
,
stage:
'test'
,
commands:
'test'
)
}
before
do
before
do
pipeline
.
reload_status!
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
end
end
...
@@ -53,7 +52,6 @@ describe "Pipelines" do
...
@@ -53,7 +52,6 @@ describe "Pipelines" do
let!
(
:failed
)
{
create
(
:ci_build
,
:failed
,
pipeline:
pipeline
,
stage:
'test'
,
commands:
'test'
)
}
let!
(
:failed
)
{
create
(
:ci_build
,
:failed
,
pipeline:
pipeline
,
stage:
'test'
,
commands:
'test'
)
}
before
do
before
do
pipeline
.
reload_status!
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
end
end
...
@@ -87,7 +85,6 @@ describe "Pipelines" do
...
@@ -87,7 +85,6 @@ describe "Pipelines" do
let!
(
:running
)
{
create
(
:generic_commit_status
,
status:
'running'
,
pipeline:
pipeline
,
stage:
'test'
)
}
let!
(
:running
)
{
create
(
:generic_commit_status
,
status:
'running'
,
pipeline:
pipeline
,
stage:
'test'
)
}
before
do
before
do
pipeline
.
reload_status!
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
end
end
...
@@ -104,7 +101,6 @@ describe "Pipelines" do
...
@@ -104,7 +101,6 @@ describe "Pipelines" do
let!
(
:failed
)
{
create
(
:generic_commit_status
,
status:
'failed'
,
pipeline:
pipeline
,
stage:
'test'
)
}
let!
(
:failed
)
{
create
(
:generic_commit_status
,
status:
'failed'
,
pipeline:
pipeline
,
stage:
'test'
)
}
before
do
before
do
pipeline
.
reload_status!
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
visit
namespace_project_pipelines_path
(
project
.
namespace
,
project
)
end
end
...
...
spec/lib/ci/charts_spec.rb
View file @
6a6a69f4
...
@@ -5,7 +5,6 @@ describe Ci::Charts, lib: true do
...
@@ -5,7 +5,6 @@ describe Ci::Charts, lib: true do
before
do
before
do
@pipeline
=
FactoryGirl
.
create
(
:ci_pipeline
)
@pipeline
=
FactoryGirl
.
create
(
:ci_pipeline
)
FactoryGirl
.
create
(
:ci_build
,
pipeline:
@pipeline
)
FactoryGirl
.
create
(
:ci_build
,
pipeline:
@pipeline
)
@pipeline
.
reload_status!
end
end
it
'returns build times in minutes'
do
it
'returns build times in minutes'
do
...
...
spec/models/ci/pipeline_spec.rb
View file @
6a6a69f4
...
@@ -2,7 +2,7 @@ require 'spec_helper'
...
@@ -2,7 +2,7 @@ require 'spec_helper'
describe
Ci
::
Pipeline
,
models:
true
do
describe
Ci
::
Pipeline
,
models:
true
do
let
(
:project
)
{
FactoryGirl
.
create
:empty_project
}
let
(
:project
)
{
FactoryGirl
.
create
:empty_project
}
let
(
:pipeline
)
{
FactoryGirl
.
create
:ci_pipeline
,
project:
project
}
let
(
:pipeline
)
{
FactoryGirl
.
create
:ci_
empty_
pipeline
,
project:
project
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:user
)
}
it
{
is_expected
.
to
belong_to
(
:user
)
}
...
@@ -51,25 +51,6 @@ describe Ci::Pipeline, models: true do
...
@@ -51,25 +51,6 @@ describe Ci::Pipeline, models: true do
end
end
end
end
describe
"#finished_at"
do
let
(
:pipeline
)
{
FactoryGirl
.
create
:ci_pipeline
}
it
"returns finished_at of latest build"
do
build
=
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
,
finished_at:
Time
.
now
-
60
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
,
finished_at:
Time
.
now
-
120
pipeline
.
reload_status!
expect
(
pipeline
.
finished_at
.
to_i
).
to
eq
(
build
.
finished_at
.
to_i
)
end
it
"returns nil if there is no finished build"
do
FactoryGirl
.
create
:ci_not_started_build
,
pipeline:
pipeline
pipeline
.
reload_status!
expect
(
pipeline
.
finished_at
).
to
be_nil
end
end
describe
"coverage"
do
describe
"coverage"
do
let
(
:project
)
{
FactoryGirl
.
create
:empty_project
,
build_coverage_regex:
"/.*/"
}
let
(
:project
)
{
FactoryGirl
.
create
:empty_project
,
build_coverage_regex:
"/.*/"
}
let
(
:pipeline
)
{
FactoryGirl
.
create
:ci_empty_pipeline
,
project:
project
}
let
(
:pipeline
)
{
FactoryGirl
.
create
:ci_empty_pipeline
,
project:
project
}
...
@@ -139,31 +120,20 @@ describe Ci::Pipeline, models: true do
...
@@ -139,31 +120,20 @@ describe Ci::Pipeline, models: true do
end
end
end
end
describe
'#
reload_status!
'
do
describe
'#
update_counters
'
do
let
(
:pipeline
)
{
create
:ci_empty_pipeline
,
project:
project
}
let
(
:pipeline
)
{
create
:ci_empty_pipeline
,
project:
project
}
context
'dependent objects'
do
let
(
:commit_status
)
{
create
:commit_status
,
:pending
,
pipeline:
pipeline
}
it
'executes reload_status! after succeeding dependent object'
do
expect
(
pipeline
).
to
receive
(
:reload_status!
).
and_return
(
true
)
commit_status
.
success
end
end
context
'updates'
do
context
'updates'
do
let
(
:current
)
{
Time
.
now
.
change
(
usec:
0
)
}
let
(
:current
)
{
Time
.
now
.
change
(
usec:
0
)
}
let
(
:build
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
,
started_at:
current
-
120
,
finished_at:
current
-
60
}
let
(
:build
)
{
FactoryGirl
.
create
:ci_build
,
pipeline:
pipeline
,
started_at:
current
-
120
,
finished_at:
current
-
60
}
before
do
before
do
build
build
.
skip
pipeline
.
reload_status!
end
end
[
:status
,
:started_at
,
:finished_at
,
:duration
].
each
do
|
param
|
[
:status
,
:started_at
,
:finished_at
,
:duration
].
each
do
|
param
|
it
"
#{
param
}
"
do
it
"
#{
param
}
"
do
expect
(
pipeline
.
send
(
param
)).
to
eq
(
build
.
send
(
param
))
expect
(
pipeline
.
reload
.
send
(
param
)).
to
eq
(
build
.
send
(
param
))
end
end
end
end
end
end
...
...
spec/requests/api/builds_spec.rb
View file @
6a6a69f4
...
@@ -238,10 +238,6 @@ describe API::API, api: true do
...
@@ -238,10 +238,6 @@ describe API::API, api: true do
it
{
expect
(
response
.
headers
).
to
include
(
download_headers
)
}
it
{
expect
(
response
.
headers
).
to
include
(
download_headers
)
}
end
end
before
do
pipeline
.
reload_status!
end
context
'with regular branch'
do
context
'with regular branch'
do
before
do
before
do
pipeline
.
update
(
ref:
'master'
,
pipeline
.
update
(
ref:
'master'
,
...
...
spec/services/ci/image_for_build_service_spec.rb
View file @
6a6a69f4
...
@@ -14,7 +14,6 @@ module Ci
...
@@ -14,7 +14,6 @@ module Ci
context
'branch name'
do
context
'branch name'
do
before
{
allow
(
project
).
to
receive
(
:commit
).
and_return
(
OpenStruct
.
new
(
sha:
commit_sha
))
}
before
{
allow
(
project
).
to
receive
(
:commit
).
and_return
(
OpenStruct
.
new
(
sha:
commit_sha
))
}
before
{
build
.
run!
}
before
{
build
.
run!
}
before
{
pipeline
.
reload_status!
}
let
(
:image
)
{
service
.
execute
(
project
,
ref:
'master'
)
}
let
(
:image
)
{
service
.
execute
(
project
,
ref:
'master'
)
}
it
{
expect
(
image
).
to
be_kind_of
(
OpenStruct
)
}
it
{
expect
(
image
).
to
be_kind_of
(
OpenStruct
)
}
...
@@ -32,7 +31,6 @@ module Ci
...
@@ -32,7 +31,6 @@ module Ci
context
'commit sha'
do
context
'commit sha'
do
before
{
build
.
run!
}
before
{
build
.
run!
}
before
{
pipeline
.
reload_status!
}
let
(
:image
)
{
service
.
execute
(
project
,
sha:
build
.
sha
)
}
let
(
:image
)
{
service
.
execute
(
project
,
sha:
build
.
sha
)
}
it
{
expect
(
image
).
to
be_kind_of
(
OpenStruct
)
}
it
{
expect
(
image
).
to
be_kind_of
(
OpenStruct
)
}
...
...
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