Commit a9de1e38 authored by Nathan Friend's avatar Nathan Friend

Merge branch '251213-remove-release-issue-summary-ff' into 'master'

Remove feature flag: release_issue_summary

See merge request gitlab-org/gitlab!44277
parents 12dd22b3 60c72d03
...@@ -11,7 +11,6 @@ import EvidenceBlock from './evidence_block.vue'; ...@@ -11,7 +11,6 @@ import EvidenceBlock from './evidence_block.vue';
import ReleaseBlockAssets from './release_block_assets.vue'; import ReleaseBlockAssets from './release_block_assets.vue';
import ReleaseBlockFooter from './release_block_footer.vue'; import ReleaseBlockFooter from './release_block_footer.vue';
import ReleaseBlockHeader from './release_block_header.vue'; import ReleaseBlockHeader from './release_block_header.vue';
import ReleaseBlockMetadata from './release_block_metadata.vue';
import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue'; import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue';
export default { export default {
...@@ -21,7 +20,6 @@ export default { ...@@ -21,7 +20,6 @@ export default {
ReleaseBlockAssets, ReleaseBlockAssets,
ReleaseBlockFooter, ReleaseBlockFooter,
ReleaseBlockHeader, ReleaseBlockHeader,
ReleaseBlockMetadata,
ReleaseBlockMilestoneInfo, ReleaseBlockMilestoneInfo,
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
...@@ -57,19 +55,13 @@ export default { ...@@ -57,19 +55,13 @@ export default {
shouldShowEvidence() { shouldShowEvidence() {
return this.glFeatures.releaseEvidenceCollection; return this.glFeatures.releaseEvidenceCollection;
}, },
shouldShowFooter() {
return this.glFeatures.releaseIssueSummary;
},
shouldRenderAssets() { shouldRenderAssets() {
return Boolean( return Boolean(
this.assets.links.length || (this.assets.sources && this.assets.sources.length), this.assets.links.length || (this.assets.sources && this.assets.sources.length),
); );
}, },
shouldRenderReleaseMetaData() {
return !this.glFeatures.releaseIssueSummary;
},
shouldRenderMilestoneInfo() { shouldRenderMilestoneInfo() {
return Boolean(this.glFeatures.releaseIssueSummary && !isEmpty(this.release.milestones)); return Boolean(!isEmpty(this.release.milestones));
}, },
}, },
...@@ -105,7 +97,6 @@ export default { ...@@ -105,7 +97,6 @@ export default {
<hr class="mb-3 mt-0" /> <hr class="mb-3 mt-0" />
</div> </div>
<release-block-metadata v-if="shouldRenderReleaseMetaData" :release="release" />
<release-block-assets v-if="shouldRenderAssets" :assets="assets" /> <release-block-assets v-if="shouldRenderAssets" :assets="assets" />
<evidence-block v-if="hasEvidence && shouldShowEvidence" :release="release" /> <evidence-block v-if="hasEvidence && shouldShowEvidence" :release="release" />
...@@ -115,7 +106,6 @@ export default { ...@@ -115,7 +106,6 @@ export default {
</div> </div>
<release-block-footer <release-block-footer
v-if="shouldShowFooter"
class="card-footer" class="card-footer"
:commit="release.commit" :commit="release.commit"
:commit-path="release.commitPath" :commit-path="release.commitPath"
......
<script>
import { GlSprintf } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
export default {
name: 'ReleaseBlockAuthor',
components: {
GlSprintf,
UserAvatarLink,
},
props: {
author: {
type: Object,
required: true,
},
},
computed: {
userImageAltDescription() {
return this.author && this.author.username
? sprintf(__("%{username}'s avatar"), { username: this.author.username })
: null;
},
},
};
</script>
<template>
<div class="d-flex">
<gl-sprintf :message="__('by %{user}')">
<template #user>
<user-avatar-link
class="gl-ml-2"
:link-href="author.webUrl"
:img-src="author.avatarUrl"
:img-alt="userImageAltDescription"
:tooltip-text="author.username"
/>
</template>
</gl-sprintf>
</div>
</template>
<script>
import { GlTooltipDirective, GlLink, GlIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import ReleaseBlockAuthor from './release_block_author.vue';
import ReleaseBlockMilestones from './release_block_milestones.vue';
export default {
name: 'ReleaseBlockMetadata',
components: {
GlIcon,
GlLink,
ReleaseBlockAuthor,
ReleaseBlockMilestones,
},
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [timeagoMixin],
props: {
release: {
type: Object,
required: true,
},
},
computed: {
author() {
return this.release.author;
},
commit() {
return this.release.commit || {};
},
commitUrl() {
return this.release.commitPath;
},
hasAuthor() {
return Boolean(this.author);
},
releasedTimeAgo() {
const now = new Date();
const isFuture = now < new Date(this.release.releasedAt);
const time = this.timeFormatted(this.release.releasedAt);
return isFuture
? sprintf(__('will be released %{time}'), { time })
: sprintf(__('released %{time}'), { time });
},
shouldRenderMilestones() {
return Boolean(this.release.milestones?.length);
},
tagUrl() {
return this.release.tagPath;
},
},
};
</script>
<template>
<div class="card-subtitle d-flex flex-wrap text-secondary">
<div class="gl-mr-3">
<gl-icon name="commit" class="align-middle" />
<gl-link v-if="commitUrl" v-gl-tooltip.bottom :title="commit.title" :href="commitUrl">
{{ commit.shortId }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="commit.title">{{ commit.shortId }}</span>
</div>
<div class="gl-mr-3">
<gl-icon name="tag" class="align-middle" />
<gl-link v-if="tagUrl" v-gl-tooltip.bottom :title="__('Tag')" :href="tagUrl">
{{ release.tagName }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="__('Tag')">{{ release.tagName }}</span>
</div>
<release-block-milestones v-if="shouldRenderMilestones" :milestones="release.milestones" />
<div class="gl-mr-2">
&bull;
<span
v-gl-tooltip.bottom
class="js-release-date-info"
:title="tooltipTitle(release.releasedAt)"
>
{{ releasedTimeAgo }}
</span>
</div>
<release-block-author v-if="hasAuthor" :author="author" />
</div>
</template>
<script>
import { GlTooltipDirective, GlLink, GlIcon } from '@gitlab/ui';
import { n__ } from '~/locale';
export default {
name: 'ReleaseBlockMilestones',
components: {
GlLink,
GlIcon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
milestones: {
type: Array,
required: true,
},
},
computed: {
labelText() {
return n__('Milestone', 'Milestones', this.milestones.length);
},
},
};
</script>
<template>
<div>
<div class="js-milestone-list-label">
<gl-icon name="flag" class="align-middle" />
<span class="js-label-text">{{ labelText }}</span>
</div>
<template v-for="(milestone, index) in milestones">
<gl-link
:key="milestone.id"
v-gl-tooltip
:title="milestone.description"
:href="milestone.webUrl"
class="mx-1 js-milestone-link"
>
{{ milestone.title }}
</gl-link>
<template v-if="index !== milestones.length - 1">
&bull;
</template>
</template>
</div>
</template>
...@@ -6,7 +6,6 @@ class Projects::ReleasesController < Projects::ApplicationController ...@@ -6,7 +6,6 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :release, only: %i[edit show update downloads] before_action :release, only: %i[edit show update downloads]
before_action :authorize_read_release! before_action :authorize_read_release!
before_action do before_action do
push_frontend_feature_flag(:release_issue_summary, project, default_enabled: true)
push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true) push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true)
push_frontend_feature_flag(:release_asset_link_editing, project, default_enabled: true) push_frontend_feature_flag(:release_asset_link_editing, project, default_enabled: true)
push_frontend_feature_flag(:graphql_release_data, project, default_enabled: true) push_frontend_feature_flag(:graphql_release_data, project, default_enabled: true)
......
---
name: release_issue_summary
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19451
rollout_issue_url:
group: group::release management
type: development
default_enabled: true
...@@ -30091,9 +30091,6 @@ msgstr "" ...@@ -30091,9 +30091,6 @@ msgstr ""
msgid "by" msgid "by"
msgstr "" msgstr ""
msgid "by %{user}"
msgstr ""
msgid "cannot be a date in the past" msgid "cannot be a date in the past"
msgstr "" msgstr ""
...@@ -31211,9 +31208,6 @@ msgstr "" ...@@ -31211,9 +31208,6 @@ msgstr ""
msgid "relates to" msgid "relates to"
msgstr "" msgstr ""
msgid "released %{time}"
msgstr ""
msgid "remaining" msgid "remaining"
msgstr "" msgstr ""
...@@ -31471,9 +31465,6 @@ msgstr "" ...@@ -31471,9 +31465,6 @@ msgstr ""
msgid "wiki page" msgid "wiki page"
msgstr "" msgstr ""
msgid "will be released %{time}"
msgstr ""
msgid "with %{additions} additions, %{deletions} deletions." msgid "with %{additions} additions, %{deletions} deletions."
msgstr "" msgstr ""
......
import { mount } from '@vue/test-utils';
import { trimText } from 'helpers/text_helper';
import { getJSONFixture } from 'helpers/fixtures';
import { cloneDeep } from 'lodash';
import ReleaseBlockMetadata from '~/releases/components/release_block_metadata.vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
const originalRelease = getJSONFixture('api/releases/release.json');
const mockFutureDate = new Date(9999, 0, 0).toISOString();
let mockIsFutureRelease = false;
jest.mock('~/vue_shared/mixins/timeago', () => ({
methods: {
timeFormatted() {
return mockIsFutureRelease ? 'in 1 month' : '7 fortnights ago';
},
tooltipTitle() {
return 'February 30, 2401';
},
},
}));
describe('Release block metadata', () => {
let wrapper;
let release;
const factory = (releaseUpdates = {}) => {
wrapper = mount(ReleaseBlockMetadata, {
propsData: {
release: {
...convertObjectPropsToCamelCase(release, { deep: true }),
...releaseUpdates,
},
},
});
};
beforeEach(() => {
release = cloneDeep(originalRelease);
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
mockIsFutureRelease = false;
});
const findReleaseDateInfo = () => wrapper.find('.js-release-date-info');
describe('with all props provided', () => {
beforeEach(() => factory());
it('renders the release time info', () => {
expect(trimText(findReleaseDateInfo().text())).toBe(`released 7 fortnights ago`);
});
});
describe('with a future release date', () => {
beforeEach(() => {
mockIsFutureRelease = true;
factory({ releasedAt: mockFutureDate });
});
it('renders the release date without the author name', () => {
expect(trimText(findReleaseDateInfo().text())).toBe(`will be released in 1 month`);
});
});
});
import $ from 'jquery'; import $ from 'jquery';
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlIcon } from '@gitlab/ui';
import { getJSONFixture } from 'helpers/fixtures'; import { getJSONFixture } from 'helpers/fixtures';
import EvidenceBlock from '~/releases/components/evidence_block.vue'; import EvidenceBlock from '~/releases/components/evidence_block.vue';
import ReleaseBlock from '~/releases/components/release_block.vue'; import ReleaseBlock from '~/releases/components/release_block.vue';
...@@ -23,7 +22,6 @@ describe('Release block', () => { ...@@ -23,7 +22,6 @@ describe('Release block', () => {
}, },
provide: { provide: {
glFeatures: { glFeatures: {
releaseIssueSummary: true,
...featureFlags, ...featureFlags,
}, },
}, },
...@@ -201,51 +199,4 @@ describe('Release block', () => { ...@@ -201,51 +199,4 @@ describe('Release block', () => {
}); });
}); });
}); });
describe('when the releaseIssueSummary feature flag is disabled', () => {
describe('with default props', () => {
beforeEach(() => factory(release, { releaseIssueSummary: false }));
it('renders the milestone icon', () => {
expect(
milestoneListLabel()
.find(GlIcon)
.exists(),
).toBe(true);
});
it('renders the label as "Milestones" if more than one milestone is passed in', () => {
expect(
milestoneListLabel()
.find('.js-label-text')
.text(),
).toEqual('Milestones');
});
it('renders a link to the milestone with a tooltip', () => {
const milestone = release.milestones[0];
const milestoneLink = wrapper.find('.js-milestone-link');
expect(milestoneLink.exists()).toBe(true);
expect(milestoneLink.text()).toBe(milestone.title);
expect(milestoneLink.attributes('href')).toBe(milestone.webUrl);
expect(milestoneLink.attributes('title')).toBe(milestone.description);
});
});
it('renders the label as "Milestone" if only a single milestone is passed in', () => {
release.milestones = release.milestones.slice(0, 1);
return factory(release, { releaseIssueSummary: false }).then(() => {
expect(
milestoneListLabel()
.find('.js-label-text')
.text(),
).toEqual('Milestone');
});
});
});
}); });
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