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
return
error
(
_
(
'Container must be a project or a group.'
),
:bad_request
)
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
)
return
error
(
_
(
"The interval must be one of %{intervals}."
)
%
{
intervals:
::
Dora
::
DailyMetrics
::
AVAILABLE_INTERVALS
.
join
(
','
)
},
:bad_request
)
...
...
@@ -72,7 +76,9 @@ module Dora
# - 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,
# 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
...
...
@@ -103,5 +109,9 @@ module Dora
def
metric
params
[
:metric
]
end
def
group_project_ids
Array
(
params
[
:group_project_ids
])
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
private
# rubocop: disable CodeReuse/ActiveRecord
def
deployments_count
@deployments_count
||=
begin
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
@deployments_count
||=
if
Feature
.
enabled?
(
:dora_deployment_frequency_in_vsa
)
deployment_count_via_dora_api
else
deployment_count_via_finder
end
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
# 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
...
...
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
end
end
describe
"#deploys"
do
context
'with from date'
do
before
do
travel_to
(
5
.
days
.
ago
)
{
create
(
:deployment
,
:success
,
project:
project
,
finished_at:
Time
.
zone
.
now
)
}
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
def
create_deployment
(
args
)
project
=
args
[
:project
]
environment
=
project
.
environments
.
production
.
first
||
create
(
:environment
,
:production
,
project:
project
)
create
(
:deployment
,
:success
,
args
.
merge
(
environment:
environment
))
it
"finds the number of deploys made created after it"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
end
# this is needed for the dora_deployment_frequency_in_vsa feature flag so we have aggregated data
::
Dora
::
DailyMetrics
::
RefreshWorker
.
new
.
perform
(
environment
.
id
,
Time
.
current
.
to_date
.
to_s
)
end
it
'returns the localized title'
do
Gitlab
::
I18n
.
with_locale
(
:ru
)
do
expect
(
subject
.
second
[
:title
]).
to
eq
(
n_
(
'Deploy'
,
'Deploys'
,
2
))
end
end
shared_examples
'VSA deployment related metrics'
do
describe
"#deploys"
do
let
(
:current_time
)
{
Time
.
current
}
let
(
:one_day_ago
)
{
current_time
-
1
.
day
}
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
travel_to
(
5
.
days
.
from_now
)
do
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
,
parent:
group
)))
stub_licensed_features
(
dora4_analytics:
true
)
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
it
"finds
deploys from them
"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'
3
'
)
it
"finds
the number of deploys made created after it
"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'
2
'
)
end
end
context
'with projects specified in options'
do
before
do
travel_to
(
5
.
days
.
from_now
)
do
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
group
,
name:
'not_applicable'
))
it
'returns the localized title'
do
Gitlab
::
I18n
.
with_locale
(
:ru
)
do
expect
(
subject
.
second
[
:title
]).
to
eq
(
n_
(
'Deploy'
,
'Deploys'
,
2
))
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
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
it
"finds deploys from them"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'3'
)
end
end
end
context
'when `from` and `to` parameters are provided'
do
subject
{
described_class
.
new
(
group
,
options:
{
from:
10
.
days
.
ago
,
to:
Time
.
now
,
current_user:
user
}).
data
}
context
'with projects specified in options'
do
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
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
end
end
end
subject
{
described_class
.
new
(
group
,
options:
{
from:
one_day_ago
,
current_user:
user
,
projects:
[
project
.
id
,
project_2
.
id
]
}).
data
}
context
'with other projects'
do
before
do
travel_to
(
5
.
days
.
from_now
)
do
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
)))
it
'shows deploys from those projects'
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
end
end
end
it
"doesn't find deploys from them"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'-'
)
end
end
describe
'#deployment_frequency'
do
let
(
:from
)
{
6
.
days
.
ago
}
let
(
:to
)
{
nil
}
context
'when `from` and `to` parameters are provided'
do
subject
{
described_class
.
new
(
group
,
options:
{
from:
ten_days_ago
,
to:
one_day_ago
,
current_user:
user
}).
data
}
subject
do
described_class
.
new
(
group
,
options:
{
from:
from
,
to:
to
,
current_user:
user
}).
data
.
third
it
'finds deployments from 5 days ago'
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'2'
)
end
end
end
it
'includes the unit: `per day`'
do
expect
(
subject
[
:unit
]).
to
eq
(
_
(
'per day'
))
end
context
'with other projects'
do
before
do
travel_to
(
one_day_ago
)
do
create_deployment
(
finished_at:
Time
.
current
,
project:
create
(
:project
,
:repository
,
namespace:
create
(
:group
)))
end
end
before
do
travel_to
(
5
.
days
.
ago
)
do
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
project
)
it
"doesn't find deploys from them"
do
expect
(
subject
.
second
[
:value
]).
to
eq
(
'-'
)
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'
)
describe
'#deployment_frequency'
do
let
(
:from
)
{
ten_days_ago
}
let
(
:to
)
{
nil
}
subject
do
described_class
.
new
(
group
,
options:
{
from:
from
,
to:
to
,
current_user:
user
}).
data
.
third
end
end
context
'when `to` is given
'
do
let
(
:from
)
{
10
.
days
.
ago
}
let
(
:to
)
{
10
.
days
.
from_now
}
it
'includes the unit: `per day`
'
do
expect
(
subject
[
:unit
]).
to
eq
(
_
(
'per day'
))
end
before
do
travel_to
(
5
.
days
.
from_now
)
do
create
(
:deployment
,
:success
,
finished_at:
Time
.
zone
.
now
,
project:
project
)
stub_licensed_features
(
dora4_analytics:
true
)
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
it
'returns deployment frequency within `from` and `to` range'
do
# 2 deployments over 20 days
expect
(
subject
[
:value
]).
to
eq
(
'0.1'
)
context
'when `to` is given'
do
let
(
:from
)
{
ten_days_ago
}
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
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
ee/spec/models/analytics/cycle_analytics/group_level_spec.rb
View file @
58f27851
...
...
@@ -27,8 +27,13 @@ RSpec.describe Analytics::CycleAnalytics::GroupLevel do
describe
'#summary'
do
before
do
stub_licensed_features
(
dora4_analytics:
true
)
create_cycle
(
user
,
project
,
issue
,
mr
,
milestone
,
pipeline
)
deploy_master
(
user
,
project
)
environment
=
project
.
environments
.
production
.
first
::
Dora
::
DailyMetrics
::
RefreshWorker
.
new
.
perform
(
environment
.
id
,
pipeline
.
created_at
.
to_date
.
to_s
)
end
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
expect
(
subject
[
:data
]).
to
eq
([{
Time
.
current
.
to_date
.
to_s
=>
1
,
'date'
=>
Time
.
current
.
to_date
.
to_s
,
'value'
=>
1
}])
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
context
'when container is a group'
do
...
...
@@ -196,6 +205,15 @@ RSpec.describe Dora::AggregateMetricsService do
expect
(
subject
[
:data
]).
to
eq
(
3
)
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
context
'when container is nil'
do
...
...
locale/gitlab.pot
View file @
58f27851
...
...
@@ -31862,6 +31862,9 @@ msgstr ""
msgid "The group will be placed in 'pending removal' state"
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."
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