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
d886be07
Commit
d886be07
authored
Apr 12, 2022
by
Bala Kumar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Run all deployment jobs for the common pipeline with same environment
Changelog: changed
parent
855a4095
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
281 additions
and
50 deletions
+281
-50
app/controllers/projects/environments_controller.rb
app/controllers/projects/environments_controller.rb
+3
-3
app/models/environment.rb
app/models/environment.rb
+43
-10
app/policies/environment_policy.rb
app/policies/environment_policy.rb
+3
-3
app/serializers/environment_entity.rb
app/serializers/environment_entity.rb
+1
-1
app/services/environments/stop_service.rb
app/services/environments/stop_service.rb
+1
-1
app/workers/environments/auto_stop_worker.rb
app/workers/environments/auto_stop_worker.rb
+4
-2
config/feature_flags/development/environment_multiple_stop_actions.yml
...e_flags/development/environment_multiple_stop_actions.yml
+8
-0
lib/api/environments.rb
lib/api/environments.rb
+1
-1
spec/controllers/projects/environments_controller_spec.rb
spec/controllers/projects/environments_controller_spec.rb
+22
-6
spec/models/environment_spec.rb
spec/models/environment_spec.rb
+185
-21
spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
...les/serializers/environment_serializer_shared_examples.rb
+10
-2
No files found.
app/controllers/projects/environments_controller.rb
View file @
d886be07
...
...
@@ -104,11 +104,11 @@ class Projects::EnvironmentsController < Projects::ApplicationController
def
stop
return
render_404
unless
@environment
.
available?
stop_action
=
@environment
.
stop_with_action
!
(
current_user
)
stop_action
s
=
@environment
.
stop_with_actions
!
(
current_user
)
action_or_env_url
=
if
stop_action
polymorphic_url
([
project
,
stop_action
])
if
stop_action
s
&
.
count
==
1
polymorphic_url
([
project
,
stop_action
s
.
first
])
else
project_environment_url
(
project
,
@environment
)
end
...
...
app/models/environment.rb
View file @
d886be07
...
...
@@ -59,7 +59,7 @@ class Environment < ApplicationRecord
allow_nil:
true
,
addressable_url:
true
delegate
:
stop_action
,
:
manual_actions
,
to: :last_deployment
,
allow_nil:
true
delegate
:manual_actions
,
to: :last_deployment
,
allow_nil:
true
delegate
:auto_rollback_enabled?
,
to: :project
scope
:available
,
->
{
with_state
(
:available
)
}
...
...
@@ -185,6 +185,23 @@ class Environment < ApplicationRecord
last_deployment
&
.
deployable
end
def
last_deployment_pipeline
last_deployable
&
.
pipeline
end
# This method returns the deployment records of the last deployment pipeline, that successfully executed to this environment.
# e.g.
# A pipeline contains
# - deploy job A => production environment
# - deploy job B => production environment
# In this case, `last_deployment_group` returns both deployments, whereas `last_deployable` returns only B.
def
last_deployment_group
return
Deployment
.
none
unless
last_deployment_pipeline
successful_deployments
.
where
(
deployable_id:
last_deployment_pipeline
.
latest_builds
.
pluck
(
:id
))
end
# NOTE: Below assocation overrides is a workaround for issue https://gitlab.com/gitlab-org/gitlab/-/issues/339908
# It helps to avoid cross joins with the CI database.
# Caveat: It also overrides and losses the default AR caching mechanism.
...
...
@@ -255,8 +272,8 @@ class Environment < ApplicationRecord
external_url
.
gsub
(
%r{
\A
.*?://}
,
''
)
end
def
stop_action_available?
available?
&&
stop_action
.
present?
def
stop_action
s
_available?
available?
&&
stop_action
s
.
present?
end
def
cancel_deployment_jobs!
...
...
@@ -269,18 +286,34 @@ class Environment < ApplicationRecord
end
end
def
stop_with_action!
(
current_user
)
def
stop_with_action
s
!
(
current_user
)
return
unless
available?
stop!
return
unless
stop_action
actions
=
[]
stop_actions
.
each
do
|
stop_action
|
Gitlab
::
OptimisticLocking
.
retry_lock
(
stop_action
,
name:
'environment_stop_with_action
'
name:
'environment_stop_with_actions
'
)
do
|
build
|
build
&
.
play
(
current_user
)
actions
<<
build
.
play
(
current_user
)
end
end
actions
end
def
stop_actions
strong_memoize
(
:stop_actions
)
do
if
::
Feature
.
enabled?
(
:environment_multiple_stop_actions
,
project
,
default_enabled: :yaml
)
# Fix N+1 queries it brings to the serializer.
# Tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/358780
last_deployment_group
.
map
(
&
:stop_action
).
compact
else
[
last_deployment
&
.
stop_action
].
compact
end
end
end
...
...
app/policies/environment_policy.rb
View file @
d886be07
...
...
@@ -4,12 +4,12 @@ class EnvironmentPolicy < BasePolicy
delegate
{
@subject
.
project
}
condition
(
:stop_with_deployment_allowed
)
do
@subject
.
stop_action_available?
&&
can?
(
:create_deployment
)
&&
can?
(
:update_build
,
@subject
.
stop_action
)
@subject
.
stop_action
s
_available?
&&
can?
(
:create_deployment
)
&&
can?
(
:update_build
,
@subject
.
stop_action
s
.
last
)
end
condition
(
:stop_with_update_allowed
)
do
!
@subject
.
stop_action_available?
&&
can?
(
:update_environment
,
@subject
)
!
@subject
.
stop_action
s
_available?
&&
can?
(
:update_environment
,
@subject
)
end
condition
(
:stopped
)
do
...
...
app/serializers/environment_entity.rb
View file @
d886be07
...
...
@@ -18,7 +18,7 @@ class EnvironmentEntity < Grape::Entity
expose
:environment_type
expose
:name_without_type
expose
:last_deployment
,
using:
DeploymentEntity
expose
:stop_action_available?
,
as: :has_stop_action
expose
:stop_action
s
_available?
,
as: :has_stop_action
expose
:rollout_status
,
if:
->
(
*
)
{
can_read_deploy_board?
},
using:
RolloutStatusEntity
expose
:tier
...
...
app/services/environments/stop_service.rb
View file @
d886be07
...
...
@@ -7,7 +7,7 @@ module Environments
def
execute
(
environment
)
return
unless
can?
(
current_user
,
:stop_environment
,
environment
)
environment
.
stop_with_action!
(
current_user
)
environment
.
stop_with_action
s
!
(
current_user
)
end
def
execute_for_branch
(
branch_name
)
...
...
app/workers/environments/auto_stop_worker.rb
View file @
d886be07
...
...
@@ -10,8 +10,10 @@ module Environments
def
perform
(
environment_id
,
params
=
{})
Environment
.
find_by_id
(
environment_id
).
try
do
|
environment
|
user
=
environment
.
stop_action
&
.
user
environment
.
stop_with_action!
(
user
)
stop_actions
=
environment
.
stop_actions
user
=
stop_actions
.
last
&
.
user
environment
.
stop_with_actions!
(
user
)
end
end
end
...
...
config/feature_flags/development/environment_multiple_stop_actions.yml
0 → 100644
View file @
d886be07
---
name
:
environment_multiple_stop_actions
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84922
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/358911
milestone
:
'
14.10'
type
:
development
group
:
group::release
default_enabled
:
false
lib/api/environments.rb
View file @
d886be07
...
...
@@ -131,7 +131,7 @@ module API
environment
=
user_project
.
environments
.
find
(
params
[
:environment_id
])
authorize!
:stop_environment
,
environment
environment
.
stop_with_action!
(
current_user
)
environment
.
stop_with_action
s
!
(
current_user
)
status
200
present
environment
,
with:
Entities
::
Environment
,
current_user:
current_user
...
...
spec/controllers/projects/environments_controller_spec.rb
View file @
d886be07
...
...
@@ -254,38 +254,54 @@ RSpec.describe Projects::EnvironmentsController do
end
describe
'PATCH #stop'
do
subject
{
patch
:stop
,
params:
environment_params
(
format: :json
)
}
context
'when env not available'
do
it
'returns 404'
do
allow_any_instance_of
(
Environment
).
to
receive
(
:available?
)
{
false
}
patch
:stop
,
params:
environment_params
(
format: :json
)
subject
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'when stop action'
do
it
'returns action url'
do
it
'returns action url
for single stop action
'
do
action
=
create
(
:ci_build
,
:manual
)
allow_any_instance_of
(
Environment
)
.
to
receive_messages
(
available?:
true
,
stop_with_action
!:
action
)
.
to
receive_messages
(
available?:
true
,
stop_with_action
s!:
[
action
]
)
patch
:stop
,
params:
environment_params
(
format: :json
)
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
eq
(
{
'redirect_url'
=>
project_job_url
(
project
,
action
)
})
end
it
'returns environment url for multiple stop actions'
do
actions
=
create_list
(
:ci_build
,
2
,
:manual
)
allow_any_instance_of
(
Environment
)
.
to
receive_messages
(
available?:
true
,
stop_with_actions!:
actions
)
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
eq
(
{
'redirect_url'
=>
project_environment_url
(
project
,
environment
)
})
end
end
context
'when no stop action'
do
it
'returns env url'
do
allow_any_instance_of
(
Environment
)
.
to
receive_messages
(
available?:
true
,
stop_with_action!:
nil
)
.
to
receive_messages
(
available?:
true
,
stop_with_action
s
!:
nil
)
patch
:stop
,
params:
environment_params
(
format: :json
)
subject
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
eq
(
...
...
spec/models/environment_spec.rb
View file @
d886be07
This diff is collapsed.
Click to expand it.
spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
View file @
d886be07
...
...
@@ -8,7 +8,11 @@ RSpec.shared_examples 'avoid N+1 on environments serialization' do |ee: false|
create_environment_with_associations
(
project
)
create_environment_with_associations
(
project
)
expect
{
serialize
(
grouping:
true
)
}.
not_to
exceed_query_limit
(
control
.
count
)
# Fix N+1 queries introduced by multi stop_actions for environment.
# Tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/358780
relax_count
=
14
expect
{
serialize
(
grouping:
true
)
}.
not_to
exceed_query_limit
(
control
.
count
+
relax_count
)
end
it
'avoids N+1 database queries without grouping'
,
:request_store
do
...
...
@@ -19,7 +23,11 @@ RSpec.shared_examples 'avoid N+1 on environments serialization' do |ee: false|
create_environment_with_associations
(
project
)
create_environment_with_associations
(
project
)
expect
{
serialize
(
grouping:
false
)
}.
not_to
exceed_query_limit
(
control
.
count
)
# Fix N+1 queries introduced by multi stop_actions for environment.
# Tracked in https://gitlab.com/gitlab-org/gitlab/-/issues/358780
relax_count
=
14
expect
{
serialize
(
grouping:
false
)
}.
not_to
exceed_query_limit
(
control
.
count
+
relax_count
)
end
it
'does not preload for environments that does not exist in the page'
,
:request_store
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment