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
b4847c73
Commit
b4847c73
authored
Nov 29, 2019
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ci Resouce Group status transition
This commit supports Ci Resource Group status transition
parent
9f852c5a
Changes
40
Hide whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
626 additions
and
54 deletions
+626
-54
app/assets/stylesheets/framework/icons.scss
app/assets/stylesheets/framework/icons.scss
+1
-0
app/assets/stylesheets/pages/pipelines.scss
app/assets/stylesheets/pages/pipelines.scss
+1
-0
app/assets/stylesheets/pages/status.scss
app/assets/stylesheets/pages/status.scss
+1
-0
app/helpers/ci_status_helper.rb
app/helpers/ci_status_helper.rb
+4
-0
app/models/ci/build.rb
app/models/ci/build.rb
+54
-8
app/models/ci/pipeline.rb
app/models/ci/pipeline.rb
+10
-5
app/models/ci/stage.rb
app/models/ci/stage.rb
+6
-1
app/models/commit_status.rb
app/models/commit_status.rb
+14
-6
app/models/concerns/has_status.rb
app/models/concerns/has_status.rb
+10
-6
app/services/ci/prepare_build_service.rb
app/services/ci/prepare_build_service.rb
+1
-1
app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb
...rce_groups/assign_resource_from_resource_group_service.rb
+17
-0
app/workers/all_queues.yml
app/workers/all_queues.yml
+1
-0
app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb
...urce_groups/assign_resource_from_resource_group_worker.rb
+20
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+3
-1
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+7
-1
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+1
-1
lib/gitlab/ci/status/build/factory.rb
lib/gitlab/ci/status/build/factory.rb
+1
-0
lib/gitlab/ci/status/build/waiting_for_resource.rb
lib/gitlab/ci/status/build/waiting_for_resource.rb
+27
-0
lib/gitlab/ci/status/composite.rb
lib/gitlab/ci/status/composite.rb
+6
-0
lib/gitlab/ci/status/factory.rb
lib/gitlab/ci/status/factory.rb
+1
-1
lib/gitlab/ci/status/waiting_for_resource.rb
lib/gitlab/ci/status/waiting_for_resource.rb
+29
-0
locale/gitlab.pot
locale/gitlab.pot
+9
-0
spec/factories/ci/builds.rb
spec/factories/ci/builds.rb
+4
-0
spec/factories/commit_statuses.rb
spec/factories/commit_statuses.rb
+4
-0
spec/features/projects/pipelines/pipeline_spec.rb
spec/features/projects/pipelines/pipeline_spec.rb
+111
-0
spec/lib/gitlab/ci/status/external/factory_spec.rb
spec/lib/gitlab/ci/status/external/factory_spec.rb
+1
-1
spec/lib/gitlab/ci/status/factory_spec.rb
spec/lib/gitlab/ci/status/factory_spec.rb
+1
-1
spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
+1
-1
spec/lib/gitlab/ci/status/stage/factory_spec.rb
spec/lib/gitlab/ci/status/stage/factory_spec.rb
+1
-1
spec/lib/gitlab/ci/status/waiting_for_resource_spec.rb
spec/lib/gitlab/ci/status/waiting_for_resource_spec.rb
+29
-0
spec/models/ci/build_spec.rb
spec/models/ci/build_spec.rb
+54
-0
spec/models/ci/pipeline_spec.rb
spec/models/ci/pipeline_spec.rb
+12
-1
spec/models/ci/stage_spec.rb
spec/models/ci/stage_spec.rb
+12
-0
spec/models/commit_status_spec.rb
spec/models/commit_status_spec.rb
+24
-6
spec/models/concerns/has_status_spec.rb
spec/models/concerns/has_status_spec.rb
+20
-4
spec/services/ci/prepare_build_service_spec.rb
spec/services/ci/prepare_build_service_spec.rb
+2
-2
spec/services/ci/process_pipeline_service_spec.rb
spec/services/ci/process_pipeline_service_spec.rb
+16
-6
spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb
...roups/assign_resource_from_resource_group_service_spec.rb
+64
-0
spec/services/ci/run_scheduled_build_service_spec.rb
spec/services/ci/run_scheduled_build_service_spec.rb
+12
-0
spec/workers/ci/resource_groups/assign_resource_from_resource_group_worker_spec.rb
...groups/assign_resource_from_resource_group_worker_spec.rb
+34
-0
No files found.
app/assets/stylesheets/framework/icons.scss
View file @
b4847c73
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
}
}
.ci-status-icon-pending
,
.ci-status-icon-pending
,
.ci-status-icon-waiting-for-resource
,
.ci-status-icon-failed-with-warnings
,
.ci-status-icon-failed-with-warnings
,
.ci-status-icon-success-with-warnings
{
.ci-status-icon-success-with-warnings
{
svg
{
svg
{
...
...
app/assets/stylesheets/pages/pipelines.scss
View file @
b4847c73
...
@@ -795,6 +795,7 @@
...
@@ -795,6 +795,7 @@
}
}
&
.ci-status-icon-pending
,
&
.ci-status-icon-pending
,
&
.ci-status-icon-waiting-for-resource
,
&
.ci-status-icon-success-with-warnings
{
&
.ci-status-icon-success-with-warnings
{
@include
mini-pipeline-graph-color
(
$white
,
$orange-100
,
$orange-200
,
$orange-500
,
$orange-600
,
$orange-700
);
@include
mini-pipeline-graph-color
(
$white
,
$orange-100
,
$orange-200
,
$orange-500
,
$orange-600
,
$orange-700
);
}
}
...
...
app/assets/stylesheets/pages/status.scss
View file @
b4847c73
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
}
}
&
.ci-pending
,
&
.ci-pending
,
&
.ci-waiting-for-resource
,
&
.ci-failed-with-warnings
,
&
.ci-failed-with-warnings
,
&
.ci-success-with-warnings
{
&
.ci-success-with-warnings
{
@include
status-color
(
$orange-100
,
$orange-500
,
$orange-700
);
@include
status-color
(
$orange-100
,
$orange-500
,
$orange-700
);
...
...
app/helpers/ci_status_helper.rb
View file @
b4847c73
...
@@ -62,6 +62,7 @@ module CiStatusHelper
...
@@ -62,6 +62,7 @@ module CiStatusHelper
status
.
humanize
status
.
humanize
end
end
# rubocop:disable Metrics/CyclomaticComplexity
def
ci_icon_for_status
(
status
,
size:
16
)
def
ci_icon_for_status
(
status
,
size:
16
)
if
detailed_status?
(
status
)
if
detailed_status?
(
status
)
return
sprite_icon
(
status
.
icon
,
size:
size
)
return
sprite_icon
(
status
.
icon
,
size:
size
)
...
@@ -77,6 +78,8 @@ module CiStatusHelper
...
@@ -77,6 +78,8 @@ module CiStatusHelper
'status_failed'
'status_failed'
when
'pending'
when
'pending'
'status_pending'
'status_pending'
when
'waiting_for_resource'
'status_pending'
when
'preparing'
when
'preparing'
'status_preparing'
'status_preparing'
when
'running'
when
'running'
...
@@ -97,6 +100,7 @@ module CiStatusHelper
...
@@ -97,6 +100,7 @@ module CiStatusHelper
sprite_icon
(
icon_name
,
size:
size
)
sprite_icon
(
icon_name
,
size:
size
)
end
end
# rubocop:enable Metrics/CyclomaticComplexity
def
ci_icon_class_for_status
(
status
)
def
ci_icon_class_for_status
(
status
)
group
=
detailed_status?
(
status
)
?
status
.
group
:
status
.
dasherize
group
=
detailed_status?
(
status
)
?
status
.
group
:
status
.
dasherize
...
...
app/models/ci/build.rb
View file @
b4847c73
...
@@ -206,9 +206,25 @@ module Ci
...
@@ -206,9 +206,25 @@ module Ci
state_machine
:status
do
state_machine
:status
do
event
:enqueue
do
event
:enqueue
do
transition
[
:created
,
:skipped
,
:manual
,
:scheduled
]
=>
:waiting_for_resource
,
if: :requires_resource?
transition
[
:created
,
:skipped
,
:manual
,
:scheduled
]
=>
:preparing
,
if: :any_unmet_prerequisites?
transition
[
:created
,
:skipped
,
:manual
,
:scheduled
]
=>
:preparing
,
if: :any_unmet_prerequisites?
end
end
event
:enqueue_scheduled
do
transition
scheduled: :waiting_for_resource
,
if: :requires_resource?
transition
scheduled: :preparing
,
if: :any_unmet_prerequisites?
transition
scheduled: :pending
end
event
:enqueue_waiting_for_resource
do
transition
waiting_for_resource: :preparing
,
if: :any_unmet_prerequisites?
transition
waiting_for_resource: :pending
end
event
:enqueue_preparing
do
transition
preparing: :pending
end
event
:actionize
do
event
:actionize
do
transition
created: :manual
transition
created: :manual
end
end
...
@@ -221,14 +237,8 @@ module Ci
...
@@ -221,14 +237,8 @@ module Ci
transition
scheduled: :manual
transition
scheduled: :manual
end
end
event
:enqueue_scheduled
do
before_transition
on: :enqueue_scheduled
do
|
build
|
transition
scheduled: :preparing
,
if:
->
(
build
)
do
build
.
scheduled_at
.
nil?
||
build
.
scheduled_at
.
past?
# If false is returned, it stops the transition
build
.
scheduled_at
&
.
past?
&&
build
.
any_unmet_prerequisites?
end
transition
scheduled: :pending
,
if:
->
(
build
)
do
build
.
scheduled_at
&
.
past?
&&
!
build
.
any_unmet_prerequisites?
end
end
end
before_transition
scheduled:
any
do
|
build
|
before_transition
scheduled:
any
do
|
build
|
...
@@ -239,6 +249,27 @@ module Ci
...
@@ -239,6 +249,27 @@ module Ci
build
.
scheduled_at
=
build
.
options_scheduled_at
build
.
scheduled_at
=
build
.
options_scheduled_at
end
end
before_transition
any
=>
:waiting_for_resource
do
|
build
|
build
.
waiting_for_resource_at
=
Time
.
now
end
before_transition
on: :enqueue_waiting_for_resource
do
|
build
|
next
unless
build
.
requires_resource?
build
.
resource_group
.
assign_resource_to
(
build
)
# If false is returned, it stops the transition
end
after_transition
any
=>
:waiting_for_resource
do
|
build
|
build
.
run_after_commit
do
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
.
perform_async
(
build
.
resource_group_id
)
end
end
before_transition
on: :enqueue_preparing
do
|
build
|
build
.
any_unmet_prerequisites?
# If false is returned, it stops the transition
end
after_transition
created: :scheduled
do
|
build
|
after_transition
created: :scheduled
do
|
build
|
build
.
run_after_commit
do
build
.
run_after_commit
do
Ci
::
BuildScheduleWorker
.
perform_at
(
build
.
scheduled_at
,
build
.
id
)
Ci
::
BuildScheduleWorker
.
perform_at
(
build
.
scheduled_at
,
build
.
id
)
...
@@ -267,6 +298,16 @@ module Ci
...
@@ -267,6 +298,16 @@ module Ci
end
end
end
end
after_transition
any
=>
::
Ci
::
Build
.
completed_statuses
do
|
build
|
next
unless
build
.
resource_group_id
.
present?
next
unless
build
.
resource_group
.
release_resource_from
(
build
)
build
.
run_after_commit
do
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
.
perform_async
(
build
.
resource_group_id
)
end
end
after_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
build
|
after_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
build
|
build
.
run_after_commit
do
build
.
run_after_commit
do
BuildFinishedWorker
.
perform_async
(
id
)
BuildFinishedWorker
.
perform_async
(
id
)
...
@@ -439,6 +480,11 @@ module Ci
...
@@ -439,6 +480,11 @@ module Ci
end
end
end
end
def
requires_resource?
Feature
.
enabled?
(
:ci_resource_group
,
project
)
&&
self
.
resource_group_id
.
present?
end
def
has_environment?
def
has_environment?
environment
.
present?
environment
.
present?
end
end
...
...
app/models/ci/pipeline.rb
View file @
b4847c73
...
@@ -95,10 +95,14 @@ module Ci
...
@@ -95,10 +95,14 @@ module Ci
state_machine
:status
,
initial: :created
do
state_machine
:status
,
initial: :created
do
event
:enqueue
do
event
:enqueue
do
transition
[
:created
,
:preparing
,
:skipped
,
:scheduled
]
=>
:pending
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:skipped
,
:scheduled
]
=>
:pending
transition
[
:success
,
:failed
,
:canceled
]
=>
:running
transition
[
:success
,
:failed
,
:canceled
]
=>
:running
end
end
event
:request_resource
do
transition
any
-
[
:waiting_for_resource
]
=>
:waiting_for_resource
end
event
:prepare
do
event
:prepare
do
transition
any
-
[
:preparing
]
=>
:preparing
transition
any
-
[
:preparing
]
=>
:preparing
end
end
...
@@ -135,7 +139,7 @@ module Ci
...
@@ -135,7 +139,7 @@ module Ci
# Do not add any operations to this state_machine
# Do not add any operations to this state_machine
# Create a separate worker for each new operation
# Create a separate worker for each new operation
before_transition
[
:created
,
:preparing
,
:pending
]
=>
:running
do
|
pipeline
|
before_transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
]
=>
:running
do
|
pipeline
|
pipeline
.
started_at
=
Time
.
now
pipeline
.
started_at
=
Time
.
now
end
end
...
@@ -158,7 +162,7 @@ module Ci
...
@@ -158,7 +162,7 @@ module Ci
end
end
end
end
after_transition
[
:created
,
:preparing
,
:pending
]
=>
:running
do
|
pipeline
|
after_transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
]
=>
:running
do
|
pipeline
|
pipeline
.
run_after_commit
{
PipelineMetricsWorker
.
perform_async
(
pipeline
.
id
)
}
pipeline
.
run_after_commit
{
PipelineMetricsWorker
.
perform_async
(
pipeline
.
id
)
}
end
end
...
@@ -166,7 +170,7 @@ module Ci
...
@@ -166,7 +170,7 @@ module Ci
pipeline
.
run_after_commit
{
PipelineMetricsWorker
.
perform_async
(
pipeline
.
id
)
}
pipeline
.
run_after_commit
{
PipelineMetricsWorker
.
perform_async
(
pipeline
.
id
)
}
end
end
after_transition
[
:created
,
:preparing
,
:pending
,
:running
]
=>
:success
do
|
pipeline
|
after_transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
]
=>
:success
do
|
pipeline
|
pipeline
.
run_after_commit
{
PipelineSuccessWorker
.
perform_async
(
pipeline
.
id
)
}
pipeline
.
run_after_commit
{
PipelineSuccessWorker
.
perform_async
(
pipeline
.
id
)
}
end
end
...
@@ -317,7 +321,7 @@ module Ci
...
@@ -317,7 +321,7 @@ module Ci
end
end
def
self
.
bridgeable_statuses
def
self
.
bridgeable_statuses
::
Ci
::
Pipeline
::
AVAILABLE_STATUSES
-
%w[created preparing pending]
::
Ci
::
Pipeline
::
AVAILABLE_STATUSES
-
%w[created
waiting_for_resource
preparing pending]
end
end
def
stages_count
def
stages_count
...
@@ -576,6 +580,7 @@ module Ci
...
@@ -576,6 +580,7 @@ module Ci
new_status
=
latest_builds_status
.
to_s
new_status
=
latest_builds_status
.
to_s
case
new_status
case
new_status
when
'created'
then
nil
when
'created'
then
nil
when
'waiting_for_resource'
then
request_resource
when
'preparing'
then
prepare
when
'preparing'
then
prepare
when
'pending'
then
enqueue
when
'pending'
then
enqueue
when
'running'
then
run
when
'running'
then
run
...
...
app/models/ci/stage.rb
View file @
b4847c73
...
@@ -39,10 +39,14 @@ module Ci
...
@@ -39,10 +39,14 @@ module Ci
state_machine
:status
,
initial: :created
do
state_machine
:status
,
initial: :created
do
event
:enqueue
do
event
:enqueue
do
transition
[
:created
,
:preparing
]
=>
:pending
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
]
=>
:pending
transition
[
:success
,
:failed
,
:canceled
,
:skipped
]
=>
:running
transition
[
:success
,
:failed
,
:canceled
,
:skipped
]
=>
:running
end
end
event
:request_resource
do
transition
any
-
[
:waiting_for_resource
]
=>
:waiting_for_resource
end
event
:prepare
do
event
:prepare
do
transition
any
-
[
:preparing
]
=>
:preparing
transition
any
-
[
:preparing
]
=>
:preparing
end
end
...
@@ -81,6 +85,7 @@ module Ci
...
@@ -81,6 +85,7 @@ module Ci
new_status
=
latest_stage_status
.
to_s
new_status
=
latest_stage_status
.
to_s
case
new_status
case
new_status
when
'created'
then
nil
when
'created'
then
nil
when
'waiting_for_resource'
then
request_resource
when
'preparing'
then
prepare
when
'preparing'
then
prepare
when
'pending'
then
enqueue
when
'pending'
then
enqueue
when
'running'
then
run
when
'running'
then
run
...
...
app/models/commit_status.rb
View file @
b4847c73
...
@@ -96,7 +96,7 @@ class CommitStatus < ApplicationRecord
...
@@ -96,7 +96,7 @@ class CommitStatus < ApplicationRecord
# A CommitStatus will never have prerequisites, but this event
# A CommitStatus will never have prerequisites, but this event
# is shared by Ci::Build, which cannot progress unless prerequisites
# is shared by Ci::Build, which cannot progress unless prerequisites
# are satisfied.
# are satisfied.
transition
[
:created
,
:
preparing
,
:skipped
,
:manual
,
:scheduled
]
=>
:pending
,
unless: :any_unmet_prerequisites
?
transition
[
:created
,
:
skipped
,
:manual
,
:scheduled
]
=>
:pending
,
if: :all_met_to_become_pending
?
end
end
event
:run
do
event
:run
do
...
@@ -104,22 +104,22 @@ class CommitStatus < ApplicationRecord
...
@@ -104,22 +104,22 @@ class CommitStatus < ApplicationRecord
end
end
event
:skip
do
event
:skip
do
transition
[
:created
,
:preparing
,
:pending
]
=>
:skipped
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
]
=>
:skipped
end
end
event
:drop
do
event
:drop
do
transition
[
:created
,
:preparing
,
:pending
,
:running
,
:scheduled
]
=>
:failed
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
,
:scheduled
]
=>
:failed
end
end
event
:success
do
event
:success
do
transition
[
:created
,
:preparing
,
:pending
,
:running
]
=>
:success
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
]
=>
:success
end
end
event
:cancel
do
event
:cancel
do
transition
[
:created
,
:preparing
,
:pending
,
:running
,
:manual
,
:scheduled
]
=>
:canceled
transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
,
:manual
,
:scheduled
]
=>
:canceled
end
end
before_transition
[
:created
,
:preparing
,
:skipped
,
:manual
,
:scheduled
]
=>
:pending
do
|
commit_status
|
before_transition
[
:created
,
:
waiting_for_resource
,
:
preparing
,
:skipped
,
:manual
,
:scheduled
]
=>
:pending
do
|
commit_status
|
commit_status
.
queued_at
=
Time
.
now
commit_status
.
queued_at
=
Time
.
now
end
end
...
@@ -218,10 +218,18 @@ class CommitStatus < ApplicationRecord
...
@@ -218,10 +218,18 @@ class CommitStatus < ApplicationRecord
false
false
end
end
def
all_met_to_become_pending?
!
any_unmet_prerequisites?
&&
!
requires_resource?
end
def
any_unmet_prerequisites?
def
any_unmet_prerequisites?
false
false
end
end
def
requires_resource?
false
end
def
auto_canceled?
def
auto_canceled?
canceled?
&&
auto_canceled_by_id?
canceled?
&&
auto_canceled_by_id?
end
end
...
...
app/models/concerns/has_status.rb
View file @
b4847c73
...
@@ -5,16 +5,16 @@ module HasStatus
...
@@ -5,16 +5,16 @@ module HasStatus
DEFAULT_STATUS
=
'created'
DEFAULT_STATUS
=
'created'
BLOCKED_STATUS
=
%w[manual scheduled]
.
freeze
BLOCKED_STATUS
=
%w[manual scheduled]
.
freeze
AVAILABLE_STATUSES
=
%w[created preparing pending running success failed canceled skipped manual scheduled]
.
freeze
AVAILABLE_STATUSES
=
%w[created
waiting_for_resource
preparing pending running success failed canceled skipped manual scheduled]
.
freeze
STARTED_STATUSES
=
%w[running success failed skipped manual scheduled]
.
freeze
STARTED_STATUSES
=
%w[running success failed skipped manual scheduled]
.
freeze
ACTIVE_STATUSES
=
%w[preparing pending running]
.
freeze
ACTIVE_STATUSES
=
%w[preparing pending running]
.
freeze
COMPLETED_STATUSES
=
%w[success failed canceled skipped]
.
freeze
COMPLETED_STATUSES
=
%w[success failed canceled skipped]
.
freeze
ORDERED_STATUSES
=
%w[failed preparing pending running manual scheduled canceled success skipped created]
.
freeze
ORDERED_STATUSES
=
%w[failed preparing pending running
waiting_for_resource
manual scheduled canceled success skipped created]
.
freeze
PASSED_WITH_WARNINGS_STATUSES
=
%w[failed canceled]
.
to_set
.
freeze
PASSED_WITH_WARNINGS_STATUSES
=
%w[failed canceled]
.
to_set
.
freeze
EXCLUDE_IGNORED_STATUSES
=
%w[manual failed canceled]
.
to_set
.
freeze
EXCLUDE_IGNORED_STATUSES
=
%w[manual failed canceled]
.
to_set
.
freeze
STATUSES_ENUM
=
{
created:
0
,
pending:
1
,
running:
2
,
success:
3
,
STATUSES_ENUM
=
{
created:
0
,
pending:
1
,
running:
2
,
success:
3
,
failed:
4
,
canceled:
5
,
skipped:
6
,
manual:
7
,
failed:
4
,
canceled:
5
,
skipped:
6
,
manual:
7
,
scheduled:
8
,
preparing:
9
}.
freeze
scheduled:
8
,
preparing:
9
,
waiting_for_resource:
10
}.
freeze
UnknownStatusError
=
Class
.
new
(
StandardError
)
UnknownStatusError
=
Class
.
new
(
StandardError
)
...
@@ -29,6 +29,7 @@ module HasStatus
...
@@ -29,6 +29,7 @@ module HasStatus
manual
=
scope_relevant
.
manual
.
select
(
'count(*)'
).
to_sql
manual
=
scope_relevant
.
manual
.
select
(
'count(*)'
).
to_sql
scheduled
=
scope_relevant
.
scheduled
.
select
(
'count(*)'
).
to_sql
scheduled
=
scope_relevant
.
scheduled
.
select
(
'count(*)'
).
to_sql
preparing
=
scope_relevant
.
preparing
.
select
(
'count(*)'
).
to_sql
preparing
=
scope_relevant
.
preparing
.
select
(
'count(*)'
).
to_sql
waiting_for_resource
=
scope_relevant
.
waiting_for_resource
.
select
(
'count(*)'
).
to_sql
pending
=
scope_relevant
.
pending
.
select
(
'count(*)'
).
to_sql
pending
=
scope_relevant
.
pending
.
select
(
'count(*)'
).
to_sql
running
=
scope_relevant
.
running
.
select
(
'count(*)'
).
to_sql
running
=
scope_relevant
.
running
.
select
(
'count(*)'
).
to_sql
skipped
=
scope_relevant
.
skipped
.
select
(
'count(*)'
).
to_sql
skipped
=
scope_relevant
.
skipped
.
select
(
'count(*)'
).
to_sql
...
@@ -46,6 +47,7 @@ module HasStatus
...
@@ -46,6 +47,7 @@ module HasStatus
WHEN (
#{
builds
}
)=(
#{
success
}
)+(
#{
skipped
}
)+(
#{
canceled
}
) THEN 'canceled'
WHEN (
#{
builds
}
)=(
#{
success
}
)+(
#{
skipped
}
)+(
#{
canceled
}
) THEN 'canceled'
WHEN (
#{
builds
}
)=(
#{
created
}
)+(
#{
skipped
}
)+(
#{
pending
}
) THEN 'pending'
WHEN (
#{
builds
}
)=(
#{
created
}
)+(
#{
skipped
}
)+(
#{
pending
}
) THEN 'pending'
WHEN (
#{
running
}
)+(
#{
pending
}
)>0 THEN 'running'
WHEN (
#{
running
}
)+(
#{
pending
}
)>0 THEN 'running'
WHEN (
#{
waiting_for_resource
}
)>0 THEN 'waiting_for_resource'
WHEN (
#{
manual
}
)>0 THEN 'manual'
WHEN (
#{
manual
}
)>0 THEN 'manual'
WHEN (
#{
scheduled
}
)>0 THEN 'scheduled'
WHEN (
#{
scheduled
}
)>0 THEN 'scheduled'
WHEN (
#{
preparing
}
)>0 THEN 'preparing'
WHEN (
#{
preparing
}
)>0 THEN 'preparing'
...
@@ -95,6 +97,7 @@ module HasStatus
...
@@ -95,6 +97,7 @@ module HasStatus
state_machine
:status
,
initial: :created
do
state_machine
:status
,
initial: :created
do
state
:created
,
value:
'created'
state
:created
,
value:
'created'
state
:waiting_for_resource
,
value:
'waiting_for_resource'
state
:preparing
,
value:
'preparing'
state
:preparing
,
value:
'preparing'
state
:pending
,
value:
'pending'
state
:pending
,
value:
'pending'
state
:running
,
value:
'running'
state
:running
,
value:
'running'
...
@@ -107,6 +110,7 @@ module HasStatus
...
@@ -107,6 +110,7 @@ module HasStatus
end
end
scope
:created
,
->
{
with_status
(
:created
)
}
scope
:created
,
->
{
with_status
(
:created
)
}
scope
:waiting_for_resource
,
->
{
with_status
(
:waiting_for_resource
)
}
scope
:preparing
,
->
{
with_status
(
:preparing
)
}
scope
:preparing
,
->
{
with_status
(
:preparing
)
}
scope
:relevant
,
->
{
without_status
(
:created
)
}
scope
:relevant
,
->
{
without_status
(
:created
)
}
scope
:running
,
->
{
with_status
(
:running
)
}
scope
:running
,
->
{
with_status
(
:running
)
}
...
@@ -117,8 +121,8 @@ module HasStatus
...
@@ -117,8 +121,8 @@ module HasStatus
scope
:skipped
,
->
{
with_status
(
:skipped
)
}
scope
:skipped
,
->
{
with_status
(
:skipped
)
}
scope
:manual
,
->
{
with_status
(
:manual
)
}
scope
:manual
,
->
{
with_status
(
:manual
)
}
scope
:scheduled
,
->
{
with_status
(
:scheduled
)
}
scope
:scheduled
,
->
{
with_status
(
:scheduled
)
}
scope
:alive
,
->
{
with_status
(
:created
,
:preparing
,
:pending
,
:running
)
}
scope
:alive
,
->
{
with_status
(
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
)
}
scope
:alive_or_scheduled
,
->
{
with_status
(
:created
,
:preparing
,
:pending
,
:running
,
:scheduled
)
}
scope
:alive_or_scheduled
,
->
{
with_status
(
:created
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:running
,
:scheduled
)
}
scope
:created_or_pending
,
->
{
with_status
(
:created
,
:pending
)
}
scope
:created_or_pending
,
->
{
with_status
(
:created
,
:pending
)
}
scope
:running_or_pending
,
->
{
with_status
(
:running
,
:pending
)
}
scope
:running_or_pending
,
->
{
with_status
(
:running
,
:pending
)
}
scope
:finished
,
->
{
with_status
(
:success
,
:failed
,
:canceled
)
}
scope
:finished
,
->
{
with_status
(
:success
,
:failed
,
:canceled
)
}
...
@@ -126,7 +130,7 @@ module HasStatus
...
@@ -126,7 +130,7 @@ module HasStatus
scope
:incomplete
,
->
{
without_statuses
(
completed_statuses
)
}
scope
:incomplete
,
->
{
without_statuses
(
completed_statuses
)
}
scope
:cancelable
,
->
do
scope
:cancelable
,
->
do
where
(
status:
[
:running
,
:preparing
,
:pending
,
:created
,
:scheduled
])
where
(
status:
[
:running
,
:
waiting_for_resource
,
:
preparing
,
:pending
,
:created
,
:scheduled
])
end
end
scope
:without_statuses
,
->
(
names
)
do
scope
:without_statuses
,
->
(
names
)
do
...
...
app/services/ci/prepare_build_service.rb
View file @
b4847c73
...
@@ -11,7 +11,7 @@ module Ci
...
@@ -11,7 +11,7 @@ module Ci
def
execute
def
execute
prerequisites
.
each
(
&
:complete!
)
prerequisites
.
each
(
&
:complete!
)
build
.
enqueue!
build
.
enqueue
_preparing
!
rescue
=>
e
rescue
=>
e
Gitlab
::
ErrorTracking
.
track_exception
(
e
,
build_id:
build
.
id
)
Gitlab
::
ErrorTracking
.
track_exception
(
e
,
build_id:
build
.
id
)
...
...
app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
module
Ci
module
ResourceGroups
class
AssignResourceFromResourceGroupService
<
::
BaseService
# rubocop: disable CodeReuse/ActiveRecord
def
execute
(
resource_group
)
free_resources
=
resource_group
.
resources
.
free
.
count
resource_group
.
builds
.
waiting_for_resource
.
take
(
free_resources
).
each
do
|
build
|
build
.
enqueue_waiting_for_resource
end
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
end
app/workers/all_queues.yml
View file @
b4847c73
...
@@ -103,6 +103,7 @@
...
@@ -103,6 +103,7 @@
-
pipeline_processing:stage_update
-
pipeline_processing:stage_update
-
pipeline_processing:update_head_pipeline_for_merge_request
-
pipeline_processing:update_head_pipeline_for_merge_request
-
pipeline_processing:ci_build_schedule
-
pipeline_processing:ci_build_schedule
-
pipeline_processing:ci_resource_groups_assign_resource_from_resource_group
-
deployment:deployments_success
-
deployment:deployments_success
-
deployment:deployments_finished
-
deployment:deployments_finished
...
...
app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
module
Ci
module
ResourceGroups
class
AssignResourceFromResourceGroupWorker
include
ApplicationWorker
include
PipelineQueue
queue_namespace
:pipeline_processing
feature_category
:continuous_delivery
def
perform
(
resource_group_id
)
::
Ci
::
ResourceGroup
.
find_by_id
(
resource_group_id
).
try
do
|
resource_group
|
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupService
.
new
(
resource_group
.
project
,
nil
)
.
execute
(
resource_group
)
end
end
end
end
end
doc/api/graphql/reference/gitlab_schema.graphql
View file @
b4847c73
...
@@ -4443,7 +4443,8 @@ type Pipeline {
...
@@ -4443,7 +4443,8 @@ type Pipeline {
startedAt
:
Time
startedAt
:
Time
"""
"""
Status
of
the
pipeline
(
CREATED
,
PREPARING
,
PENDING
,
RUNNING
,
FAILED
,
SUCCESS
,
CANCELED
,
SKIPPED
,
MANUAL
,
SCHEDULED
)
Status
of
the
pipeline
(
CREATED
,
WAITING_FOR_RESOURCE
,
PREPARING
,
PENDING
,
RUNNING
,
FAILED
,
SUCCESS
,
CANCELED
,
SKIPPED
,
MANUAL
,
SCHEDULED
)
"""
"""
status
:
PipelineStatusEnum
!
status
:
PipelineStatusEnum
!
...
@@ -4521,6 +4522,7 @@ enum PipelineStatusEnum {
...
@@ -4521,6 +4522,7 @@ enum PipelineStatusEnum {
SCHEDULED
SCHEDULED
SKIPPED
SKIPPED
SUCCESS
SUCCESS
WAITING_FOR_RESOURCE
}
}
type
Project
{
type
Project
{
...
...
doc/api/graphql/reference/gitlab_schema.json
View file @
b4847c73
...
@@ -12203,7 +12203,7 @@
...
@@ -12203,7 +12203,7 @@
},
},
{
{
"name"
:
"status"
,
"name"
:
"status"
,
"description"
:
"Status of the pipeline (CREATED, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED)"
,
"description"
:
"Status of the pipeline (CREATED,
WAITING_FOR_RESOURCE,
PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED)"
,
"args"
:
[
"args"
:
[
],
],
...
@@ -12344,6 +12344,12 @@
...
@@ -12344,6 +12344,12 @@
"isDeprecated"
:
false
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
"deprecationReason"
:
null
},
},
{
"name"
:
"WAITING_FOR_RESOURCE"
,
"description"
:
null
,
"isDeprecated"
:
false
,
"deprecationReason"
:
null
},
{
{
"name"
:
"PREPARING"
,
"name"
:
"PREPARING"
,
"description"
:
null
,
"description"
:
null
,
...
...
doc/api/graphql/reference/index.md
View file @
b4847c73
...
@@ -635,7 +635,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
...
@@ -635,7 +635,7 @@ The API can be explored interactively using the [GraphiQL IDE](../index.md#graph
|
`iid`
| String! | Internal ID of the pipeline |
|
`iid`
| String! | Internal ID of the pipeline |
|
`sha`
| String! | SHA of the pipeline's commit |
|
`sha`
| String! | SHA of the pipeline's commit |
|
`beforeSha`
| String | Base SHA of the source branch |
|
`beforeSha`
| String | Base SHA of the source branch |
|
`status`
| PipelineStatusEnum! | Status of the pipeline (CREATED, PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) |
|
`status`
| PipelineStatusEnum! | Status of the pipeline (CREATED,
WAITING_FOR_RESOURCE,
PREPARING, PENDING, RUNNING, FAILED, SUCCESS, CANCELED, SKIPPED, MANUAL, SCHEDULED) |
|
`detailedStatus`
| DetailedStatus! | Detailed status of the pipeline |
|
`detailedStatus`
| DetailedStatus! | Detailed status of the pipeline |
|
`duration`
| Int | Duration of the pipeline in seconds |
|
`duration`
| Int | Duration of the pipeline in seconds |
|
`coverage`
| Float | Coverage percentage |
|
`coverage`
| Float | Coverage percentage |
...
...
lib/gitlab/ci/status/build/factory.rb
View file @
b4847c73
...
@@ -11,6 +11,7 @@ module Gitlab
...
@@ -11,6 +11,7 @@ module Gitlab
Status
::
Build
::
Manual
,
Status
::
Build
::
Manual
,
Status
::
Build
::
Canceled
,
Status
::
Build
::
Canceled
,
Status
::
Build
::
Created
,
Status
::
Build
::
Created
,
Status
::
Build
::
WaitingForResource
,
Status
::
Build
::
Preparing
,
Status
::
Build
::
Preparing
,
Status
::
Build
::
Pending
,
Status
::
Build
::
Pending
,
Status
::
Build
::
Skipped
],
Status
::
Build
::
Skipped
],
...
...
lib/gitlab/ci/status/build/waiting_for_resource.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
module
Gitlab
module
Ci
module
Status
module
Build
class
WaitingForResource
<
Status
::
Extended
##
# TODO: image is shared with 'pending'
# until we get a dedicated one
#
def
illustration
{
image:
'illustrations/pending_job_empty.svg'
,
size:
'svg-430'
,
title:
_
(
'This job is waiting for resource: '
)
+
subject
.
resource_group
.
key
}
end
def
self
.
matches?
(
build
,
_
)
build
.
waiting_for_resource?
end
end
end
end
end
end
lib/gitlab/ci/status/composite.rb
View file @
b4847c73
...
@@ -25,6 +25,8 @@ module Gitlab
...
@@ -25,6 +25,8 @@ module Gitlab
# 2. In other cases we assume that status is of that type
# 2. In other cases we assume that status is of that type
# based on what statuses are no longer valid based on the
# based on what statuses are no longer valid based on the
# data set that we have
# data set that we have
# rubocop: disable Metrics/CyclomaticComplexity
# rubocop: disable Metrics/PerceivedComplexity
def
status
def
status
return
if
none?
return
if
none?
...
@@ -43,6 +45,8 @@ module Gitlab
...
@@ -43,6 +45,8 @@ module Gitlab
'pending'
'pending'
elsif
any_of?
(
:running
,
:pending
)
elsif
any_of?
(
:running
,
:pending
)
'running'
'running'
elsif
any_of?
(
:waiting_for_resource
)
'waiting_for_resource'
elsif
any_of?
(
:manual
)
elsif
any_of?
(
:manual
)
'manual'
'manual'
elsif
any_of?
(
:scheduled
)
elsif
any_of?
(
:scheduled
)
...
@@ -56,6 +60,8 @@ module Gitlab
...
@@ -56,6 +60,8 @@ module Gitlab
end
end
end
end
end
end
# rubocop: enable Metrics/CyclomaticComplexity
# rubocop: enable Metrics/PerceivedComplexity
def
warnings?
def
warnings?
@status_set
.
include?
(
:success_with_warnings
)
@status_set
.
include?
(
:success_with_warnings
)
...
...
lib/gitlab/ci/status/factory.rb
View file @
b4847c73
...
@@ -20,7 +20,7 @@ module Gitlab
...
@@ -20,7 +20,7 @@ module Gitlab
def
core_status
def
core_status
Gitlab
::
Ci
::
Status
Gitlab
::
Ci
::
Status
.
const_get
(
@status
.
capita
lize
,
false
)
.
const_get
(
@status
.
to_s
.
came
lize
,
false
)
.
new
(
@subject
,
@user
)
.
new
(
@subject
,
@user
)
.
extend
(
self
.
class
.
common_helpers
)
.
extend
(
self
.
class
.
common_helpers
)
end
end
...
...
lib/gitlab/ci/status/waiting_for_resource.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
module
Gitlab
module
Ci
module
Status
class
WaitingForResource
<
Status
::
Core
def
text
s_
(
'CiStatusText|waiting'
)
end
def
label
s_
(
'CiStatusLabel|waiting for resource'
)
end
def
icon
'status_pending'
end
def
favicon
'favicon_pending'
end
def
group
'waiting-for-resource'
end
end
end
end
end
locale/gitlab.pot
View file @
b4847c73
...
@@ -3358,6 +3358,9 @@ msgstr ""
...
@@ -3358,6 +3358,9 @@ msgstr ""
msgid "CiStatusLabel|waiting for manual action"
msgid "CiStatusLabel|waiting for manual action"
msgstr ""
msgstr ""
msgid "CiStatusLabel|waiting for resource"
msgstr ""
msgid "CiStatusText|blocked"
msgid "CiStatusText|blocked"
msgstr ""
msgstr ""
...
@@ -3388,6 +3391,9 @@ msgstr ""
...
@@ -3388,6 +3391,9 @@ msgstr ""
msgid "CiStatusText|skipped"
msgid "CiStatusText|skipped"
msgstr ""
msgstr ""
msgid "CiStatusText|waiting"
msgstr ""
msgid "CiStatus|running"
msgid "CiStatus|running"
msgstr ""
msgstr ""
...
@@ -18505,6 +18511,9 @@ msgstr ""
...
@@ -18505,6 +18511,9 @@ msgstr ""
msgid "This job is stuck because you don't have any active runners that can run this job."
msgid "This job is stuck because you don't have any active runners that can run this job."
msgstr ""
msgstr ""
msgid "This job is waiting for resource: "
msgstr ""
msgid "This job requires a manual action"
msgid "This job requires a manual action"
msgstr ""
msgstr ""
...
...
spec/factories/ci/builds.rb
View file @
b4847c73
...
@@ -77,6 +77,10 @@ FactoryBot.define do
...
@@ -77,6 +77,10 @@ FactoryBot.define do
status
{
'created'
}
status
{
'created'
}
end
end
trait
:waiting_for_resource
do
status
{
'waiting_for_resource'
}
end
trait
:preparing
do
trait
:preparing
do
status
{
'preparing'
}
status
{
'preparing'
}
end
end
...
...
spec/factories/commit_statuses.rb
View file @
b4847c73
...
@@ -35,6 +35,10 @@ FactoryBot.define do
...
@@ -35,6 +35,10 @@ FactoryBot.define do
status
{
'pending'
}
status
{
'pending'
}
end
end
trait
:waiting_for_resource
do
status
{
'waiting_for_resource'
}
end
trait
:preparing
do
trait
:preparing
do
status
{
'preparing'
}
status
{
'preparing'
}
end
end
...
...
spec/features/projects/pipelines/pipeline_spec.rb
View file @
b4847c73
...
@@ -606,6 +606,117 @@ describe 'Pipeline', :js do
...
@@ -606,6 +606,117 @@ describe 'Pipeline', :js do
end
end
end
end
context
'when build requires resource'
,
:sidekiq_inline
do
let_it_be
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
project:
project
)
}
let
(
:resource_group
)
{
create
(
:ci_resource_group
,
project:
project
)
}
let!
(
:test_job
)
do
create
(
:ci_build
,
:pending
,
stage:
'test'
,
name:
'test'
,
stage_idx:
1
,
pipeline:
pipeline
,
project:
project
)
end
let!
(
:deploy_job
)
do
create
(
:ci_build
,
:created
,
stage:
'deploy'
,
name:
'deploy'
,
stage_idx:
2
,
pipeline:
pipeline
,
project:
project
,
resource_group:
resource_group
)
end
describe
'GET /:project/pipelines/:id'
do
subject
{
visit
project_pipeline_path
(
project
,
pipeline
)
}
it
'shows deploy job as created'
do
subject
within
(
'.pipeline-header-container'
)
do
expect
(
page
).
to
have_content
(
'pending'
)
end
within
(
'.pipeline-graph'
)
do
within
'.stage-column:nth-child(1)'
do
expect
(
page
).
to
have_content
(
'test'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-pending'
)
end
within
'.stage-column:nth-child(2)'
do
expect
(
page
).
to
have_content
(
'deploy'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-created'
)
end
end
end
context
'when test job succeeded'
do
before
do
test_job
.
success!
end
it
'shows deploy job as pending'
do
subject
within
(
'.pipeline-header-container'
)
do
expect
(
page
).
to
have_content
(
'running'
)
end
within
(
'.pipeline-graph'
)
do
within
'.stage-column:nth-child(1)'
do
expect
(
page
).
to
have_content
(
'test'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-success'
)
end
within
'.stage-column:nth-child(2)'
do
expect
(
page
).
to
have_content
(
'deploy'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-pending'
)
end
end
end
end
context
'when test job succeeded but there are no available resources'
do
let
(
:another_job
)
{
create
(
:ci_build
,
:running
,
project:
project
,
resource_group:
resource_group
)
}
before
do
resource_group
.
assign_resource_to
(
another_job
)
test_job
.
success!
end
it
'shows deploy job as waiting for resource'
do
subject
within
(
'.pipeline-header-container'
)
do
expect
(
page
).
to
have_content
(
'waiting'
)
end
within
(
'.pipeline-graph'
)
do
within
'.stage-column:nth-child(2)'
do
expect
(
page
).
to
have_content
(
'deploy'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-waiting-for-resource'
)
end
end
end
context
'when resource is released from another job'
do
before
do
another_job
.
success!
end
it
'shows deploy job as pending'
do
subject
within
(
'.pipeline-header-container'
)
do
expect
(
page
).
to
have_content
(
'running'
)
end
within
(
'.pipeline-graph'
)
do
within
'.stage-column:nth-child(2)'
do
expect
(
page
).
to
have_content
(
'deploy'
)
expect
(
page
).
to
have_css
(
'.ci-status-icon-pending'
)
end
end
end
end
end
end
end
describe
'GET /:project/pipelines/:id/builds'
do
describe
'GET /:project/pipelines/:id/builds'
do
include_context
'pipeline builds'
include_context
'pipeline builds'
...
...
spec/lib/gitlab/ci/status/external/factory_spec.rb
View file @
b4847c73
...
@@ -22,7 +22,7 @@ describe Gitlab::Ci::Status::External::Factory do
...
@@ -22,7 +22,7 @@ describe Gitlab::Ci::Status::External::Factory do
end
end
let
(
:expected_status
)
do
let
(
:expected_status
)
do
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
capita
lize
,
false
)
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
to_s
.
came
lize
,
false
)
end
end
it
"fabricates a core status
#{
simple_status
}
"
do
it
"fabricates a core status
#{
simple_status
}
"
do
...
...
spec/lib/gitlab/ci/status/factory_spec.rb
View file @
b4847c73
...
@@ -13,7 +13,7 @@ describe Gitlab::Ci::Status::Factory do
...
@@ -13,7 +13,7 @@ describe Gitlab::Ci::Status::Factory do
let
(
:resource
)
{
double
(
'resource'
,
status:
simple_status
)
}
let
(
:resource
)
{
double
(
'resource'
,
status:
simple_status
)
}
let
(
:expected_status
)
do
let
(
:expected_status
)
do
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
capita
lize
,
false
)
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
to_s
.
came
lize
,
false
)
end
end
it
"fabricates a core status
#{
simple_status
}
"
do
it
"fabricates a core status
#{
simple_status
}
"
do
...
...
spec/lib/gitlab/ci/status/pipeline/factory_spec.rb
View file @
b4847c73
...
@@ -18,7 +18,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do
...
@@ -18,7 +18,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
status:
simple_status
)
}
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
status:
simple_status
)
}
let
(
:expected_status
)
do
let
(
:expected_status
)
do
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
ca
pita
lize
,
false
)
Gitlab
::
Ci
::
Status
.
const_get
(
simple_status
.
ca
me
lize
,
false
)
end
end
it
"matches correct core status for
#{
simple_status
}
"
do
it
"matches correct core status for
#{
simple_status
}
"
do
...
...
spec/lib/gitlab/ci/status/stage/factory_spec.rb
View file @
b4847c73
...
@@ -34,7 +34,7 @@ describe Gitlab::Ci::Status::Stage::Factory do
...
@@ -34,7 +34,7 @@ describe Gitlab::Ci::Status::Stage::Factory do
it
"fabricates a core status
#{
core_status
}
"
do
it
"fabricates a core status
#{
core_status
}
"
do
expect
(
status
).
to
be_a
(
expect
(
status
).
to
be_a
(
Gitlab
::
Ci
::
Status
.
const_get
(
core_status
.
ca
pita
lize
,
false
))
Gitlab
::
Ci
::
Status
.
const_get
(
core_status
.
ca
me
lize
,
false
))
end
end
it
'extends core status with common stage methods'
do
it
'extends core status with common stage methods'
do
...
...
spec/lib/gitlab/ci/status/waiting_for_resource_spec.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
Ci
::
Status
::
WaitingForResource
do
subject
do
described_class
.
new
(
double
(
'subject'
),
double
(
'user'
))
end
describe
'#text'
do
it
{
expect
(
subject
.
text
).
to
eq
'waiting'
}
end
describe
'#label'
do
it
{
expect
(
subject
.
label
).
to
eq
'waiting for resource'
}
end
describe
'#icon'
do
it
{
expect
(
subject
.
icon
).
to
eq
'status_pending'
}
end
describe
'#favicon'
do
it
{
expect
(
subject
.
favicon
).
to
eq
'favicon_pending'
}
end
describe
'#group'
do
it
{
expect
(
subject
.
group
).
to
eq
'waiting-for-resource'
}
end
end
spec/models/ci/build_spec.rb
View file @
b4847c73
...
@@ -1119,6 +1119,60 @@ describe Ci::Build do
...
@@ -1119,6 +1119,60 @@ describe Ci::Build do
end
end
end
end
describe
'state transition with resource group'
do
let
(
:resource_group
)
{
create
(
:ci_resource_group
,
project:
project
)
}
context
'when build status is created'
do
let
(
:build
)
{
create
(
:ci_build
,
:created
,
project:
project
,
resource_group:
resource_group
)
}
it
'is waiting for resource when build is enqueued'
do
expect
(
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
).
to
receive
(
:perform_async
).
with
(
resource_group
.
id
)
expect
{
build
.
enqueue!
}.
to
change
{
build
.
status
}.
from
(
'created'
).
to
(
'waiting_for_resource'
)
expect
(
build
.
waiting_for_resource_at
).
not_to
be_nil
end
context
'when build is waiting for resource'
do
before
do
build
.
update_column
(
:status
,
'waiting_for_resource'
)
end
it
'is enqueued when build requests resource'
do
expect
{
build
.
enqueue_waiting_for_resource!
}.
to
change
{
build
.
status
}.
from
(
'waiting_for_resource'
).
to
(
'pending'
)
end
it
'releases a resource when build finished'
do
expect
(
build
.
resource_group
).
to
receive
(
:release_resource_from
).
with
(
build
).
and_call_original
expect
(
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
).
to
receive
(
:perform_async
).
with
(
build
.
resource_group_id
)
build
.
enqueue_waiting_for_resource!
build
.
success!
end
context
'when build has prerequisites'
do
before
do
allow
(
build
).
to
receive
(
:any_unmet_prerequisites?
)
{
true
}
end
it
'is preparing when build is enqueued'
do
expect
{
build
.
enqueue_waiting_for_resource!
}.
to
change
{
build
.
status
}.
from
(
'waiting_for_resource'
).
to
(
'preparing'
)
end
end
context
'when there are no available resources'
do
before
do
resource_group
.
assign_resource_to
(
create
(
:ci_build
))
end
it
'stays as waiting for resource when build requests resource'
do
expect
{
build
.
enqueue_waiting_for_resource
}.
not_to
change
{
build
.
status
}
end
end
end
end
end
describe
'#on_stop'
do
describe
'#on_stop'
do
subject
{
build
.
on_stop
}
subject
{
build
.
on_stop
}
...
...
spec/models/ci/pipeline_spec.rb
View file @
b4847c73
...
@@ -1749,7 +1749,7 @@ describe Ci::Pipeline, :mailer do
...
@@ -1749,7 +1749,7 @@ describe Ci::Pipeline, :mailer do
subject
{
described_class
.
bridgeable_statuses
}
subject
{
described_class
.
bridgeable_statuses
}
it
{
is_expected
.
to
be_an
(
Array
)
}
it
{
is_expected
.
to
be_an
(
Array
)
}
it
{
is_expected
.
not_to
include
(
'created'
,
'preparing'
,
'pending'
)
}
it
{
is_expected
.
not_to
include
(
'created'
,
'
waiting_for_resource'
,
'
preparing'
,
'pending'
)
}
end
end
describe
'#status'
,
:sidekiq_might_not_need_inline
do
describe
'#status'
,
:sidekiq_might_not_need_inline
do
...
@@ -1759,6 +1759,17 @@ describe Ci::Pipeline, :mailer do
...
@@ -1759,6 +1759,17 @@ describe Ci::Pipeline, :mailer do
subject
{
pipeline
.
reload
.
status
}
subject
{
pipeline
.
reload
.
status
}
context
'on waiting for resource'
do
before
do
allow
(
build
).
to
receive
(
:requires_resource?
)
{
true
}
allow
(
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
).
to
receive
(
:perform_async
)
build
.
enqueue
end
it
{
is_expected
.
to
eq
(
'waiting_for_resource'
)
}
end
context
'on prepare'
do
context
'on prepare'
do
before
do
before
do
# Prevent skipping directly to 'pending'
# Prevent skipping directly to 'pending'
...
...
spec/models/ci/stage_spec.rb
View file @
b4847c73
...
@@ -105,6 +105,18 @@ describe Ci::Stage, :models do
...
@@ -105,6 +105,18 @@ describe Ci::Stage, :models do
end
end
end
end
context
'when build is waiting for resource'
do
before
do
create
(
:ci_build
,
:waiting_for_resource
,
stage_id:
stage
.
id
)
end
it
'updates status to waiting for resource'
do
expect
{
stage
.
update_status
}
.
to
change
{
stage
.
reload
.
status
}
.
to
'waiting_for_resource'
end
end
context
'when stage is skipped because is empty'
do
context
'when stage is skipped because is empty'
do
it
'updates status to skipped'
do
it
'updates status to skipped'
do
expect
{
stage
.
update_status
}
expect
{
stage
.
update_status
}
...
...
spec/models/commit_status_spec.rb
View file @
b4847c73
...
@@ -634,6 +634,30 @@ describe CommitStatus do
...
@@ -634,6 +634,30 @@ describe CommitStatus do
end
end
end
end
describe
'#all_met_to_become_pending?'
do
subject
{
commit_status
.
all_met_to_become_pending?
}
let
(
:commit_status
)
{
create
(
:commit_status
)
}
it
{
is_expected
.
to
eq
(
true
)
}
context
'when build requires a resource'
do
before
do
allow
(
commit_status
).
to
receive
(
:requires_resource?
)
{
true
}
end
it
{
is_expected
.
to
eq
(
false
)
}
end
context
'when build has a prerequisite'
do
before
do
allow
(
commit_status
).
to
receive
(
:any_unmet_prerequisites?
)
{
true
}
end
it
{
is_expected
.
to
eq
(
false
)
}
end
end
describe
'#enqueue'
do
describe
'#enqueue'
do
let!
(
:current_time
)
{
Time
.
new
(
2018
,
4
,
5
,
14
,
0
,
0
)
}
let!
(
:current_time
)
{
Time
.
new
(
2018
,
4
,
5
,
14
,
0
,
0
)
}
...
@@ -654,12 +678,6 @@ describe CommitStatus do
...
@@ -654,12 +678,6 @@ describe CommitStatus do
it_behaves_like
'commit status enqueued'
it_behaves_like
'commit status enqueued'
end
end
context
'when initial state is :preparing'
do
let
(
:commit_status
)
{
create
(
:commit_status
,
:preparing
)
}
it_behaves_like
'commit status enqueued'
end
context
'when initial state is :skipped'
do
context
'when initial state is :skipped'
do
let
(
:commit_status
)
{
create
(
:commit_status
,
:skipped
)
}
let
(
:commit_status
)
{
create
(
:commit_status
,
:skipped
)
}
...
...
spec/models/concerns/has_status_spec.rb
View file @
b4847c73
...
@@ -39,6 +39,22 @@ describe HasStatus do
...
@@ -39,6 +39,22 @@ describe HasStatus do
it
{
is_expected
.
to
eq
'running'
}
it
{
is_expected
.
to
eq
'running'
}
end
end
context
'all waiting for resource'
do
let!
(
:statuses
)
do
[
create
(
type
,
status: :waiting_for_resource
),
create
(
type
,
status: :waiting_for_resource
)]
end
it
{
is_expected
.
to
eq
'waiting_for_resource'
}
end
context
'at least one waiting for resource'
do
let!
(
:statuses
)
do
[
create
(
type
,
status: :success
),
create
(
type
,
status: :waiting_for_resource
)]
end
it
{
is_expected
.
to
eq
'waiting_for_resource'
}
end
context
'all preparing'
do
context
'all preparing'
do
let!
(
:statuses
)
do
let!
(
:statuses
)
do
[
create
(
type
,
status: :preparing
),
create
(
type
,
status: :preparing
)]
[
create
(
type
,
status: :preparing
),
create
(
type
,
status: :preparing
)]
...
@@ -219,7 +235,7 @@ describe HasStatus do
...
@@ -219,7 +235,7 @@ describe HasStatus do
end
end
end
end
%i[created preparing running pending success
%i[created
waiting_for_resource
preparing running pending success
failed canceled skipped]
.
each
do
|
status
|
failed canceled skipped]
.
each
do
|
status
|
it_behaves_like
'having a job'
,
status
it_behaves_like
'having a job'
,
status
end
end
...
@@ -265,7 +281,7 @@ describe HasStatus do
...
@@ -265,7 +281,7 @@ describe HasStatus do
describe
'.alive'
do
describe
'.alive'
do
subject
{
CommitStatus
.
alive
}
subject
{
CommitStatus
.
alive
}
%i[running pending preparing created]
.
each
do
|
status
|
%i[running pending
waiting_for_resource
preparing created]
.
each
do
|
status
|
it_behaves_like
'containing the job'
,
status
it_behaves_like
'containing the job'
,
status
end
end
...
@@ -277,7 +293,7 @@ describe HasStatus do
...
@@ -277,7 +293,7 @@ describe HasStatus do
describe
'.alive_or_scheduled'
do
describe
'.alive_or_scheduled'
do
subject
{
CommitStatus
.
alive_or_scheduled
}
subject
{
CommitStatus
.
alive_or_scheduled
}
%i[running pending preparing created scheduled]
.
each
do
|
status
|
%i[running pending
waiting_for_resource
preparing created scheduled]
.
each
do
|
status
|
it_behaves_like
'containing the job'
,
status
it_behaves_like
'containing the job'
,
status
end
end
...
@@ -313,7 +329,7 @@ describe HasStatus do
...
@@ -313,7 +329,7 @@ describe HasStatus do
describe
'.cancelable'
do
describe
'.cancelable'
do
subject
{
CommitStatus
.
cancelable
}
subject
{
CommitStatus
.
cancelable
}
%i[running pending preparing created scheduled]
.
each
do
|
status
|
%i[running pending
waiting_for_resource
preparing created scheduled]
.
each
do
|
status
|
it_behaves_like
'containing the job'
,
status
it_behaves_like
'containing the job'
,
status
end
end
...
...
spec/services/ci/prepare_build_service_spec.rb
View file @
b4847c73
...
@@ -14,7 +14,7 @@ describe Ci::PrepareBuildService do
...
@@ -14,7 +14,7 @@ describe Ci::PrepareBuildService do
shared_examples
'build enqueueing'
do
shared_examples
'build enqueueing'
do
it
'enqueues the build'
do
it
'enqueues the build'
do
expect
(
build
).
to
receive
(
:enqueue
).
once
expect
(
build
).
to
receive
(
:enqueue
_preparing
).
once
subject
subject
end
end
...
@@ -34,7 +34,7 @@ describe Ci::PrepareBuildService do
...
@@ -34,7 +34,7 @@ describe Ci::PrepareBuildService do
context
'prerequisites fail to complete'
do
context
'prerequisites fail to complete'
do
before
do
before
do
allow
(
build
).
to
receive
(
:enqueue
).
and_return
(
false
)
allow
(
build
).
to
receive
(
:enqueue
_preparing
).
and_return
(
false
)
end
end
it
'drops the build'
do
it
'drops the build'
do
...
...
spec/services/ci/process_pipeline_service_spec.rb
View file @
b4847c73
...
@@ -261,12 +261,16 @@ describe Ci::ProcessPipelineService, '#execute' do
...
@@ -261,12 +261,16 @@ describe Ci::ProcessPipelineService, '#execute' do
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'scheduled'
})
enqueue_scheduled
(
'rollout10%'
)
Timecop
.
travel
2
.
minutes
.
from_now
do
enqueue_scheduled
(
'rollout10%'
)
end
succeed_pending
succeed_pending
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'success'
,
'rollout100%'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'success'
,
'rollout100%'
:
'scheduled'
})
enqueue_scheduled
(
'rollout100%'
)
Timecop
.
travel
2
.
minutes
.
from_now
do
enqueue_scheduled
(
'rollout100%'
)
end
succeed_pending
succeed_pending
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'success'
,
'rollout100%'
:
'success'
,
'cleanup'
:
'pending'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'success'
,
'rollout100%'
:
'success'
,
'cleanup'
:
'pending'
})
...
@@ -328,7 +332,9 @@ describe Ci::ProcessPipelineService, '#execute' do
...
@@ -328,7 +332,9 @@ describe Ci::ProcessPipelineService, '#execute' do
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'scheduled'
})
enqueue_scheduled
(
'rollout10%'
)
Timecop
.
travel
2
.
minutes
.
from_now
do
enqueue_scheduled
(
'rollout10%'
)
end
fail_running_or_pending
fail_running_or_pending
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'failed'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'build'
:
'success'
,
'rollout10%'
:
'failed'
})
...
@@ -394,7 +400,9 @@ describe Ci::ProcessPipelineService, '#execute' do
...
@@ -394,7 +400,9 @@ describe Ci::ProcessPipelineService, '#execute' do
expect
(
process_pipeline
).
to
be_truthy
expect
(
process_pipeline
).
to
be_truthy
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed1'
:
'scheduled'
,
'delayed2'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed1'
:
'scheduled'
,
'delayed2'
:
'scheduled'
})
enqueue_scheduled
(
'delayed1'
)
Timecop
.
travel
2
.
minutes
.
from_now
do
enqueue_scheduled
(
'delayed1'
)
end
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed1'
:
'pending'
,
'delayed2'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed1'
:
'pending'
,
'delayed2'
:
'scheduled'
})
expect
(
pipeline
.
reload
.
status
).
to
eq
'running'
expect
(
pipeline
.
reload
.
status
).
to
eq
'running'
...
@@ -413,7 +421,9 @@ describe Ci::ProcessPipelineService, '#execute' do
...
@@ -413,7 +421,9 @@ describe Ci::ProcessPipelineService, '#execute' do
expect
(
process_pipeline
).
to
be_truthy
expect
(
process_pipeline
).
to
be_truthy
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed'
:
'scheduled'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed'
:
'scheduled'
})
enqueue_scheduled
(
'delayed'
)
Timecop
.
travel
2
.
minutes
.
from_now
do
enqueue_scheduled
(
'delayed'
)
end
fail_running_or_pending
fail_running_or_pending
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed'
:
'failed'
,
'job'
:
'pending'
})
expect
(
builds_names_and_statuses
).
to
eq
({
'delayed'
:
'failed'
,
'job'
:
'pending'
})
...
@@ -906,7 +916,7 @@ describe Ci::ProcessPipelineService, '#execute' do
...
@@ -906,7 +916,7 @@ describe Ci::ProcessPipelineService, '#execute' do
end
end
def
enqueue_scheduled
(
name
)
def
enqueue_scheduled
(
name
)
builds
.
scheduled
.
find_by
(
name:
name
).
enqueue
builds
.
scheduled
.
find_by
(
name:
name
).
enqueue
_scheduled
end
end
def
retry_build
(
name
)
def
retry_build
(
name
)
...
...
spec/services/ci/resource_groups/assign_resource_from_resource_group_service_spec.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
require
'spec_helper'
describe
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupService
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:service
)
{
described_class
.
new
(
project
,
user
)
}
describe
'#execute'
do
subject
{
service
.
execute
(
resource_group
)
}
let
(
:resource_group
)
{
create
(
:ci_resource_group
,
project:
project
)
}
let!
(
:build
)
{
create
(
:ci_build
,
:waiting_for_resource
,
project:
project
,
user:
user
,
resource_group:
resource_group
)
}
context
'when there is an available resource'
do
it
'requests resource'
do
subject
expect
(
build
.
reload
).
to
be_pending
expect
(
build
.
resource
).
to
be_present
end
context
'when failed to request resource'
do
before
do
allow_next_instance_of
(
Ci
::
Build
)
do
|
build
|
allow
(
build
).
to
receive
(
:enqueue_waiting_for_resource
)
{
false
}
end
end
it
'has a build waiting for resource'
do
subject
expect
(
build
).
to
be_waiting_for_resource
end
end
context
'when the build has already retained a resource'
do
before
do
resource_group
.
assign_resource_to
(
build
)
build
.
update_column
(
:status
,
:pending
)
end
it
'has a pending build'
do
subject
expect
(
build
).
to
be_pending
end
end
end
context
'when there are no available resources'
do
before
do
resource_group
.
assign_resource_to
(
create
(
:ci_build
))
end
it
'does not request resource'
do
expect_any_instance_of
(
Ci
::
Build
).
not_to
receive
(
:enqueue_waiting_for_resource
)
subject
end
end
end
end
spec/services/ci/run_scheduled_build_service_spec.rb
View file @
b4847c73
...
@@ -26,6 +26,18 @@ describe Ci::RunScheduledBuildService do
...
@@ -26,6 +26,18 @@ describe Ci::RunScheduledBuildService do
expect
(
build
).
to
be_pending
expect
(
build
).
to
be_pending
end
end
context
'when build requires resource'
do
let
(
:resource_group
)
{
create
(
:ci_resource_group
,
project:
project
)
}
before
do
build
.
update!
(
resource_group:
resource_group
)
end
it
'transits to waiting for resource status'
do
expect
{
subject
}.
to
change
{
build
.
status
}.
from
(
'scheduled'
).
to
(
'waiting_for_resource'
)
end
end
end
end
context
'when scheduled_at is not expired'
do
context
'when scheduled_at is not expired'
do
...
...
spec/workers/ci/resource_groups/assign_resource_from_resource_group_worker_spec.rb
0 → 100644
View file @
b4847c73
# frozen_string_literal: true
require
'spec_helper'
describe
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupWorker
do
let
(
:worker
)
{
described_class
.
new
}
describe
'#perform'
do
subject
{
worker
.
perform
(
resource_group_id
)
}
context
'when resource group exists'
do
let
(
:resource_group
)
{
create
(
:ci_resource_group
)
}
let
(
:resource_group_id
)
{
resource_group
.
id
}
it
'executes AssignResourceFromResourceGroupService'
do
expect_next_instance_of
(
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupService
,
resource_group
.
project
,
nil
)
do
|
service
|
expect
(
service
).
to
receive
(
:execute
).
with
(
resource_group
)
end
subject
end
end
context
'when build does not exist'
do
let
(
:resource_group_id
)
{
123
}
it
'does not execute AssignResourceFromResourceGroupService'
do
expect
(
Ci
::
ResourceGroups
::
AssignResourceFromResourceGroupService
).
not_to
receive
(
:new
)
subject
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