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
7b83426d
Commit
7b83426d
authored
Feb 03, 2021
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply 3 suggestion(s) to 1 file(s)
This commit fixes the documentation and adding tests.
parent
c4aca6df
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
272 additions
and
51 deletions
+272
-51
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+12
-13
lib/gitlab/ci/status/processable/waiting_for_resource.rb
lib/gitlab/ci/status/processable/waiting_for_resource.rb
+2
-2
spec/factories/ci/bridge.rb
spec/factories/ci/bridge.rb
+1
-8
spec/factories/ci/builds.rb
spec/factories/ci/builds.rb
+1
-19
spec/factories/ci/processable.rb
spec/factories/ci/processable.rb
+26
-0
spec/features/projects/pipelines/pipeline_spec.rb
spec/features/projects/pipelines/pipeline_spec.rb
+22
-0
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+12
-1
spec/lib/gitlab/ci/status/bridge/factory_spec.rb
spec/lib/gitlab/ci/status/bridge/factory_spec.rb
+19
-2
spec/lib/gitlab/ci/status/bridge/waiting_for_resource_spec.rb
.../lib/gitlab/ci/status/bridge/waiting_for_resource_spec.rb
+7
-0
spec/lib/gitlab/ci/status/build/waiting_for_resource_spec.rb
spec/lib/gitlab/ci/status/build/waiting_for_resource_spec.rb
+7
-0
spec/lib/gitlab/ci/status/processable/waiting_for_resource_spec.rb
...gitlab/ci/status/processable/waiting_for_resource_spec.rb
+36
-0
spec/models/ci/bridge_spec.rb
spec/models/ci/bridge_spec.rb
+8
-0
spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb
...ci/create_pipeline_service/cross_project_pipeline_spec.rb
+86
-0
spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
.../ci/create_pipeline_service/parent_child_pipeline_spec.rb
+33
-6
No files found.
doc/ci/yaml/README.md
View file @
7b83426d
...
@@ -3934,17 +3934,16 @@ For more information, see [Deployments Safety](../environments/deployment_safety
...
@@ -3934,17 +3934,16 @@ For more information, see [Deployments Safety](../environments/deployment_safety
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9.
You can define
`resource_group`
for downstream pipelines that are sensitive to
You can define
`resource_group`
for downstream pipelines that are sensitive to
concurrent
concurrent executions. Downstream pipelines can be triggered by
[
`trigger` keyword
](
#trigger
)
executions. The
[
`trigger` keyword
](
#trigger
)
can trigger downstream pipelines. The
and
[
`resource_group` keyword
](
#resource_group
)
can co-exist with it. This is useful to control the
[
`resource_group` keyword
](
#resource_group
)
can co-exist with it. This is useful to control the
concurency for deployment pipelines, while running non-sensitive jobs concurrently.
concur
r
ency for deployment pipelines, while running non-sensitive jobs concurrently.
In ths following example, we have two pipeline configurations in a project.
This example has two pipeline configurations in a project. When a pipeline starts running,
When a pipeline started running, non-sensitive jobs are executed at first and they
non-sensitive jobs are executed first and aren't affected by concurrent executions in other
won't be affected by the concurrent executions in the other pipelines.
pipelines. However, GitLab ensures that there are no other deployment pipelines running before
However, when it's about to trigger a deployment (child) pipeline, GitLab ensures that
triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits
there are no other deployment pipelines running, and if it's conflicted,
until those pipelines finish before running another one.
the pipeline will wait until it's finished.
```
yaml
```
yaml
# .gitlab-ci.yml (parent pipeline)
# .gitlab-ci.yml (parent pipeline)
...
@@ -3981,9 +3980,9 @@ deployment:
...
@@ -3981,9 +3980,9 @@ deployment:
script
:
echo "Deploying..."
script
:
echo "Deploying..."
```
```
Please note that
[
`strategy: depend`
](
#linking-pipelines-with-triggerstrategy
)
Note that you must define
[
`strategy: depend`
](
#linking-pipelines-with-triggerstrategy
)
must be defined with the
`trigger`
keyword. This ensures that the lock won't
with the
`trigger`
keyword. This ensures that the lock isn't released until the downstream pipeline
be relesed until the downstream pipeline has finished
.
finishes
.
### `release`
### `release`
...
...
lib/gitlab/ci/status/processable/waiting_for_resource.rb
View file @
7b83426d
...
@@ -17,8 +17,8 @@ module Gitlab
...
@@ -17,8 +17,8 @@ module Gitlab
}
}
end
end
def
self
.
matches?
(
build
,
_
)
def
self
.
matches?
(
processable
,
_
)
build
.
waiting_for_resource?
processable
.
waiting_for_resource?
end
end
end
end
end
end
...
...
spec/factories/ci/bridge.rb
View file @
7b83426d
# frozen_string_literal: true
# frozen_string_literal: true
FactoryBot
.
define
do
FactoryBot
.
define
do
factory
:ci_bridge
,
class:
'Ci::Bridge'
do
factory
:ci_bridge
,
class:
'Ci::Bridge'
,
parent: :ci_processable
do
name
{
'bridge'
}
name
{
'bridge'
}
stage
{
'test'
}
stage_idx
{
0
}
ref
{
'master'
}
tag
{
false
}
created_at
{
'2013-10-29 09:50:00 CET'
}
created_at
{
'2013-10-29 09:50:00 CET'
}
status
{
:created
}
status
{
:created
}
scheduling_type
{
'stage'
}
pipeline
factory: :ci_pipeline
trait
:variables
do
trait
:variables
do
yaml_variables
do
yaml_variables
do
...
...
spec/factories/ci/builds.rb
View file @
7b83426d
...
@@ -3,15 +3,10 @@
...
@@ -3,15 +3,10 @@
include
ActionDispatch
::
TestProcess
include
ActionDispatch
::
TestProcess
FactoryBot
.
define
do
FactoryBot
.
define
do
factory
:ci_build
,
class:
'Ci::Build'
do
factory
:ci_build
,
class:
'Ci::Build'
,
parent: :ci_processable
do
name
{
'test'
}
name
{
'test'
}
stage
{
'test'
}
stage_idx
{
0
}
ref
{
'master'
}
tag
{
false
}
add_attribute
(
:protected
)
{
false
}
add_attribute
(
:protected
)
{
false
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
created_at
{
'Di 29. Okt 09:50:00 CET 2013'
}
scheduling_type
{
'stage'
}
pending
pending
options
do
options
do
...
@@ -28,7 +23,6 @@ FactoryBot.define do
...
@@ -28,7 +23,6 @@ FactoryBot.define do
]
]
end
end
pipeline
factory: :ci_pipeline
project
{
pipeline
.
project
}
project
{
pipeline
.
project
}
trait
:degenerated
do
trait
:degenerated
do
...
@@ -79,10 +73,6 @@ FactoryBot.define do
...
@@ -79,10 +73,6 @@ 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
...
@@ -213,14 +203,6 @@ FactoryBot.define do
...
@@ -213,14 +203,6 @@ FactoryBot.define do
trigger_request
factory: :ci_trigger_request
trigger_request
factory: :ci_trigger_request
end
end
trait
:resource_group
do
waiting_for_resource_at
{
5
.
minutes
.
ago
}
after
(
:build
)
do
|
build
,
evaluator
|
build
.
resource_group
=
create
(
:ci_resource_group
,
project:
build
.
project
)
end
end
trait
:with_deployment
do
trait
:with_deployment
do
after
(
:build
)
do
|
build
,
evaluator
|
after
(
:build
)
do
|
build
,
evaluator
|
##
##
...
...
spec/factories/ci/processable.rb
0 → 100644
View file @
7b83426d
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:ci_processable
,
class:
'Ci::Processable'
do
name
{
'processable'
}
stage
{
'test'
}
stage_idx
{
0
}
ref
{
'master'
}
tag
{
false
}
pipeline
factory: :ci_pipeline
project
{
pipeline
.
project
}
scheduling_type
{
'stage'
}
trait
:waiting_for_resource
do
status
{
'waiting_for_resource'
}
end
trait
:resource_group
do
waiting_for_resource_at
{
5
.
minutes
.
ago
}
after
(
:build
)
do
|
processable
,
evaluator
|
processable
.
resource_group
=
create
(
:ci_resource_group
,
project:
processable
.
project
)
end
end
end
end
spec/features/projects/pipelines/pipeline_spec.rb
View file @
7b83426d
...
@@ -846,6 +846,28 @@ RSpec.describe 'Pipeline', :js do
...
@@ -846,6 +846,28 @@ RSpec.describe 'Pipeline', :js do
end
end
end
end
end
end
context
'when deploy job is a bridge to trigger a downstream pipeline'
do
let!
(
:deploy_job
)
do
create
(
:ci_bridge
,
:created
,
stage:
'deploy'
,
name:
'deploy'
,
stage_idx:
2
,
pipeline:
pipeline
,
project:
project
,
resource_group:
resource_group
)
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
end
end
end
end
end
end
end
...
...
spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
View file @
7b83426d
...
@@ -383,14 +383,25 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
...
@@ -383,14 +383,25 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do
end
end
context
'when job is a bridge'
do
context
'when job is a bridge'
do
let
(
:attributes
)
do
let
(
:
base_
attributes
)
do
{
{
name:
'rspec'
,
ref:
'master'
,
options:
{
trigger:
'my/project'
},
scheduling_type: :stage
name:
'rspec'
,
ref:
'master'
,
options:
{
trigger:
'my/project'
},
scheduling_type: :stage
}
}
end
end
let
(
:attributes
)
{
base_attributes
}
it
{
is_expected
.
to
be_a
(
::
Ci
::
Bridge
)
}
it
{
is_expected
.
to
be_a
(
::
Ci
::
Bridge
)
}
it
{
is_expected
.
to
be_valid
}
it
{
is_expected
.
to
be_valid
}
context
'when job belongs to a resource group'
do
let
(
:attributes
)
{
base_attributes
.
merge
(
resource_group_key:
'iOS'
)
}
it
'returns a job with resource group'
do
expect
(
subject
.
resource_group
).
not_to
be_nil
expect
(
subject
.
resource_group
.
key
).
to
eq
(
'iOS'
)
end
end
end
end
it
'memoizes a resource object'
do
it
'memoizes a resource object'
do
...
...
spec/lib/gitlab/ci/status/bridge/factory_spec.rb
View file @
7b83426d
...
@@ -117,14 +117,31 @@ RSpec.describe Gitlab::Ci::Status::Bridge::Factory do
...
@@ -117,14 +117,31 @@ RSpec.describe Gitlab::Ci::Status::Bridge::Factory do
end
end
end
end
context
'when bridge is waiting for resource'
do
let
(
:bridge
)
{
create_bridge
(
:waiting_for_resource
,
:resource_group
)
}
it
'matches correct core status'
do
expect
(
factory
.
core_status
).
to
be_a
Gitlab
::
Ci
::
Status
::
WaitingForResource
end
it
'fabricates status with correct details'
do
expect
(
status
.
text
).
to
eq
'waiting'
expect
(
status
.
group
).
to
eq
'waiting-for-resource'
expect
(
status
.
icon
).
to
eq
'status_pending'
expect
(
status
.
favicon
).
to
eq
'favicon_pending'
expect
(
status
.
illustration
).
to
include
(
:image
,
:size
,
:title
)
expect
(
status
).
not_to
have_details
end
end
private
private
def
create_bridge
(
trait
)
def
create_bridge
(
*
traits
)
upstream_project
=
create
(
:project
,
:repository
)
upstream_project
=
create
(
:project
,
:repository
)
downstream_project
=
create
(
:project
,
:repository
)
downstream_project
=
create
(
:project
,
:repository
)
upstream_pipeline
=
create
(
:ci_pipeline
,
:running
,
project:
upstream_project
)
upstream_pipeline
=
create
(
:ci_pipeline
,
:running
,
project:
upstream_project
)
trigger
=
{
trigger:
{
project:
downstream_project
.
full_path
,
branch:
'feature'
}
}
trigger
=
{
trigger:
{
project:
downstream_project
.
full_path
,
branch:
'feature'
}
}
create
(
:ci_bridge
,
trait
,
options:
trigger
,
pipeline:
upstream_pipeline
)
create
(
:ci_bridge
,
*
traits
,
options:
trigger
,
pipeline:
upstream_pipeline
)
end
end
end
end
spec/lib/gitlab/ci/status/bridge/waiting_for_resource_spec.rb
0 → 100644
View file @
7b83426d
# frozen_string_literal: true
require
'fast_spec_helper'
RSpec
.
describe
Gitlab
::
Ci
::
Status
::
Bridge
::
WaitingForResource
do
it
{
expect
(
described_class
).
to
be
<
Gitlab
::
Ci
::
Status
::
Processable
::
WaitingForResource
}
end
spec/lib/gitlab/ci/status/build/waiting_for_resource_spec.rb
0 → 100644
View file @
7b83426d
# frozen_string_literal: true
require
'fast_spec_helper'
RSpec
.
describe
Gitlab
::
Ci
::
Status
::
Build
::
WaitingForResource
do
it
{
expect
(
described_class
).
to
be
<
Gitlab
::
Ci
::
Status
::
Processable
::
WaitingForResource
}
end
spec/lib/gitlab/ci/status/processable/waiting_for_resource_spec.rb
0 → 100644
View file @
7b83426d
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Gitlab
::
Ci
::
Status
::
Processable
::
WaitingForResource
do
let
(
:user
)
{
create
(
:user
)
}
subject
do
processable
=
create
(
:ci_build
,
:waiting_for_resource
,
:resource_group
)
described_class
.
new
(
Gitlab
::
Ci
::
Status
::
Core
.
new
(
processable
,
user
))
end
describe
'#illustration'
do
it
{
expect
(
subject
.
illustration
).
to
include
(
:image
,
:size
,
:title
)
}
end
describe
'.matches?'
do
subject
{
described_class
.
matches?
(
processable
,
user
)
}
context
'when processable is waiting for resource'
do
let
(
:processable
)
{
create
(
:ci_build
,
:waiting_for_resource
)
}
it
'is a correct match'
do
expect
(
subject
).
to
be
true
end
end
context
'when processable is not waiting for resource'
do
let
(
:processable
)
{
create
(
:ci_build
)
}
it
'does not match'
do
expect
(
subject
).
to
be
false
end
end
end
end
spec/models/ci/bridge_spec.rb
View file @
7b83426d
...
@@ -80,6 +80,14 @@ RSpec.describe Ci::Bridge do
...
@@ -80,6 +80,14 @@ RSpec.describe Ci::Bridge do
end
end
end
end
it
"schedules downstream pipeline creation when the status is waiting for resource"
do
bridge
.
status
=
:waiting_for_resource
expect
(
bridge
).
to
receive
(
:schedule_downstream_pipeline!
)
bridge
.
enqueue_waiting_for_resource!
end
it
'raises error when the status is failed'
do
it
'raises error when the status is failed'
do
bridge
.
status
=
:failed
bridge
.
status
=
:failed
...
...
spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb
0 → 100644
View file @
7b83426d
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Ci
::
CreatePipelineService
,
'#execute'
do
let_it_be
(
:group
)
{
create
(
:group
,
name:
'my-organization'
)
}
let
(
:upstream_project
)
{
create
(
:project
,
:repository
,
name:
'upstream'
,
group:
group
)
}
let
(
:downstram_project
)
{
create
(
:project
,
:repository
,
name:
'downstream'
,
group:
group
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:service
)
do
described_class
.
new
(
upstream_project
,
user
,
ref:
'master'
)
end
before
do
upstream_project
.
add_developer
(
user
)
downstram_project
.
add_developer
(
user
)
create_gitlab_ci_yml
(
upstream_project
,
upstream_config
)
create_gitlab_ci_yml
(
downstram_project
,
downstream_config
)
end
context
'with resource group'
,
:aggregate_failures
do
let
(
:upstream_config
)
do
<<~
YAML
instrumentation_test:
stage: test
resource_group: iOS
trigger:
project: my-organization/downstream
strategy: depend
YAML
end
let
(
:downstream_config
)
do
<<~
YAML
test:
script: echo "Testing..."
YAML
end
it
'creates bridge job with resource group'
do
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
pipeline
).
to
be_created_successfully
expect
(
pipeline
.
triggered_pipelines
).
not_to
be_exist
expect
(
upstream_project
.
resource_groups
.
count
).
to
eq
(
1
)
expect
(
test
).
to
be_a
Ci
::
Bridge
expect
(
test
).
to
be_waiting_for_resource
expect
(
test
.
resource_group
.
key
).
to
eq
(
'iOS'
)
end
context
'when sidekiq processes the job'
,
:sidekiq_inline
do
it
'transitions to pending status and triggers a downstream pipeline'
do
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
test
).
to
be_pending
expect
(
pipeline
.
triggered_pipelines
.
count
).
to
eq
(
1
)
end
context
'when the resource is occupied by the other bridge'
do
before
do
resource_group
=
create
(
:ci_resource_group
,
project:
upstream_project
,
key:
'iOS'
)
resource_group
.
assign_resource_to
(
create
(
:ci_build
,
project:
upstream_project
))
end
it
'stays waiting for resource'
do
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
test
).
to
be_waiting_for_resource
expect
(
pipeline
.
triggered_pipelines
.
count
).
to
eq
(
0
)
end
end
end
end
def
create_pipeline!
service
.
execute
(
:push
)
end
def
create_gitlab_ci_yml
(
project
,
content
)
project
.
repository
.
create_file
(
user
,
'.gitlab-ci.yml'
,
content
,
branch_name:
'master'
,
message:
'test'
)
end
end
spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb
View file @
7b83426d
...
@@ -84,19 +84,46 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
...
@@ -84,19 +84,46 @@ RSpec.describe Ci::CreatePipelineService, '#execute' do
stage: test
stage: test
resource_group: iOS
resource_group: iOS
trigger:
trigger:
include:
include:
path/to/child.yml
- local: path/to/child.yml
strategy: depend
YAML
YAML
end
end
it
'creates bridge job
but still resource group is no-o
p'
,
:aggregate_failures
do
it
'creates bridge job
with resource grou
p'
,
:aggregate_failures
do
pipeline
=
create_pipeline!
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
pipeline
).
to
be_created_successfully
expect
(
pipeline
).
to
be_persisted
expect
(
pipeline
.
triggered_pipelines
).
not_to
be_exist
expect
(
test
).
to
be_a
Ci
::
Bridge
expect
(
project
.
resource_groups
.
count
).
to
eq
(
1
)
expect
(
project
.
resource_groups
.
count
).
to
eq
(
1
)
expect
(
test
).
to
be_a
Ci
::
Bridge
expect
(
test
).
to
be_waiting_for_resource
expect
(
test
.
resource_group
.
key
).
to
eq
(
'iOS'
)
end
context
'when sidekiq processes the job'
,
:sidekiq_inline
do
it
'transitions to pending status and triggers a downstream pipeline'
do
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
test
).
to
be_pending
expect
(
pipeline
.
triggered_pipelines
.
count
).
to
eq
(
1
)
end
context
'when the resource is occupied by the other bridge'
do
before
do
resource_group
=
create
(
:ci_resource_group
,
project:
project
,
key:
'iOS'
)
resource_group
.
assign_resource_to
(
create
(
:ci_build
,
project:
project
))
end
it
'stays waiting for resource'
do
pipeline
=
create_pipeline!
test
=
pipeline
.
statuses
.
find_by
(
name:
'instrumentation_test'
)
expect
(
test
).
to
be_waiting_for_resource
expect
(
pipeline
.
triggered_pipelines
.
count
).
to
eq
(
0
)
end
end
end
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment