diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app.vue b/app/assets/javascripts/projects/pipelines/charts/components/app.vue index 25bacc1cc4a3c768832651b9b7d00bc0f6c83d84..7379d5caed7aa98654f8281e48e3a96fe833fd07 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/app.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/app.vue @@ -11,12 +11,17 @@ export default { DeploymentFrequencyCharts: () => import('ee_component/dora/components/deployment_frequency_charts.vue'), LeadTimeCharts: () => import('ee_component/dora/components/lead_time_charts.vue'), + ProjectQualitySummary: () => import('ee_component/project_quality_summary/app.vue'), }, inject: { shouldRenderDoraCharts: { type: Boolean, default: false, }, + shouldRenderQualitySummary: { + type: Boolean, + default: false, + }, }, data() { return { @@ -31,6 +36,10 @@ export default { chartsToShow.push('deployment-frequency', 'lead-time'); } + if (this.shouldRenderQualitySummary) { + chartsToShow.push('project-quality'); + } + return chartsToShow; }, }, @@ -68,6 +77,9 @@ export default { + + + diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js index 5f5ee44c2048ddc525d945f6e842a79068cf569e..003b61d94b1baa856d61808dc3cd35dfafdbf450 100644 --- a/app/assets/javascripts/projects/pipelines/charts/index.js +++ b/app/assets/javascripts/projects/pipelines/charts/index.js @@ -14,6 +14,7 @@ const mountPipelineChartsApp = (el) => { const { projectPath } = el.dataset; const shouldRenderDoraCharts = parseBoolean(el.dataset.shouldRenderDoraCharts); + const shouldRenderQualitySummary = parseBoolean(el.dataset.shouldRenderQualitySummary); return new Vue({ el, @@ -25,6 +26,7 @@ const mountPipelineChartsApp = (el) => { provide: { projectPath, shouldRenderDoraCharts, + shouldRenderQualitySummary, }, render: (createElement) => createElement(ProjectPipelinesCharts, {}), }); diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb index 3a94f7d47c22fb6923d4ef86e1b8568e464483f3..45ca820f7b3e7105ec6a97222853707122cdcb75 100644 --- a/app/helpers/graph_helper.rb +++ b/app/helpers/graph_helper.rb @@ -26,6 +26,10 @@ def success_ratio(counts) def should_render_dora_charts false end + + def should_render_quality_summary + false + end end GraphHelper.prepend_mod_with('GraphHelper') diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index 992407adf715e2171cd519facef6620a10f17b42..21e871246d72cbe4d4b32d55c411658e86506b88 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -1,4 +1,5 @@ - page_title _('CI/CD Analytics') #js-project-pipelines-charts-app{ data: { project_path: @project.full_path, - should_render_dora_charts: should_render_dora_charts.to_s } } + should_render_dora_charts: should_render_dora_charts.to_s, + should_render_quality_summary: should_render_quality_summary.to_s } } diff --git a/ee/app/assets/javascripts/project_quality_summary/app.vue b/ee/app/assets/javascripts/project_quality_summary/app.vue new file mode 100644 index 0000000000000000000000000000000000000000..3a452daa5be23491555fcb12a921d949b0f3a93d --- /dev/null +++ b/ee/app/assets/javascripts/project_quality_summary/app.vue @@ -0,0 +1,4 @@ + + diff --git a/ee/app/helpers/ee/graph_helper.rb b/ee/app/helpers/ee/graph_helper.rb index a959b4e7fce306f90fee8aed613d85c96a7109e4..81631d776544451a5edfbe813d6cc0be3d0738ac 100644 --- a/ee/app/helpers/ee/graph_helper.rb +++ b/ee/app/helpers/ee/graph_helper.rb @@ -12,5 +12,11 @@ def should_render_dora_charts can?(current_user, :read_dora4_analytics, container) end + + override :should_render_quality_summary + def should_render_quality_summary + @project.feature_available?(:project_quality_summary) && + ::Feature.enabled?(:project_quality_summary_page, @project, default_enabled: :yaml) + end end end diff --git a/ee/app/models/license.rb b/ee/app/models/license.rb index ee2e135c47fe7771d4dbd840f8a2b50485a17f31..eb70a00a98a3736cbe619dc751841e8d0b333ac9 100644 --- a/ee/app/models/license.rb +++ b/ee/app/models/license.rb @@ -177,6 +177,7 @@ class License < ApplicationRecord kubernetes_cluster_vulnerabilities license_scanning personal_access_token_expiration_policy + project_quality_summary prometheus_alerts pseudonymizer quality_management diff --git a/ee/config/feature_flags/development/project_quality_summary_page.yml b/ee/config/feature_flags/development/project_quality_summary_page.yml new file mode 100644 index 0000000000000000000000000000000000000000..eac7db4e99f4f862a195c448ac5e6e28b305b5e8 --- /dev/null +++ b/ee/config/feature_flags/development/project_quality_summary_page.yml @@ -0,0 +1,8 @@ +--- +name: project_quality_summary_page +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72724 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343687 +milestone: '14.4' +type: development +group: group::testing +default_enabled: false diff --git a/ee/spec/helpers/ee/graph_helper_spec.rb b/ee/spec/helpers/ee/graph_helper_spec.rb index 8d59bd1824ab2ca578a5f85c24228e8755b013b8..3ff2635b4a303b8dcfbd5503e9109e3e288565d0 100644 --- a/ee/spec/helpers/ee/graph_helper_spec.rb +++ b/ee/spec/helpers/ee/graph_helper_spec.rb @@ -58,4 +58,38 @@ it_behaves_like '#should_render_dora_charts for a specific type of container' end end + + describe '#should_render_quality_summary' do + subject { helper.should_render_quality_summary } + + before do + self.instance_variable_set(:@project, project) + end + + context 'when licensed feature is available' do + before do + stub_licensed_features(project_quality_summary: true) + end + + context 'when feature flag is enabled' do + it { is_expected.to eq(true) } + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(project_quality_summary_page: false) + end + + it { is_expected.to eq(false) } + end + end + + context 'when licensed feature is not available' do + before do + stub_licensed_features(project_quality_summary: false) + end + + it { is_expected.to eq(false) } + end + end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 1720b2be13f7c0490a9a5e0b1337be38311052af..26aaf2fa9c9634ee2b63d4d9fee7b33c35bc3ced 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -28215,6 +28215,9 @@ msgstr "" msgid "PushoverService|Total commits count: %{total_commits_count}" msgstr "" +msgid "QualitySummary|Project quality" +msgstr "" + msgid "Quarters" msgstr "" diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index 987a215eb4cccaf1c16189c67585061868805813..b4067f6a72ba7c8ab1105e0c26536156eb69fabf 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -11,6 +11,7 @@ jest.mock('~/lib/utils/url_utility'); const DeploymentFrequencyChartsStub = { name: 'DeploymentFrequencyCharts', render: () => {} }; const LeadTimeChartsStub = { name: 'LeadTimeCharts', render: () => {} }; +const ProjectQualitySummaryStub = { name: 'ProjectQualitySummary', render: () => {} }; describe('ProjectsPipelinesChartsApp', () => { let wrapper; @@ -23,10 +24,12 @@ describe('ProjectsPipelinesChartsApp', () => { { provide: { shouldRenderDoraCharts: true, + shouldRenderQualitySummary: true, }, stubs: { DeploymentFrequencyCharts: DeploymentFrequencyChartsStub, LeadTimeCharts: LeadTimeChartsStub, + ProjectQualitySummary: ProjectQualitySummaryStub, }, }, mountOptions, @@ -44,6 +47,7 @@ describe('ProjectsPipelinesChartsApp', () => { const findLeadTimeCharts = () => wrapper.find(LeadTimeChartsStub); const findDeploymentFrequencyCharts = () => wrapper.find(DeploymentFrequencyChartsStub); const findPipelineCharts = () => wrapper.find(PipelineCharts); + const findProjectQualitySummary = () => wrapper.find(ProjectQualitySummaryStub); describe('when all charts are available', () => { beforeEach(() => { @@ -70,6 +74,10 @@ describe('ProjectsPipelinesChartsApp', () => { expect(findLeadTimeCharts().exists()).toBe(true); }); + it('renders the project quality summary', () => { + expect(findProjectQualitySummary().exists()).toBe(true); + }); + it('sets the tab and url when a tab is clicked', async () => { let chartsPath; setWindowLocation(`${TEST_HOST}/gitlab-org/gitlab-test/-/pipelines/charts`); @@ -163,9 +171,11 @@ describe('ProjectsPipelinesChartsApp', () => { }); }); - describe('when the dora charts are not available', () => { + describe('when the dora charts are not available and project quality summary is not available', () => { beforeEach(() => { - createComponent({ provide: { shouldRenderDoraCharts: false } }); + createComponent({ + provide: { shouldRenderDoraCharts: false, shouldRenderQualitySummary: false }, + }); }); it('does not render tabs', () => { @@ -176,4 +186,14 @@ describe('ProjectsPipelinesChartsApp', () => { expect(findPipelineCharts().exists()).toBe(true); }); }); + + describe('when the project quality summary is not available', () => { + beforeEach(() => { + createComponent({ provide: { shouldRenderQualitySummary: false } }); + }); + + it('does not render the tab', () => { + expect(findProjectQualitySummary().exists()).toBe(false); + }); + }); }); diff --git a/spec/helpers/graph_helper_spec.rb b/spec/helpers/graph_helper_spec.rb index 0930417accb8da7266b615d5e0f854778911236a..a5d4e1313e11727509582471d33cac2de13d8bfc 100644 --- a/spec/helpers/graph_helper_spec.rb +++ b/spec/helpers/graph_helper_spec.rb @@ -27,4 +27,16 @@ expect(should_render_dora_charts).to be(false) end end + + describe '#should_render_quality_summary' do + let(:project) { create(:project, :private) } + + before do + self.instance_variable_set(:@project, project) + end + + it 'always returns false' do + expect(should_render_quality_summary).to be(false) + end + end end