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 { ...@@ -42,7 +42,6 @@ export default {
GlDropdownDivider, GlDropdownDivider,
GlFormCheckbox, GlFormCheckbox,
GlLoadingIcon, GlLoadingIcon,
CodeQualityBadge: () => import('ee_component/diffs/components/code_quality_badge.vue'),
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -203,9 +202,6 @@ export default { ...@@ -203,9 +202,6 @@ export default {
externalUrlLabel() { externalUrlLabel() {
return sprintf(__('View on %{url}'), { url: this.diffFile.formatted_external_url }); return sprintf(__('View on %{url}'), { url: this.diffFile.formatted_external_url });
}, },
showCodequalityBadge() {
return this.codequalityDiff?.length > 0 && !this.glFeatures.codequalityMrDiffAnnotations;
},
}, },
watch: { watch: {
'idState.moreActionsShown': { 'idState.moreActionsShown': {
...@@ -350,13 +346,6 @@ export default { ...@@ -350,13 +346,6 @@ export default {
data-track-property="diff_copy_file" 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"> <small v-if="isModeChanged" ref="fileMode" class="mr-1">
{{ diffFile.a_mode }}{{ diffFile.b_mode }} {{ diffFile.a_mode }}{{ diffFile.b_mode }}
</small> </small>
......
...@@ -90,21 +90,13 @@ export default { ...@@ -90,21 +90,13 @@ export default {
), ),
showCodequalityLeft: memoize( showCodequalityLeft: memoize(
(props) => { (props) => {
return ( return props.inline && props.line.left?.codequality?.length > 0;
window.gon?.features?.codequalityMrDiffAnnotations &&
props.inline &&
props.line.left?.codequality?.length > 0
);
}, },
(props) => [props.inline, props.line.left?.codequality?.length].join(':'), (props) => [props.inline, props.line.left?.codequality?.length].join(':'),
), ),
showCodequalityRight: memoize( showCodequalityRight: memoize(
(props) => { (props) => {
return ( return !props.inline && props.line.right?.codequality?.length > 0;
window.gon?.features?.codequalityMrDiffAnnotations &&
!props.inline &&
props.line.right?.codequality?.length > 0
);
}, },
(props) => [props.inline, props.line.right?.codequality?.length].join(':'), (props) => [props.inline, props.line.right?.codequality?.length].join(':'),
), ),
......
...@@ -66,10 +66,7 @@ export default { ...@@ -66,10 +66,7 @@ export default {
); );
}, },
hasCodequalityChanges() { hasCodequalityChanges() {
return ( return this.codequalityDiff?.files?.[this.diffFile.file_path]?.length > 0;
this.glFeatures.codequalityMrDiffAnnotations &&
this.codequalityDiff?.files?.[this.diffFile.file_path]?.length > 0
);
}, },
}, },
methods: { methods: {
......
...@@ -39,7 +39,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo ...@@ -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(: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(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:diffs_virtual_scrolling, 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 # Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml) 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 ...@@ -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) ![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 ## Example configuration
This example shows how to run Code Quality on your code by using GitLab CI/CD and Docker. 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', () => { ...@@ -20,13 +20,7 @@ describe('EE DiffRow', () => {
fileLineCoverage: () => ({}), fileLineCoverage: () => ({}),
}; };
const createComponent = ({ const createComponent = ({ props, state, actions, isLoggedIn = true }) => {
props,
state,
actions,
isLoggedIn = true,
codequalityMrDiffAnnotations,
}) => {
const diffs = diffsModule(); const diffs = diffsModule();
diffs.state = { ...diffs.state, ...state }; diffs.state = { ...diffs.state, ...state };
diffs.actions = { ...diffs.actions, ...actions }; diffs.actions = { ...diffs.actions, ...actions };
...@@ -38,8 +32,6 @@ describe('EE DiffRow', () => { ...@@ -38,8 +32,6 @@ describe('EE DiffRow', () => {
getters, getters,
}); });
window.gon = { features: { codequalityMrDiffAnnotations } };
wrapper = shallowMount(DiffRow, { wrapper = shallowMount(DiffRow, {
propsData: { ...defaultProps, ...props }, propsData: { ...defaultProps, ...props },
store, store,
...@@ -65,11 +57,10 @@ describe('EE DiffRow', () => { ...@@ -65,11 +57,10 @@ describe('EE DiffRow', () => {
}); });
}); });
describe('with feature flag enabled', () => { describe('with a new code quality violation', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ createComponent({
props: { line: { right: { codequality: [{ severity: 'critical' }] } } }, props: { line: { right: { codequality: [{ severity: 'critical' }] } } },
codequalityMrDiffAnnotations: true,
}); });
}); });
...@@ -78,15 +69,14 @@ describe('EE DiffRow', () => { ...@@ -78,15 +69,14 @@ describe('EE DiffRow', () => {
}); });
}); });
describe('without feature flag enabled', () => { describe('with no new code quality violations', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ createComponent({
props: { line: { right: { codequality: [{ severity: 'critical' }] } } }, props: { line: { right: { codequality: [] } } },
codequalityMrDiffAnnotations: false,
}); });
}); });
it('does not code quality gutter icon', () => { it('does not show code quality gutter icon', () => {
expect(findIcon().exists()).toBe(false); expect(findIcon().exists()).toBe(false);
}); });
}); });
......
...@@ -61,11 +61,10 @@ describe('EE DiffView', () => { ...@@ -61,11 +61,10 @@ describe('EE DiffView', () => {
wrapper.destroy(); 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(() => { beforeEach(() => {
({ wrapper } = createComponent({ ({ wrapper } = createComponent({
withCodequality: true, withCodequality: true,
provide: { glFeatures: { codequalityMrDiffAnnotations: true } },
})); }));
}); });
...@@ -74,19 +73,6 @@ describe('EE DiffView', () => { ...@@ -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', () => { describe('when there is no diff data for the file', () => {
beforeEach(() => { beforeEach(() => {
({ wrapper } = createComponent({ withCodequality: false })); ({ wrapper } = createComponent({ withCodequality: false }));
......
...@@ -7903,21 +7903,12 @@ msgstr "" ...@@ -7903,21 +7903,12 @@ msgstr ""
msgid "CodeOwner|Pattern" msgid "CodeOwner|Pattern"
msgstr "" msgstr ""
msgid "CodeQuality|Code quality"
msgstr ""
msgid "CodeQuality|Code quality: %{severity} - %{description}" msgid "CodeQuality|Code quality: %{severity} - %{description}"
msgstr "" msgstr ""
msgid "CodeQuality|New code quality degradations in this file"
msgstr ""
msgid "CodeQuality|New code quality degradations on this line" msgid "CodeQuality|New code quality degradations on this line"
msgstr "" msgstr ""
msgid "CodeQuality|Some changes in this file degrade the code quality."
msgstr ""
msgid "Cohorts|Inactive users" msgid "Cohorts|Inactive users"
msgstr "" 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