Commit 4b22aa90 authored by Jacques Erasmus's avatar Jacques Erasmus

Merge branch '330909-remove-code-quality-annotations-feature-flag' into 'master'

Remove codequality_mr_diff_annotations flag

See merge request gitlab-org/gitlab!65960
parents d183f9ab 5404b220
......@@ -42,7 +42,6 @@ export default {
GlDropdownDivider,
GlFormCheckbox,
GlLoadingIcon,
CodeQualityBadge: () => import('ee_component/diffs/components/code_quality_badge.vue'),
},
directives: {
GlTooltip: GlTooltipDirective,
......@@ -203,9 +202,6 @@ export default {
externalUrlLabel() {
return sprintf(__('View on %{url}'), { url: this.diffFile.formatted_external_url });
},
showCodequalityBadge() {
return this.codequalityDiff?.length > 0 && !this.glFeatures.codequalityMrDiffAnnotations;
},
},
watch: {
'idState.moreActionsShown': {
......@@ -350,13 +346,6 @@ export default {
data-track-property="diff_copy_file"
/>
<code-quality-badge
v-if="showCodequalityBadge"
:file-name="filePath"
:codequality-diff="codequalityDiff"
class="gl-mr-2"
/>
<small v-if="isModeChanged" ref="fileMode" class="mr-1">
{{ diffFile.a_mode }}{{ diffFile.b_mode }}
</small>
......
......@@ -90,21 +90,13 @@ export default {
),
showCodequalityLeft: memoize(
(props) => {
return (
window.gon?.features?.codequalityMrDiffAnnotations &&
props.inline &&
props.line.left?.codequality?.length > 0
);
return props.inline && props.line.left?.codequality?.length > 0;
},
(props) => [props.inline, props.line.left?.codequality?.length].join(':'),
),
showCodequalityRight: memoize(
(props) => {
return (
window.gon?.features?.codequalityMrDiffAnnotations &&
!props.inline &&
props.line.right?.codequality?.length > 0
);
return !props.inline && props.line.right?.codequality?.length > 0;
},
(props) => [props.inline, props.line.right?.codequality?.length].join(':'),
),
......
......@@ -66,10 +66,7 @@ export default {
);
},
hasCodequalityChanges() {
return (
this.glFeatures.codequalityMrDiffAnnotations &&
this.codequalityDiff?.files?.[this.diffFile.file_path]?.length > 0
);
return this.codequalityDiff?.files?.[this.diffFile.file_path]?.length > 0;
},
},
methods: {
......
......@@ -39,7 +39,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:usage_data_i_testing_summary_widget_total, @project, default_enabled: :yaml)
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:diffs_virtual_scrolling, project, default_enabled: :yaml)
push_frontend_feature_flag(:codequality_mr_diff_annotations, project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml)
......
---
name: codequality_mr_diff_annotations
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57926
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330909
milestone: '14.0'
type: development
group: group::testing
default_enabled: false
......@@ -67,20 +67,6 @@ the merge request's diff view displays an indicator next to lines with new Code
![Code Quality MR diff report](img/code_quality_mr_diff_report_v14.png)
Previously, an indicator was displayed (**{information-o}** **Code Quality**) on the file in the merge request's diff view:
![Code Quality MR diff report](img/code_quality_mr_diff_report_v13_11.png)
To switch to the previous version of this feature, a GitLab administrator can run the following in a
[Rails console](../../../administration/operations/rails_console.md):
```ruby
# For the instance
Feature.disable(:codequality_mr_diff_annotations)
# For a single project
Feature.disable(:codequality_mr_diff_annotations, Project.find(<project id>))
```
## Example configuration
This example shows how to run Code Quality on your code by using GitLab CI/CD and Docker.
......
<script>
import { GlBadge, GlTooltipDirective, GlModalDirective, GlModal } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
export default {
components: {
CodequalityIssueBody,
GlBadge,
GlModal,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModal: GlModalDirective,
},
i18n: {
badgeTitle: s__('CodeQuality|Code quality'),
badgeTooltip: s__('CodeQuality|Some changes in this file degrade the code quality.'),
modalTitle: s__('CodeQuality|New code quality degradations in this file'),
},
modalCloseButton: {
text: __('Close'),
attributes: [{ variant: 'info' }],
},
props: {
fileName: {
type: String,
required: true,
},
codequalityDiff: {
type: Array,
required: false,
default: () => [],
},
},
computed: {
degradations() {
return this.codequalityDiff.map((degradation) => {
return {
name: degradation.description,
path: this.fileName,
severity: degradation.severity,
};
});
},
},
};
</script>
<template>
<span>
<gl-badge
v-gl-modal="`codequality-details-${fileName}`"
v-gl-tooltip
:title="$options.i18n.badgeTooltip"
class="gl-display-inline-block"
icon="information"
href="#"
>
{{ $options.i18n.badgeTitle }}
</gl-badge>
<gl-modal
:modal-id="`codequality-details-${fileName}`"
:title="$options.i18n.modalTitle"
:action-primary="$options.modalCloseButton"
>
<codequality-issue-body
v-for="(degradation, index) in degradations"
:key="index"
:issue="degradation"
/>
</gl-modal>
</span>
</template>
import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CodeQualityBadge from 'ee/diffs/components/code_quality_badge.vue';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
describe('EE CodeQualityBadge', () => {
let wrapper;
const props = {
fileName: 'index.js',
codequalityDiff: [
{
severity: 'major',
description:
'Function `aVeryLongFunction` has 52 lines of code (exceeds 25 allowed). Consider refactoring.',
},
{
severity: 'minor',
description: 'Arrow function has too many statements (52). Maximum allowed is 30.',
},
],
};
beforeEach(() => {
wrapper = shallowMount(CodeQualityBadge, {
propsData: props,
});
});
afterEach(() => {
wrapper.destroy();
});
it('opens a code quality details modal on click', () => {
const modalId = 'codequality-details-index.js';
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
wrapper.findComponent(GlBadge).trigger('click');
expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
it('passes the issue data into the issue components correctly', () => {
const issueProps = wrapper
.findAllComponents(CodequalityIssueBody)
.wrappers.map((w) => w.props());
expect(issueProps).toEqual([
{
issue: {
path: props.fileName,
severity: props.codequalityDiff[0].severity,
name: props.codequalityDiff[0].description,
},
status: 'neutral',
},
{
issue: {
path: props.fileName,
severity: props.codequalityDiff[1].severity,
name: props.codequalityDiff[1].description,
},
status: 'neutral',
},
]);
});
});
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import CodeQualityBadge from 'ee/diffs/components/code_quality_badge.vue';
import diffFileMockDataReadable from 'jest/diffs/mock_data/diff_file';
import DiffFileComponent from '~/diffs/components/diff_file.vue';
import createDiffsStore from '~/diffs/store/modules';
const getReadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataReadable));
function createComponent({ withCodequality = true, provide = {} }) {
const file = getReadableFile();
const localVue = createLocalVue();
localVue.use(Vuex);
const store = new Vuex.Store({
modules: {
diffs: createDiffsStore(),
},
});
store.state.diffs.diffFiles = [file];
if (withCodequality) {
store.state.diffs.codequalityDiff = {
files: {
[file.file_path]: [
{ line: 1, description: 'Unexpected alert.', severity: 'minor' },
{
line: 3,
description: 'Arrow function has too many statements (52). Maximum allowed is 30.',
severity: 'minor',
},
],
},
};
}
const wrapper = mount(DiffFileComponent, {
store,
localVue,
propsData: {
file,
canCurrentUserFork: false,
viewDiffsFileByFile: false,
isFirstFile: false,
isLastFile: false,
},
provide,
});
return {
localVue,
wrapper,
store,
};
}
describe('EE DiffFile', () => {
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('code quality badge', () => {
describe('when there is diff data for the file', () => {
beforeEach(() => {
({ wrapper } = createComponent({ withCodequality: true }));
});
it('shows the code quality badge', () => {
expect(wrapper.find(CodeQualityBadge).exists()).toBe(true);
});
});
describe('when the feature flag for the next iteration is enabled', () => {
beforeEach(() => {
({ wrapper } = createComponent({
withCodequality: true,
provide: { glFeatures: { codequalityMrDiffAnnotations: true } },
}));
});
it('does not show the code quality badge', () => {
expect(wrapper.find(CodeQualityBadge).exists()).toBe(false);
});
});
describe('when there is no diff data for the file', () => {
beforeEach(() => {
({ wrapper } = createComponent({ withCodequality: false }));
});
it('does not show the code quality badge', () => {
expect(wrapper.find(CodeQualityBadge).exists()).toBe(false);
});
});
});
});
......@@ -20,13 +20,7 @@ describe('EE DiffRow', () => {
fileLineCoverage: () => ({}),
};
const createComponent = ({
props,
state,
actions,
isLoggedIn = true,
codequalityMrDiffAnnotations,
}) => {
const createComponent = ({ props, state, actions, isLoggedIn = true }) => {
const diffs = diffsModule();
diffs.state = { ...diffs.state, ...state };
diffs.actions = { ...diffs.actions, ...actions };
......@@ -38,8 +32,6 @@ describe('EE DiffRow', () => {
getters,
});
window.gon = { features: { codequalityMrDiffAnnotations } };
wrapper = shallowMount(DiffRow, {
propsData: { ...defaultProps, ...props },
store,
......@@ -65,11 +57,10 @@ describe('EE DiffRow', () => {
});
});
describe('with feature flag enabled', () => {
describe('with a new code quality violation', () => {
beforeEach(() => {
createComponent({
props: { line: { right: { codequality: [{ severity: 'critical' }] } } },
codequalityMrDiffAnnotations: true,
});
});
......@@ -78,15 +69,14 @@ describe('EE DiffRow', () => {
});
});
describe('without feature flag enabled', () => {
describe('with no new code quality violations', () => {
beforeEach(() => {
createComponent({
props: { line: { right: { codequality: [{ severity: 'critical' }] } } },
codequalityMrDiffAnnotations: false,
props: { line: { right: { codequality: [] } } },
});
});
it('does not code quality gutter icon', () => {
it('does not show code quality gutter icon', () => {
expect(findIcon().exists()).toBe(false);
});
});
......
......@@ -61,11 +61,10 @@ describe('EE DiffView', () => {
wrapper.destroy();
});
describe('when there is diff data for the file and the feature flag is enabled', () => {
describe('when there is diff data for the file', () => {
beforeEach(() => {
({ wrapper } = createComponent({
withCodequality: true,
provide: { glFeatures: { codequalityMrDiffAnnotations: true } },
}));
});
......@@ -74,19 +73,6 @@ describe('EE DiffView', () => {
});
});
describe('when there is diff data for the file and the feature flag is disabled', () => {
beforeEach(() => {
({ wrapper } = createComponent({
withCodequality: true,
provide: { glFeatures: { codequalityMrDiffAnnotations: false } },
}));
});
it('does not have the with-codequality class', () => {
expect(wrapper.classes('with-codequality')).toBe(false);
});
});
describe('when there is no diff data for the file', () => {
beforeEach(() => {
({ wrapper } = createComponent({ withCodequality: false }));
......
......@@ -7903,21 +7903,12 @@ msgstr ""
msgid "CodeOwner|Pattern"
msgstr ""
msgid "CodeQuality|Code quality"
msgstr ""
msgid "CodeQuality|Code quality: %{severity} - %{description}"
msgstr ""
msgid "CodeQuality|New code quality degradations in this file"
msgstr ""
msgid "CodeQuality|New code quality degradations on this line"
msgstr ""
msgid "CodeQuality|Some changes in this file degrade the code quality."
msgstr ""
msgid "Cohorts|Inactive users"
msgstr ""
......
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