Commit 1cc37e15 authored by Nathan Friend's avatar Nathan Friend Committed by Savas Vedova

Update text on DORA 4 charts

parent 67bcc4fb
......@@ -29,7 +29,7 @@ export default {
const chartsToShow = ['pipelines'];
if (this.shouldRenderDoraCharts) {
chartsToShow.push('deployments', 'lead-time');
chartsToShow.push('deployment-frequency', 'lead-time');
}
return chartsToShow;
......@@ -62,10 +62,10 @@ export default {
<pipeline-charts />
</gl-tab>
<template v-if="shouldRenderDoraCharts">
<gl-tab :title="__('Deployments')">
<gl-tab :title="__('Deployment frequency')">
<deployment-frequency-charts />
</gl-tab>
<gl-tab :title="__('Lead Time')">
<gl-tab :title="__('Lead time')">
<lead-time-charts />
</gl-tab>
</template>
......
......@@ -52,7 +52,7 @@ The following table shows the supported metrics, at which level they are support
| --------------- | ----------- | --------------- | ---------- | ------- |
| `deployment_frequency` | Project-level | [13.7+](../../api/dora/metrics.md) | [13.8+](#deployment-frequency-charts) | The [old API endopint](../../api/dora4_project_analytics.md) was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/323713) in 13.10. |
| `deployment_frequency` | Group-level | [13.10+](../../api/dora/metrics.md) | To be supported | |
| `lead_time_for_changes` | Project-level | [13.10+](../../api/dora/metrics.md) | To be supported | Unit in seconds. Aggregation method is median. |
| `lead_time_for_changes` | Project-level | [13.10+](../../api/dora/metrics.md) | [13.11+](#lead-time-charts) | Unit in seconds. Aggregation method is median. |
| `lead_time_for_changes` | Group-level | [13.10+](../../api/dora/metrics.md) | To be supported | Unit in seconds. Aggregation method is median. |
| `change_failure_rate` | Project/Group-level | To be supported | To be supported | |
| `time_to_restore_service` | Project/Group-level | To be supported | To be supported | |
......@@ -61,9 +61,10 @@ The following table shows the supported metrics, at which level they are support
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.8.
The **Analytics > CI/CD Analytics** page shows information about the deployment frequency to the
`production` environment. The environment **must** be named `production` for its deployment
information to appear on the graphs.
The **Analytics > CI/CD Analytics** page shows information about the deployment
frequency to the `production` environment. The environment must be part of the
[production deployment tier](../../ci/environments/index.md#deployment-tier-of-environments)
for its deployment information to appear on the graphs.
![Deployment frequency](img/deployment_frequency_chart_v13_8.png)
......
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import * as DoraApi from 'ee/api/dora_api';
import createFlash from '~/flash';
import { s__ } from '~/locale';
import CiCdAnalyticsCharts from '~/projects/pipelines/charts/components/ci_cd_analytics_charts.vue';
import DoraChartHeader from './dora_chart_header.vue';
import {
allChartDefinitions,
areaChartOptions,
......@@ -20,9 +20,8 @@ import { apiDataToChartSeries } from './util';
export default {
name: 'DeploymentFrequencyCharts',
components: {
GlLink,
GlSprintf,
CiCdAnalyticsCharts,
DoraChartHeader,
},
inject: {
projectPath: {
......@@ -64,7 +63,7 @@ export default {
if (requestErrors.length) {
createFlash({
message: s__('DORA4Metrics|Something went wrong while getting deployment frequency data'),
message: s__('DORA4Metrics|Something went wrong while getting deployment frequency data.'),
});
const allErrorMessages = requestErrors.join('\n');
......@@ -75,7 +74,6 @@ export default {
);
}
},
allChartDefinitions,
areaChartOptions,
chartDescriptionText,
chartDocumentationHref,
......@@ -83,17 +81,11 @@ export default {
</script>
<template>
<div>
<h4 class="gl-my-4">{{ s__('DORA4Metrics|Deployments charts') }}</h4>
<p data-testid="help-text">
<gl-sprintf :message="$options.chartDescriptionText">
<template #code="{ content }">
<code>{{ content }}</code>
</template>
</gl-sprintf>
<gl-link :href="$options.chartDocumentationHref">
{{ __('Learn more.') }}
</gl-link>
</p>
<dora-chart-header
:header-text="s__('DORA4Metrics|Deployment frequency')"
:chart-description-text="$options.chartDescriptionText"
:chart-documentation-href="$options.chartDocumentationHref"
/>
<ci-cd-analytics-charts :charts="charts" :chart-options="$options.areaChartOptions" />
</div>
</template>
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { environmentTierDocumentationHref } from './static_data/shared';
export default {
name: 'DoraChartHeader',
components: {
GlLink,
GlSprintf,
},
props: {
headerText: {
type: String,
required: true,
},
chartDescriptionText: {
type: String,
required: true,
},
chartDocumentationHref: {
type: String,
required: true,
},
},
environmentTierDocumentationHref,
};
</script>
<template>
<div>
<h4 class="gl-my-4">{{ headerText }}</h4>
<p data-testid="help-text">
<gl-sprintf :message="chartDescriptionText">
<template #link="{ content }">
<gl-link :href="$options.environmentTierDocumentationHref" target="_blank"
><code>{{ content }}</code></gl-link
>
</template>
</gl-sprintf>
<gl-link :href="chartDocumentationHref" target="_blank">
{{ __('Learn more.') }}
</gl-link>
</p>
</div>
</template>
<script>
import { GlLink } from '@gitlab/ui';
import * as DoraApi from 'ee/api/dora_api';
import createFlash from '~/flash';
import { humanizeTimeInterval } from '~/lib/utils/datetime_utility';
import { s__ } from '~/locale';
import CiCdAnalyticsCharts from '~/projects/pipelines/charts/components/ci_cd_analytics_charts.vue';
import DoraChartHeader from './dora_chart_header.vue';
import {
allChartDefinitions,
areaChartOptions,
......@@ -20,8 +20,8 @@ import { buildNullSeriesForLeadTimeChart, apiDataToChartSeries } from './util';
export default {
name: 'LeadTimeCharts',
components: {
GlLink,
CiCdAnalyticsCharts,
DoraChartHeader,
},
inject: {
projectPath: {
......@@ -83,7 +83,6 @@ export default {
this.tooltipValue = seconds != null ? humanizeTimeInterval(seconds) : null;
},
},
allChartDefinitions,
areaChartOptions,
chartDescriptionText,
chartDocumentationHref,
......@@ -91,13 +90,11 @@ export default {
</script>
<template>
<div>
<h4 class="gl-my-4">{{ s__('DORA4|Lead time charts') }}</h4>
<p data-testid="help-text">
{{ $options.chartDescriptionText }}
<gl-link :href="$options.chartDocumentationHref">
{{ __('Learn more.') }}
</gl-link>
</p>
<dora-chart-header
:header-text="s__('DORA4Metrics|Lead time')"
:chart-description-text="$options.chartDescriptionText"
:chart-documentation-href="$options.chartDocumentationHref"
/>
<!-- Using renderer="canvas" here, otherwise the area chart coloring doesn't work if the
first value in the series is `null`. This appears to have been fixed in ECharts v5,
......
......@@ -3,7 +3,7 @@ import { s__ } from '~/locale';
export * from './shared';
export const CHART_TITLE = s__('DORA4Metrics|Deployments');
export const CHART_TITLE = s__('DORA4Metrics|Deployment frequency');
export const areaChartOptions = {
xAxis: {
......@@ -11,14 +11,14 @@ export const areaChartOptions = {
type: 'category',
},
yAxis: {
name: s__('DORA4Metrics|Deployments'),
name: s__('DORA4Metrics|Number of deployments'),
type: 'value',
minInterval: 1,
},
};
export const chartDescriptionText = s__(
'DORA4Metrics|These charts display the frequency of deployments to the production environment, as part of the DORA 4 metrics. The environment must be named %{codeStart}production%{codeEnd} for its data to appear in these charts.',
'DORA4Metrics|The chart displays the frequency of deployments to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value.',
);
export const chartDocumentationHref = helpPagePath('user/analytics/ci_cd_analytics.html', {
......
......@@ -24,7 +24,7 @@ export const areaChartOptions = {
};
export const chartDescriptionText = s__(
'DORA4Metrics|These charts display the median time between a merge request being merged and deployed to production, as part of the DORA 4 metrics.',
'DORA4Metrics|The chart displays the median time between a merge request being merged and deployed to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value.',
);
export const chartDocumentationHref = helpPagePath('user/analytics/ci_cd_analytics.html', {
......
import dateFormat from 'dateformat';
import { helpPagePath } from '~/helpers/help_page_helper';
import { nDaysBefore, nMonthsBefore, getStartOfDay, dayAfter } from '~/lib/utils/datetime_utility';
import { __, s__, sprintf } from '~/locale';
export const environmentTierDocumentationHref = helpPagePath('ci/environments/index.html', {
anchor: 'deployment-tier-of-environments',
});
/* eslint-disable @gitlab/require-i18n-strings */
export const LAST_WEEK = 'LAST_WEEK';
export const LAST_MONTH = 'LAST_MONTH';
......
---
title: Update text on project-level DORA 4 charts
merge_request: 59310
author:
type: changed
......@@ -35,7 +35,7 @@ Array [
1,
],
],
"name": "Deployments",
"name": "Deployment frequency",
},
],
"endDate": 2015-07-04T00:00:00.000Z,
......@@ -175,7 +175,7 @@ Array [
1,
],
],
"name": "Deployments",
"name": "Deployment frequency",
},
],
"endDate": 2015-07-04T00:00:00.000Z,
......@@ -555,7 +555,7 @@ Array [
1,
],
],
"name": "Deployments",
"name": "Deployment frequency",
},
],
"endDate": 2015-07-04T00:00:00.000Z,
......
import { GlSprintf, GlLink } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
......@@ -24,8 +23,9 @@ describe('deployment_frequency_charts.vue', () => {
useFixturesFakeDate();
let DeploymentFrequencyCharts;
let DoraChartHeader;
// Import the component _after_ the date has been set using `useFakeDate`, so
// Import these components _after_ the date has been set using `useFakeDate`, so
// that any calls to `new Date()` during module initialization use the fake date
beforeAll(async () => {
DeploymentFrequencyCharts = (
......@@ -33,6 +33,9 @@ describe('deployment_frequency_charts.vue', () => {
'ee_component/projects/pipelines/charts/components/deployment_frequency_charts.vue'
)
).default;
DoraChartHeader = (
await import('ee/projects/pipelines/charts/components/dora_chart_header.vue')
).default;
});
let wrapper;
......@@ -43,7 +46,6 @@ describe('deployment_frequency_charts.vue', () => {
provide: {
projectPath: 'test/project',
},
stubs: { GlSprintf },
});
};
......@@ -69,9 +71,6 @@ describe('deployment_frequency_charts.vue', () => {
mock.restore();
});
const findHelpText = () => wrapper.find('[data-testid="help-text"]');
const findDocLink = () => findHelpText().find(GlLink);
describe('when there are no network errors', () => {
beforeEach(async () => {
mock = new MockAdapter(axios);
......@@ -99,7 +98,7 @@ describe('deployment_frequency_charts.vue', () => {
});
it('converts the data from the API into data usable by the chart component', () => {
const chartWrapper = wrapper.find(CiCdAnalyticsCharts);
const chartWrapper = wrapper.findComponent(CiCdAnalyticsCharts);
expect(chartWrapper.props().charts).toMatchSnapshot();
});
......@@ -107,16 +106,8 @@ describe('deployment_frequency_charts.vue', () => {
expect(createFlash).not.toHaveBeenCalled();
});
it('renders description text', () => {
expect(findHelpText().text()).toMatchInterpolatedText(
'These charts display the frequency of deployments to the production environment, as part of the DORA 4 metrics. The environment must be named production for its data to appear in these charts. Learn more.',
);
});
it('renders a link to the documentation', () => {
expect(findDocLink().attributes().href).toBe(
'/help/user/analytics/ci_cd_analytics.html#deployment-frequency-charts',
);
it('renders a header', () => {
expect(wrapper.findComponent(DoraChartHeader).exists()).toBe(true);
});
});
......@@ -139,7 +130,7 @@ describe('deployment_frequency_charts.vue', () => {
it('shows a flash message', () => {
expect(createFlash).toHaveBeenCalledTimes(1);
expect(createFlash).toHaveBeenCalledWith({
message: 'Something went wrong while getting deployment frequency data',
message: 'Something went wrong while getting deployment frequency data.',
});
});
......
import DoraChartHeader from 'ee/projects/pipelines/charts/components/dora_chart_header.vue';
import { chartDescriptionText } from 'ee/projects/pipelines/charts/components/static_data/lead_time';
import { environmentTierDocumentationHref } from 'ee/projects/pipelines/charts/components/static_data/shared';
import { mountExtended } from 'helpers/vue_test_utils_helper';
describe('dora_chart_header.vue', () => {
const mockHeaderText = 'Header text';
const mockDocLink = 'https://example.com/docs';
let wrapper;
const createComponent = () => {
wrapper = mountExtended(DoraChartHeader, {
propsData: {
headerText: mockHeaderText,
chartDescriptionText,
chartDocumentationHref: mockDocLink,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
it('renders the header text', () => {
const actualText = wrapper.find('h4').text();
expect(actualText).toBe(mockHeaderText);
});
it('renders a link to the documentation about deployment tier', () => {
const link = wrapper.findByRole('link', { name: 'deployment_tier' });
expect(link.attributes('href')).toBe(environmentTierDocumentationHref);
});
it('renders a "Learn more." documentation link', () => {
const link = wrapper.findByRole('link', { name: 'Learn more.' });
expect(link.attributes('href')).toBe(mockDocLink);
});
it('renders the chart description/help text', () => {
const helpText = wrapper.find('[data-testid="help-text"]');
expect(helpText.text()).toMatchInterpolatedText(
'The chart displays the median time between a merge request being merged and deployed to production environment(s) that are based on the deployment_tier value. Learn more.',
);
});
});
import { GlSprintf, GlLink } from '@gitlab/ui';
import { GlSprintf } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { useFixturesFakeDate } from 'helpers/fake_date';
......@@ -23,13 +23,17 @@ describe('lead_time_charts.vue', () => {
useFixturesFakeDate();
let LeadTimeCharts;
let DoraChartHeader;
// Import the component _after_ the date has been set using `useFakeDate`, so
// Import these components _after_ the date has been set using `useFakeDate`, so
// that any calls to `new Date()` during module initialization use the fake date
beforeAll(async () => {
LeadTimeCharts = (
await import('ee_component/projects/pipelines/charts/components/lead_time_charts.vue')
).default;
DoraChartHeader = (
await import('ee/projects/pipelines/charts/components/dora_chart_header.vue')
).default;
});
let wrapper;
......@@ -64,10 +68,8 @@ describe('lead_time_charts.vue', () => {
mock.restore();
});
const findHelpText = () => wrapper.find('[data-testid="help-text"]');
const findDocLink = () => findHelpText().find(GlLink);
const getTooltipValue = () => wrapper.find('[data-testid="tooltip-value"]').text();
const findCiCdAnalyticsCharts = () => wrapper.find(CiCdAnalyticsCharts);
const findCiCdAnalyticsCharts = () => wrapper.findComponent(CiCdAnalyticsCharts);
describe('when there are no network errors', () => {
beforeEach(async () => {
......@@ -99,16 +101,8 @@ describe('lead_time_charts.vue', () => {
expect(createFlash).not.toHaveBeenCalled();
});
it('renders description text', () => {
expect(findHelpText().text()).toMatchInterpolatedText(
'These charts display the median time between a merge request being merged and deployed to production, as part of the DORA 4 metrics. Learn more.',
);
});
it('renders a link to the documentation', () => {
expect(findDocLink().attributes().href).toBe(
'/help/user/analytics/ci_cd_analytics.html#lead-time-charts',
);
it('renders a header', () => {
expect(wrapper.findComponent(DoraChartHeader).exists()).toBe(true);
});
describe('methods', () => {
......
......@@ -9956,10 +9956,7 @@ msgstr ""
msgid "DORA4Metrics|Days from merge to deploy"
msgstr ""
msgid "DORA4Metrics|Deployments"
msgstr ""
msgid "DORA4Metrics|Deployments charts"
msgid "DORA4Metrics|Deployment frequency"
msgstr ""
msgid "DORA4Metrics|Lead time"
......@@ -9971,19 +9968,19 @@ msgstr ""
msgid "DORA4Metrics|No merge requests were deployed during this period"
msgstr ""
msgid "DORA4Metrics|Something went wrong while getting deployment frequency data"
msgid "DORA4Metrics|Number of deployments"
msgstr ""
msgid "DORA4Metrics|Something went wrong while getting lead time data."
msgid "DORA4Metrics|Something went wrong while getting deployment frequency data."
msgstr ""
msgid "DORA4Metrics|These charts display the frequency of deployments to the production environment, as part of the DORA 4 metrics. The environment must be named %{codeStart}production%{codeEnd} for its data to appear in these charts."
msgid "DORA4Metrics|Something went wrong while getting lead time data."
msgstr ""
msgid "DORA4Metrics|These charts display the median time between a merge request being merged and deployed to production, as part of the DORA 4 metrics."
msgid "DORA4Metrics|The chart displays the frequency of deployments to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value."
msgstr ""
msgid "DORA4|Lead time charts"
msgid "DORA4Metrics|The chart displays the median time between a merge request being merged and deployed to production environment(s) that are based on the %{linkStart}deployment_tier%{linkEnd} value."
msgstr ""
msgid "Dashboard"
......@@ -10990,6 +10987,9 @@ msgstr ""
msgid "Deployment Frequency"
msgstr ""
msgid "Deployment frequency"
msgstr ""
msgid "Deployments"
msgstr ""
......@@ -18941,6 +18941,9 @@ msgstr ""
msgid "Lead Time"
msgstr ""
msgid "Lead time"
msgstr ""
msgid "Learn CI/CD syntax"
msgstr ""
......
......@@ -54,8 +54,8 @@ describe('ProjectsPipelinesChartsApp', () => {
expect(findGlTabs().exists()).toBe(true);
expect(findGlTabAtIndex(0).attributes('title')).toBe('Pipelines');
expect(findGlTabAtIndex(1).attributes('title')).toBe('Deployments');
expect(findGlTabAtIndex(2).attributes('title')).toBe('Lead Time');
expect(findGlTabAtIndex(1).attributes('title')).toBe('Deployment frequency');
expect(findGlTabAtIndex(2).attributes('title')).toBe('Lead time');
});
it('renders the pipeline charts', () => {
......@@ -75,7 +75,7 @@ describe('ProjectsPipelinesChartsApp', () => {
setWindowLocation(`${TEST_HOST}/gitlab-org/gitlab-test/-/pipelines/charts`);
mergeUrlParams.mockImplementation(({ chart }, path) => {
expect(chart).toBe('deployments');
expect(chart).toBe('deployment-frequency');
expect(path).toBe(window.location.pathname);
chartsPath = `${path}?chart=${chart}`;
return chartsPath;
......@@ -114,12 +114,12 @@ describe('ProjectsPipelinesChartsApp', () => {
describe('when provided with a query param', () => {
it.each`
chart | tab
${'lead-time'} | ${'2'}
${'deployments'} | ${'1'}
${'pipelines'} | ${'0'}
${'fake'} | ${'0'}
${''} | ${'0'}
chart | tab
${'lead-time'} | ${'2'}
${'deployment-frequency'} | ${'1'}
${'pipelines'} | ${'0'}
${'fake'} | ${'0'}
${''} | ${'0'}
`('shows the correct tab for URL parameter "$chart"', ({ chart, tab }) => {
setWindowLocation(`${TEST_HOST}/gitlab-org/gitlab-test/-/pipelines/charts?chart=${chart}`);
getParameterValues.mockImplementation((name) => {
......@@ -152,7 +152,7 @@ describe('ProjectsPipelinesChartsApp', () => {
getParameterValues.mockImplementationOnce((name) => {
expect(name).toBe('chart');
return ['deployments'];
return ['deployment-frequency'];
});
popstateHandler();
......
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