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
58f27851
Commit
58f27851
authored
Apr 23, 2021
by
Adam Hegyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use aggregated DORA API for DF
Use aggregated DORA API for deployment frequency and count in VSA.
parent
4cd14988
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
207 additions
and
85 deletions
+207
-85
ee/app/services/dora/aggregate_metrics_service.rb
ee/app/services/dora/aggregate_metrics_service.rb
+11
-1
ee/config/feature_flags/development/dora_deployment_frequency_in_vsa.yml
...re_flags/development/dora_deployment_frequency_in_vsa.yml
+8
-0
ee/lib/gitlab/analytics/cycle_analytics/summary/group/deploy.rb
.../gitlab/analytics/cycle_analytics/summary/group/deploy.rb
+39
-9
ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_summary_spec.rb
...ytics/cycle_analytics/summary/group/stage_summary_spec.rb
+123
-75
ee/spec/models/analytics/cycle_analytics/group_level_spec.rb
ee/spec/models/analytics/cycle_analytics/group_level_spec.rb
+5
-0
ee/spec/services/dora/aggregate_metrics_service_spec.rb
ee/spec/services/dora/aggregate_metrics_service_spec.rb
+18
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/services/dora/aggregate_metrics_service.rb
View file @
58f27851
...
@@ -35,6 +35,10 @@ module Dora
...
@@ -35,6 +35,10 @@ module Dora
return
error
(
_
(
'Container must be a project or a group.'
),
:bad_request
)
return
error
(
_
(
'Container must be a project or a group.'
),
:bad_request
)
end
end
if
group_project_ids
.
present?
&&
!
group?
return
error
(
_
(
'The group_project_ids parameter is only allowed for a group'
),
:bad_request
)
end
unless
::
Dora
::
DailyMetrics
::
AVAILABLE_INTERVALS
.
include?
(
interval
)
unless
::
Dora
::
DailyMetrics
::
AVAILABLE_INTERVALS
.
include?
(
interval
)
return
error
(
_
(
"The interval must be one of %{intervals}."
)
%
{
intervals:
::
Dora
::
DailyMetrics
::
AVAILABLE_INTERVALS
.
join
(
','
)
},
return
error
(
_
(
"The interval must be one of %{intervals}."
)
%
{
intervals:
::
Dora
::
DailyMetrics
::
AVAILABLE_INTERVALS
.
join
(
','
)
},
:bad_request
)
:bad_request
)
...
@@ -72,7 +76,9 @@ module Dora
...
@@ -72,7 +76,9 @@ module Dora
# - In the subsequent projects, the assigned role at the group-level
# - In the subsequent projects, the assigned role at the group-level
# can't be lowered. For example, if the user is reporter at group-level,
# can't be lowered. For example, if the user is reporter at group-level,
# the user can be developer in subsequent projects, but can't be guest.
# the user can be developer in subsequent projects, but can't be guest.
container
.
all_projects
projects
=
container
.
all_projects
projects
=
projects
.
id_in
(
group_project_ids
)
if
group_project_ids
.
any?
projects
end
end
end
end
...
@@ -103,5 +109,9 @@ module Dora
...
@@ -103,5 +109,9 @@ module Dora
def
metric
def
metric
params
[
:metric
]
params
[
:metric
]
end
end
def
group_project_ids
Array
(
params
[
:group_project_ids
])
end
end
end
end
end
ee/config/feature_flags/development/dora_deployment_frequency_in_vsa.yml
0 → 100644
View file @
58f27851
---
name
:
dora_deployment_frequency_in_vsa
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60367
rollout_issue_url
:
https://gitlab.com/gitlab-org/gitlab/-/issues/329178
milestone
:
'
13.12'
type
:
development
group
:
group::optimize
default_enabled
:
false
ee/lib/gitlab/analytics/cycle_analytics/summary/group/deploy.rb
View file @
58f27851
...
@@ -18,18 +18,48 @@ module Gitlab
...
@@ -18,18 +18,48 @@ module Gitlab
private
private
# rubocop: disable CodeReuse/ActiveRecord
def
deployments_count
def
deployments_count
@deployments_count
||=
begin
@deployments_count
||=
if
Feature
.
enabled?
(
:dora_deployment_frequency_in_vsa
)
deployments
=
DeploymentsFinder
deployment_count_via_dora_api
.
new
(
group:
group
,
finished_after:
options
[
:from
],
finished_before:
options
[
:to
],
status: :success
)
else
.
execute
deployment_count_via_finder
end
deployments
=
deployments
.
where
(
project_id:
options
[
:projects
])
if
options
[
:projects
].
present?
end
deployments
.
count
end
# rubocop: disable CodeReuse/ActiveRecord
def
deployment_count_via_finder
deployments
=
DeploymentsFinder
.
new
(
group:
group
,
finished_after:
options
[
:from
],
finished_before:
options
[
:to
],
status: :success
)
.
execute
deployments
=
deployments
.
where
(
project_id:
options
[
:projects
])
if
options
[
:projects
].
present?
deployments
.
count
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
def
deployment_count_via_dora_api
result
=
Dora
::
AggregateMetricsService
.
new
(
container:
group
,
current_user:
options
[
:current_user
],
params:
dora_aggregate_metrics_params
).
execute
result
[
:status
]
==
:success
?
(
result
[
:data
]
||
0
)
:
0
end
def
dora_aggregate_metrics_params
params
=
{
start_date:
options
[
:from
].
to_date
,
end_date:
(
options
[
:to
]
||
Date
.
today
).
to_date
,
interval:
'all'
,
environment_tier:
'production'
,
metric:
'deployment_frequency'
}
params
[
:group_project_ids
]
=
options
[
:projects
]
if
options
[
:projects
].
present?
params
end
end
end
end
end
end
end
...
...
ee/spec/lib/gitlab/analytics/cycle_analytics/summary/group/stage_summary_spec.rb
View file @
58f27851
...
@@ -127,116 +127,164 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
...
@@ -127,116 +127,164 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Summary::Group::StageSummary d
end
end
end
end
describe
"#deploys"
do
def
create_deployment
(
args
)
context
'with from date'
do
project
=
args
[
:project
]
before
do
environment
=
project
.
environments
.
production
.
first
||
create
(
:environment
,
:production
,
project:
project
)
travel_to
(
5
.
days
.
ago
)
{
create
(
:deployment
,
:success
,
project:
project
,
finished_at:
Time
.
zone
.
now
)
}
create
(
:deployment
,
:success
,
args
.
merge
(
environment:
environment
))
travel_to
(
5
.
days
.
from_now
)
{
create
(
:deployment
,
:success
,
project:
project
,
finished_at:
Time
.
zone
.
now
)
}
travel_to
(
5
.
days
.
ago
)
{
create
(
:deployment
,
:success
,
project:
project_2
,
finished_at:
Time
.
zone
.
now
)
}
travel_to
(
5
.
days
.
from_now
)
{
create
(
:deployment
,
:success
,
project:
project_2
,
finished_at:
Time
.
zone
.
now
)
}
end
it
"finds the number of deploys made created after it"
do
# this is needed for the dora_deployment_frequency_in_vsa feature flag so we have aggregated data
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
::
Dora
::
DailyMetrics
::
RefreshWorker
.
new
.
perform
(
environment
.
id
,
Time
.
current
.
to_date
.
to_s
)
end
end
it
'returns the localized title'
do
shared_examples
'VSA deployment related metrics'
do
Gitlab
::
I18n
.
with_locale
(
:ru
)
do
describe
"#deploys"
do
expect
(
subject
.
second
[
:title
]).
to
eq
(
n_
(
'Deploy'
,
'Deploys'
,
2
))
let
(
:current_time
)
{
Time
.
current
}
end
let
(
:one_day_ago
)
{
current_time
-
1
.
day
}
end
let
(
:two_days_ago
)
{
current_time
-
2
.
days
}
let
(
:five_days_ago
)
{
current_time
-
5
.
days
}
let
(
:ten_days_ago
)
{
current_time
-
10
.
days
}
context
'with from date'
do
subject
{
described_class
.
new
(
group
,
options:
{
from:
two_days_ago
,
current_user:
user
}).
data
}
context
'with subgroups'
do
before
do
before
do
travel_to
(
5
.
days
.
from_now
)
do
stub_licensed_features
(
dora4_analytics:
true
)
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
,
parent:
group
)))
travel_to
(
five_days_ago
)
do
create_deployment
(
project:
project
,
finished_at:
Time
.
current
)
create_deployment
(
project:
project_2
,
finished_at:
Time
.
current
)
end
travel_to
(
current_time
)
do
create_deployment
(
project:
project
,
finished_at:
Time
.
current
)
create_deployment
(
project:
project_2
,
finished_at:
Time
.
current
)
end
end
end
end
it
"finds
deploys from them
"
do
it
"finds
the number of deploys made created after it
"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'
3
'
)
expect
(
subject
.
second
[
:value
]).
to
eq
(
'
2
'
)
end
end
end
context
'with projects specified in options'
do
it
'returns the localized title'
do
before
do
Gitlab
::
I18n
.
with_locale
(
:ru
)
do
travel_to
(
5
.
days
.
from_now
)
do
expect
(
subject
.
second
[
:title
]).
to
eq
(
n_
(
'Deploy'
,
'Deploys'
,
2
))
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
group
,
name:
'not_applicable'
))
end
end
end
end
subject
{
described_class
.
new
(
group
,
options:
{
from:
Time
.
now
,
current_user:
user
,
projects:
[
project
.
id
,
project_2
.
id
]
}).
data
}
context
'with subgroups'
do
before
do
travel_to
(
current_time
)
do
create_deployment
(
project:
project
,
finished_at:
Time
.
current
)
end
end
it
'shows deploys from those projects'
do
it
"finds deploys from them"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
expect
(
subject
.
second
[
:value
]).
to
eq
(
'3'
)
end
end
end
end
context
'when `from` and `to` parameters are provided'
do
context
'with projects specified in options'
do
subject
{
described_class
.
new
(
group
,
options:
{
from:
10
.
days
.
ago
,
to:
Time
.
now
,
current_user:
user
}).
data
}
before
do
travel_to
(
Date
.
today
)
do
create_deployment
(
finished_at:
current_time
,
project:
create
(
:project
,
:repository
,
namespace:
group
,
name:
'not_applicable'
))
end
end
it
'finds deployments from 5 days ago'
do
subject
{
described_class
.
new
(
group
,
options:
{
from:
one_day_ago
,
current_user:
user
,
projects:
[
project
.
id
,
project_2
.
id
]
}).
data
}
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
end
end
end
context
'with other projects'
do
it
'shows deploys from those projects'
do
before
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
travel_to
(
5
.
days
.
from_now
)
do
end
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
)))
end
end
end
it
"doesn't find deploys from them"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'-'
)
end
end
describe
'#deployment_frequency'
do
context
'when `from` and `to` parameters are provided'
do
let
(
:from
)
{
6
.
days
.
ago
}
subject
{
described_class
.
new
(
group
,
options:
{
from:
ten_days_ago
,
to:
one_day_ago
,
current_user:
user
}).
data
}
let
(
:to
)
{
nil
}
subject
do
it
'finds deployments from 5 days ago'
do
described_class
.
new
(
group
,
options:
{
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
from:
from
,
end
to:
to
,
end
current_user:
user
}).
data
.
third
end
end
it
'includes the unit: `per day`'
do
context
'with other projects'
do
expect
(
subject
[
:unit
]).
to
eq
(
_
(
'per day'
))
before
do
end
travel_to
(
one_day_ago
)
do
create_deployment
(
finished_at:
Time
.
current
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
)))
end
end
before
do
it
"doesn't find deploys from them"
do
travel_to
(
5
.
days
.
ago
)
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'-'
)
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
project
)
end
end
end
end
context
'when `to` is nil'
do
describe
'#deployment_frequency'
do
it
'includes range until now'
do
let
(
:from
)
{
ten_days_ago
}
# 1 deployment over 7 days
let
(
:to
)
{
nil
}
expect
(
subject
[
:value
]).
to
eq
(
'0.1'
)
subject
do
described_class
.
new
(
group
,
options:
{
from:
from
,
to:
to
,
current_user:
user
}).
data
.
third
end
end
end
context
'when `to` is given
'
do
it
'includes the unit: `per day`
'
do
let
(
:from
)
{
10
.
days
.
ago
}
expect
(
subject
[
:unit
]).
to
eq
(
_
(
'per day'
))
let
(
:to
)
{
10
.
days
.
from_now
}
end
before
do
before
do
travel_to
(
5
.
days
.
from_now
)
do
stub_licensed_features
(
dora4_analytics:
true
)
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
project
)
travel_to
(
five_days_ago
)
do
create_deployment
(
finished_at:
Time
.
current
,
project:
project
)
end
end
context
'when `to` is nil'
do
it
'includes range until now'
do
# 1 deployment over 7 days
expect
(
subject
[
:value
]).
to
eq
(
'0.1'
)
end
end
end
end
it
'returns deployment frequency within `from` and `to` range'
do
context
'when `to` is given'
do
# 2 deployments over 20 days
let
(
:from
)
{
ten_days_ago
}
expect
(
subject
[
:value
]).
to
eq
(
'0.1'
)
let
(
:to
)
{
10
.
days
.
from_now
}
before
do
travel_to
(
Date
.
yesterday
)
do
create_deployment
(
finished_at:
Time
.
current
,
project:
project
)
end
end
it
'returns deployment frequency within `from` and `to` range'
do
# 2 deployments over 20 days
expect
(
subject
[
:value
]).
to
eq
(
'0.1'
)
end
end
end
end
end
end
end
end
end
context
'when dora_deployment_frequency_in_vsa feature flag is enabled'
do
before
do
stub_feature_flags
(
dora_deployment_frequency_in_vsa:
true
)
expect
(
Dora
::
AggregateMetricsService
).
to
receive
(
:new
).
and_call_original
end
it_behaves_like
'VSA deployment related metrics'
end
context
'when dora_deployment_frequency_in_vsa feature flag is disabled'
do
before
do
stub_feature_flags
(
dora_deployment_frequency_in_vsa:
false
)
expect
(
Dora
::
AggregateMetricsService
).
not_to
receive
(
:new
)
end
it_behaves_like
'VSA deployment related metrics'
end
end
end
ee/spec/models/analytics/cycle_analytics/group_level_spec.rb
View file @
58f27851
...
@@ -27,8 +27,13 @@ RSpec.describe Analytics::CycleAnalytics::GroupLevel do
...
@@ -27,8 +27,13 @@ RSpec.describe Analytics::CycleAnalytics::GroupLevel do
describe
'#summary'
do
describe
'#summary'
do
before
do
before
do
stub_licensed_features
(
dora4_analytics:
true
)
create_cycle
(
user
,
project
,
issue
,
mr
,
milestone
,
pipeline
)
create_cycle
(
user
,
project
,
issue
,
mr
,
milestone
,
pipeline
)
deploy_master
(
user
,
project
)
deploy_master
(
user
,
project
)
environment
=
project
.
environments
.
production
.
first
::
Dora
::
DailyMetrics
::
RefreshWorker
.
new
.
perform
(
environment
.
id
,
pipeline
.
created_at
.
to_date
.
to_s
)
end
end
it
'returns medians for each stage for a specific group'
do
it
'returns medians for each stage for a specific group'
do
...
...
ee/spec/services/dora/aggregate_metrics_service_spec.rb
View file @
58f27851
...
@@ -144,6 +144,15 @@ RSpec.describe Dora::AggregateMetricsService do
...
@@ -144,6 +144,15 @@ RSpec.describe Dora::AggregateMetricsService do
expect
(
subject
[
:data
]).
to
eq
([{
Time
.
current
.
to_date
.
to_s
=>
1
,
'date'
=>
Time
.
current
.
to_date
.
to_s
,
'value'
=>
1
}])
expect
(
subject
[
:data
]).
to
eq
([{
Time
.
current
.
to_date
.
to_s
=>
1
,
'date'
=>
Time
.
current
.
to_date
.
to_s
,
'value'
=>
1
}])
end
end
end
end
context
'when group_project_ids parameter is given'
do
let
(
:extra_params
)
{
{
interval:
Dora
::
DailyMetrics
::
INTERVAL_ALL
,
group_project_ids:
[
1
]
}
}
it_behaves_like
'request failure'
do
let
(
:message
)
{
'The group_project_ids parameter is only allowed for a group'
}
let
(
:http_status
)
{
:bad_request
}
end
end
end
end
context
'when container is a group'
do
context
'when container is a group'
do
...
@@ -196,6 +205,15 @@ RSpec.describe Dora::AggregateMetricsService do
...
@@ -196,6 +205,15 @@ RSpec.describe Dora::AggregateMetricsService do
expect
(
subject
[
:data
]).
to
eq
(
3
)
expect
(
subject
[
:data
]).
to
eq
(
3
)
end
end
end
end
context
'when group_project_ids parameter is given'
do
let
(
:extra_params
)
{
{
interval:
Dora
::
DailyMetrics
::
INTERVAL_ALL
,
group_project_ids:
[
project_2
.
id
]
}
}
it
'returns the aggregated data'
do
expect
(
subject
[
:status
]).
to
eq
(
:success
)
expect
(
subject
[
:data
]).
to
eq
(
1
)
end
end
end
end
context
'when container is nil'
do
context
'when container is nil'
do
...
...
locale/gitlab.pot
View file @
58f27851
...
@@ -31862,6 +31862,9 @@ msgstr ""
...
@@ -31862,6 +31862,9 @@ msgstr ""
msgid "The group will be placed in 'pending removal' state"
msgid "The group will be placed in 'pending removal' state"
msgstr ""
msgstr ""
msgid "The group_project_ids parameter is only allowed for a group"
msgstr ""
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
msgstr ""
...
...
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