Commit f88acb6c authored by Sean McGivern's avatar Sean McGivern

Merge branch '342926-ci-cd-analytics-usage-metrics-by-tab' into 'master'

Project level CI/CD Analytics: Usage metrics by tab

See merge request gitlab-org/gitlab!75187
parents 71344985 ecdd2b6b
<script> <script>
import { GlTabs, GlTab } from '@gitlab/ui'; import { GlTabs, GlTab } from '@gitlab/ui';
import API from '~/api';
import { mergeUrlParams, updateHistory, getParameterValues } from '~/lib/utils/url_utility'; import { mergeUrlParams, updateHistory, getParameterValues } from '~/lib/utils/url_utility';
import PipelineCharts from './pipeline_charts.vue'; import PipelineCharts from './pipeline_charts.vue';
...@@ -13,6 +14,9 @@ export default { ...@@ -13,6 +14,9 @@ export default {
LeadTimeCharts: () => import('ee_component/dora/components/lead_time_charts.vue'), LeadTimeCharts: () => import('ee_component/dora/components/lead_time_charts.vue'),
ProjectQualitySummary: () => import('ee_component/project_quality_summary/app.vue'), ProjectQualitySummary: () => import('ee_component/project_quality_summary/app.vue'),
}, },
piplelinesTabEvent: 'p_analytics_ci_cd_pipelines',
deploymentFrequencyTabEvent: 'p_analytics_ci_cd_deployment_frequency',
leadTimeTabEvent: 'p_analytics_ci_cd_lead_time',
inject: { inject: {
shouldRenderDoraCharts: { shouldRenderDoraCharts: {
type: Boolean, type: Boolean,
...@@ -60,20 +64,35 @@ export default { ...@@ -60,20 +64,35 @@ export default {
updateHistory({ url: path, title: window.title }); updateHistory({ url: path, title: window.title });
} }
}, },
trackTabClick(tab) {
API.trackRedisHllUserEvent(tab);
},
}, },
}; };
</script> </script>
<template> <template>
<div> <div>
<gl-tabs v-if="charts.length > 1" :value="selectedTab" @input="onTabChange"> <gl-tabs v-if="charts.length > 1" :value="selectedTab" @input="onTabChange">
<gl-tab :title="__('Pipelines')"> <gl-tab
:title="__('Pipelines')"
data-testid="pipelines-tab"
@click="trackTabClick($options.piplelinesTabEvent)"
>
<pipeline-charts /> <pipeline-charts />
</gl-tab> </gl-tab>
<template v-if="shouldRenderDoraCharts"> <template v-if="shouldRenderDoraCharts">
<gl-tab :title="__('Deployment frequency')"> <gl-tab
:title="__('Deployment frequency')"
data-testid="deployment-frequency-tab"
@click="trackTabClick($options.deploymentFrequencyTabEvent)"
>
<deployment-frequency-charts /> <deployment-frequency-charts />
</gl-tab> </gl-tab>
<gl-tab :title="__('Lead time')"> <gl-tab
:title="__('Lead time')"
data-testid="lead-time-tab"
@click="trackTabClick($options.leadTimeTabEvent)"
>
<lead-time-charts /> <lead-time-charts />
</gl-tab> </gl-tab>
</template> </template>
......
...@@ -19,8 +19,13 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -19,8 +19,13 @@ class Projects::PipelinesController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:index, :show] around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/345074
track_redis_hll_event :charts, name: 'p_analytics_pipelines' track_redis_hll_event :charts, name: 'p_analytics_pipelines'
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_pipelines', if: -> { should_track_ci_cd_pipelines? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_deployment_frequency', if: -> { should_track_ci_cd_deployment_frequency? }
track_redis_hll_event :charts, name: 'p_analytics_ci_cd_lead_time', if: -> { should_track_ci_cd_lead_time? }
wrap_parameters Ci::Pipeline wrap_parameters Ci::Pipeline
POLLING_INTERVAL = 10_000 POLLING_INTERVAL = 10_000
...@@ -323,6 +328,18 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -323,6 +328,18 @@ class Projects::PipelinesController < Projects::ApplicationController
e.record! e.record!
end end
end end
def should_track_ci_cd_pipelines?
params[:chart].blank? || params[:chart] == 'pipelines'
end
def should_track_ci_cd_deployment_frequency?
params[:chart] == 'deployment-frequency'
end
def should_track_ci_cd_lead_time?
params[:chart] == 'lead-time'
end
end end
Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController') Projects::PipelinesController.prepend_mod_with('Projects::PipelinesController')
...@@ -24,6 +24,9 @@ options: ...@@ -24,6 +24,9 @@ options:
- g_analytics_productivity - g_analytics_productivity
- g_analytics_valuestream - g_analytics_valuestream
- p_analytics_pipelines - p_analytics_pipelines
- p_analytics_ci_cd_pipelines
- p_analytics_ci_cd_deployment_frequency
- p_analytics_ci_cd_lead_time
- p_analytics_code_reviews - p_analytics_code_reviews
- p_analytics_valuestream - p_analytics_valuestream
- p_analytics_insights - p_analytics_insights
...@@ -31,11 +34,11 @@ options: ...@@ -31,11 +34,11 @@ options:
- p_analytics_repo - p_analytics_repo
- i_analytics_cohorts - i_analytics_cohorts
distribution: distribution:
- ce - ce
- ee - ee
tier: tier:
- free - free
- premium - premium
- ultimate - ultimate
performance_indicator_type: [] performance_indicator_type: []
milestone: "<13.9" milestone: '<13.9'
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_pipelines_monthly
description: Count of unique visits to the project level CI CD Analytics pipelines tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_pipelines
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_deployment_frequency_monthly
description: Count of unique visits to the project level CI CD Analytics deployment frequency tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_deployment_frequency
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_lead_time_monthly
description: Count of unique visits to the project level CI CD Analytics lead time tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_lead_time
...@@ -24,6 +24,9 @@ options: ...@@ -24,6 +24,9 @@ options:
- g_analytics_productivity - g_analytics_productivity
- g_analytics_valuestream - g_analytics_valuestream
- p_analytics_pipelines - p_analytics_pipelines
- p_analytics_ci_cd_pipelines
- p_analytics_ci_cd_deployment_frequency
- p_analytics_ci_cd_lead_time
- p_analytics_code_reviews - p_analytics_code_reviews
- p_analytics_valuestream - p_analytics_valuestream
- p_analytics_insights - p_analytics_insights
...@@ -31,11 +34,11 @@ options: ...@@ -31,11 +34,11 @@ options:
- p_analytics_repo - p_analytics_repo
- i_analytics_cohorts - i_analytics_cohorts
distribution: distribution:
- ce - ce
- ee - ee
tier: tier:
- free - free
- premium - premium
- ultimate - ultimate
performance_indicator_type: [] performance_indicator_type: []
milestone: "<13.9" milestone: '<13.9'
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_pipelines_weekly
description: Count of unique visits to the project level CI CD Analytics pipelines tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_pipelines
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_deployment_frequency_weekly
description: Count of unique visits to the project level CI CD Analytics deployment frequency tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_deployment_frequency
---
key_path: redis_hll_counters.analytics.p_analytics_ci_cd_lead_time_weekly
description: Count of unique visits to the project level CI CD Analytics lead time tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
options:
events:
- p_analytics_ci_cd_lead_time
---
data_category: optional
key_path: analytics_unique_visits.p_analytics_ci_cd_pipelines
description: Count of unique visits to the project level CI CD Analytics pipelines tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: all
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
---
data_category: optional
key_path: analytics_unique_visits.p_analytics_ci_cd_deployment_frequency
description: Count of unique visits to the project level CI CD Analytics deployment frequency tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: all
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
---
data_category: optional
key_path: analytics_unique_visits.p_analytics_ci_cd_lead_time
description: Count of unique visits to the project level CI CD Analytics lead time tab
product_section: dev
product_stage: manage
product_group: group::optimize
product_category:
value_type: number
status: active
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75187
time_frame: all
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
...@@ -66,3 +66,15 @@ ...@@ -66,3 +66,15 @@
category: analytics category: analytics
redis_slot: analytics redis_slot: analytics
aggregation: weekly aggregation: weekly
- name: p_analytics_ci_cd_pipelines
category: analytics
redis_slot: analytics
aggregation: weekly
- name: p_analytics_ci_cd_deployment_frequency
category: analytics
redis_slot: analytics
aggregation: weekly
- name: p_analytics_ci_cd_lead_time
category: analytics
redis_slot: analytics
aggregation: weekly
...@@ -745,9 +745,28 @@ RSpec.describe Projects::PipelinesController do ...@@ -745,9 +745,28 @@ RSpec.describe Projects::PipelinesController do
describe 'GET #charts' do describe 'GET #charts' do
let(:pipeline) { create(:ci_pipeline, project: project) } let(:pipeline) { create(:ci_pipeline, project: project) }
[
{
chart_param: '',
event: 'p_analytics_ci_cd_pipelines'
},
{
chart_param: 'pipelines',
event: 'p_analytics_ci_cd_pipelines'
},
{
chart_param: 'deployment-frequency',
event: 'p_analytics_ci_cd_deployment_frequency'
},
{
chart_param: 'lead-time',
event: 'p_analytics_ci_cd_lead_time'
}
].each do |tab|
it_behaves_like 'tracking unique visits', :charts do it_behaves_like 'tracking unique visits', :charts do
let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id } } let(:request_params) { { namespace_id: project.namespace, project_id: project, id: pipeline.id, chart: tab[:chart_param] } }
let(:target_id) { 'p_analytics_pipelines' } let(:target_id) { ['p_analytics_pipelines', tab[:event]] }
end
end end
end end
......
import { GlTabs, GlTab } from '@gitlab/ui'; import { GlTabs, GlTab } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { merge } from 'lodash'; import { merge } from 'lodash';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import setWindowLocation from 'helpers/set_window_location_helper'; import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import { mergeUrlParams, updateHistory, getParameterValues } from '~/lib/utils/url_utility'; import { mergeUrlParams, updateHistory, getParameterValues } from '~/lib/utils/url_utility';
import Component from '~/projects/pipelines/charts/components/app.vue'; import Component from '~/projects/pipelines/charts/components/app.vue';
import PipelineCharts from '~/projects/pipelines/charts/components/pipeline_charts.vue'; import PipelineCharts from '~/projects/pipelines/charts/components/pipeline_charts.vue';
import API from '~/api';
jest.mock('~/lib/utils/url_utility'); jest.mock('~/lib/utils/url_utility');
...@@ -17,7 +18,7 @@ describe('ProjectsPipelinesChartsApp', () => { ...@@ -17,7 +18,7 @@ describe('ProjectsPipelinesChartsApp', () => {
let wrapper; let wrapper;
function createComponent(mountOptions = {}) { function createComponent(mountOptions = {}) {
wrapper = shallowMount( wrapper = shallowMountExtended(
Component, Component,
merge( merge(
{}, {},
...@@ -118,6 +119,23 @@ describe('ProjectsPipelinesChartsApp', () => { ...@@ -118,6 +119,23 @@ describe('ProjectsPipelinesChartsApp', () => {
expect(updateHistory).not.toHaveBeenCalled(); expect(updateHistory).not.toHaveBeenCalled();
}); });
describe('event tracking', () => {
it.each`
testId | event
${'pipelines-tab'} | ${'p_analytics_ci_cd_pipelines'}
${'deployment-frequency-tab'} | ${'p_analytics_ci_cd_deployment_frequency'}
${'lead-time-tab'} | ${'p_analytics_ci_cd_lead_time'}
`('tracks the $event event when clicked', ({ testId, event }) => {
jest.spyOn(API, 'trackRedisHllUserEvent');
expect(API.trackRedisHllUserEvent).not.toHaveBeenCalled();
wrapper.findByTestId(testId).vm.$emit('click');
expect(API.trackRedisHllUserEvent).toHaveBeenCalledWith(event);
});
});
}); });
describe('when provided with a query param', () => { describe('when provided with a query param', () => {
......
...@@ -1210,6 +1210,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do ...@@ -1210,6 +1210,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
'i_analytics_cohorts' => 123, 'i_analytics_cohorts' => 123,
'i_analytics_dev_ops_score' => 123, 'i_analytics_dev_ops_score' => 123,
'i_analytics_instance_statistics' => 123, 'i_analytics_instance_statistics' => 123,
'p_analytics_ci_cd_deployment_frequency' => 123,
'p_analytics_ci_cd_lead_time' => 123,
'p_analytics_ci_cd_pipelines' => 123,
'p_analytics_merge_request' => 123, 'p_analytics_merge_request' => 123,
'i_analytics_dev_ops_adoption' => 123, 'i_analytics_dev_ops_adoption' => 123,
'users_viewing_analytics_group_devops_adoption' => 123, 'users_viewing_analytics_group_devops_adoption' => 123,
......
...@@ -6,15 +6,23 @@ RSpec.shared_examples 'tracking unique visits' do |method| ...@@ -6,15 +6,23 @@ RSpec.shared_examples 'tracking unique visits' do |method|
let(:request_params) { {} } let(:request_params) { {} }
it 'tracks unique visit if the format is HTML' do it 'tracks unique visit if the format is HTML' do
ids = target_id.instance_of?(String) ? [target_id] : target_id
ids.each do |id|
expect(Gitlab::UsageDataCounters::HLLRedisCounter) expect(Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event).with(target_id, values: kind_of(String)) .to receive(:track_event).with(id, values: kind_of(String))
end
get method, params: request_params, format: :html get method, params: request_params, format: :html
end end
it 'tracks unique visit if DNT is not enabled' do it 'tracks unique visit if DNT is not enabled' do
ids = target_id.instance_of?(String) ? [target_id] : target_id
ids.each do |id|
expect(Gitlab::UsageDataCounters::HLLRedisCounter) expect(Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event).with(target_id, values: kind_of(String)) .to receive(:track_event).with(id, values: kind_of(String))
end
stub_do_not_track('0') stub_do_not_track('0')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment