Commit 032de703 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch '239518-always-display-build-info-for-packages-in-the-ui' into 'master'

Display more pipelines info in package history

See merge request gitlab-org/gitlab!49040
parents d9ad3c6d 5e0291a4
<script> <script>
import { GlLink, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale'; import { first } from 'lodash';
import { s__, n__ } from '~/locale';
import { truncateSha } from '~/lib/utils/text_utility';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue'; import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
export default { export default {
name: 'PackageHistory', name: 'PackageHistory',
i18n: { i18n: {
createdOn: s__('PackageRegistry|%{name} version %{version} was created %{datetime}'), createdOn: s__('PackageRegistry|%{name} version %{version} was first created %{datetime}'),
updatedAtText: s__('PackageRegistry|%{name} version %{version} was updated %{datetime}'), createdByCommitText: s__('PackageRegistry|Created by commit %{link} on branch %{branch}'),
commitText: s__('PackageRegistry|Commit %{link} on branch %{branch}'), createdByPipelineText: s__(
pipelineText: s__('PackageRegistry|Pipeline %{link} triggered %{datetime} by %{author}'), 'PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}',
),
publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'), publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'),
combinedUpdateText: s__(
'PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}',
),
archivedPipelineMessageSingular: s__('PackageRegistry|Package has %{number} archived update'),
archivedPipelineMessagePlural: s__('PackageRegistry|Package has %{number} archived updates'),
}, },
components: { components: {
GlLink, GlLink,
...@@ -35,8 +44,32 @@ export default { ...@@ -35,8 +44,32 @@ export default {
}; };
}, },
computed: { computed: {
packagePipeline() { pipelines() {
return this.packageEntity.pipeline?.id ? this.packageEntity.pipeline : null; return this.packageEntity.pipelines || [];
},
firstPipeline() {
return first(this.pipelines);
},
lastPipelines() {
return this.pipelines.slice(1).slice(-HISTORY_PIPELINES_LIMIT);
},
showPipelinesInfo() {
return Boolean(this.firstPipeline?.id);
},
archiviedLines() {
return Math.max(this.pipelines.length - HISTORY_PIPELINES_LIMIT - 1, 0);
},
archivedPipelineMessage() {
return n__(
this.$options.i18n.archivedPipelineMessageSingular,
this.$options.i18n.archivedPipelineMessagePlural,
this.archiviedLines,
);
},
},
methods: {
truncate(value) {
return truncateSha(value);
}, },
}, },
}; };
...@@ -59,46 +92,35 @@ export default { ...@@ -59,46 +92,35 @@ export default {
</template> </template>
</gl-sprintf> </gl-sprintf>
</history-item> </history-item>
<history-item icon="pencil" data-testid="updated-at">
<gl-sprintf :message="$options.i18n.updatedAtText"> <template v-if="showPipelinesInfo">
<template #name> <!-- FIRST PIPELINE BLOCK -->
<strong>{{ packageEntity.name }}</strong> <history-item icon="commit" data-testid="first-pipeline-commit">
</template> <gl-sprintf :message="$options.i18n.createdByCommitText">
<template #version>
<strong>{{ packageEntity.version }}</strong>
</template>
<template #datetime>
<time-ago-tooltip :time="packageEntity.updated_at" />
</template>
</gl-sprintf>
</history-item>
<template v-if="packagePipeline">
<history-item icon="commit" data-testid="commit">
<gl-sprintf :message="$options.i18n.commitText">
<template #link> <template #link>
<gl-link :href="packagePipeline.project.commit_url">{{ <gl-link :href="firstPipeline.project.commit_url"
packagePipeline.sha >#{{ truncate(firstPipeline.sha) }}</gl-link
}}</gl-link> >
</template> </template>
<template #branch> <template #branch>
<strong>{{ packagePipeline.ref }}</strong> <strong>{{ firstPipeline.ref }}</strong>
</template> </template>
</gl-sprintf> </gl-sprintf>
</history-item> </history-item>
<history-item icon="pipeline" data-testid="pipeline"> <history-item icon="pipeline" data-testid="first-pipeline-pipeline">
<gl-sprintf :message="$options.i18n.pipelineText"> <gl-sprintf :message="$options.i18n.createdByPipelineText">
<template #link> <template #link>
<gl-link :href="packagePipeline.project.pipeline_url" <gl-link :href="firstPipeline.project.pipeline_url">#{{ firstPipeline.id }}</gl-link>
>#{{ packagePipeline.id }}</gl-link
>
</template> </template>
<template #datetime> <template #datetime>
<time-ago-tooltip :time="packagePipeline.created_at" /> <time-ago-tooltip :time="firstPipeline.created_at" />
</template> </template>
<template #author>{{ packagePipeline.user.name }}</template> <template #author>{{ firstPipeline.user.name }}</template>
</gl-sprintf> </gl-sprintf>
</history-item> </history-item>
</template> </template>
<!-- PUBLISHED LINE -->
<history-item icon="package" data-testid="published"> <history-item icon="package" data-testid="published">
<gl-sprintf :message="$options.i18n.publishText"> <gl-sprintf :message="$options.i18n.publishText">
<template #project> <template #project>
...@@ -109,6 +131,37 @@ export default { ...@@ -109,6 +131,37 @@ export default {
</template> </template>
</gl-sprintf> </gl-sprintf>
</history-item> </history-item>
<history-item v-if="archiviedLines" icon="history" data-testid="archived">
<gl-sprintf :message="archivedPipelineMessage">
<template #number>
<strong>{{ archiviedLines }}</strong>
</template>
</gl-sprintf>
</history-item>
<!-- PIPELINES LIST ENTRIES -->
<history-item
v-for="pipeline in lastPipelines"
:key="pipeline.id"
icon="pencil"
data-testid="pipeline-entry"
>
<gl-sprintf :message="$options.i18n.combinedUpdateText">
<template #link>
<gl-link :href="pipeline.project.commit_url">#{{ truncate(pipeline.sha) }}</gl-link>
</template>
<template #branch>
<strong>{{ pipeline.ref }}</strong>
</template>
<template #pipeline>
<gl-link :href="pipeline.project.pipeline_url">#{{ pipeline.id }}</gl-link>
</template>
<template #datetime>
<time-ago-tooltip :time="pipeline.created_at" />
</template>
</gl-sprintf>
</history-item>
</ul> </ul>
</div> </div>
</template> </template>
...@@ -45,3 +45,5 @@ export const NpmManager = { ...@@ -45,3 +45,5 @@ export const NpmManager = {
export const FETCH_PACKAGE_VERSIONS_ERROR = s__( export const FETCH_PACKAGE_VERSIONS_ERROR = s__(
'PackageRegistry|Unable to fetch package version information.', 'PackageRegistry|Unable to fetch package version information.',
); );
export const HISTORY_PIPELINES_LIMIT = 5;
---
title: Display more pipelines info in package history
merge_request: 49040
author:
type: changed
...@@ -19564,10 +19564,7 @@ msgstr "" ...@@ -19564,10 +19564,7 @@ msgstr ""
msgid "Package type must be PyPi" msgid "Package type must be PyPi"
msgstr "" msgstr ""
msgid "PackageRegistry|%{name} version %{version} was created %{datetime}" msgid "PackageRegistry|%{name} version %{version} was first created %{datetime}"
msgstr ""
msgid "PackageRegistry|%{name} version %{version} was updated %{datetime}"
msgstr "" msgstr ""
msgid "PackageRegistry|Add Conan Remote" msgid "PackageRegistry|Add Conan Remote"
...@@ -19585,7 +19582,7 @@ msgstr "" ...@@ -19585,7 +19582,7 @@ msgstr ""
msgid "PackageRegistry|App name: %{name}" msgid "PackageRegistry|App name: %{name}"
msgstr "" msgstr ""
msgid "PackageRegistry|Commit %{link} on branch %{branch}" msgid "PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}"
msgstr "" msgstr ""
msgid "PackageRegistry|Composer" msgid "PackageRegistry|Composer"
...@@ -19645,6 +19642,9 @@ msgstr "" ...@@ -19645,6 +19642,9 @@ msgstr ""
msgid "PackageRegistry|Copy yarn setup command" msgid "PackageRegistry|Copy yarn setup command"
msgstr "" msgstr ""
msgid "PackageRegistry|Created by commit %{link} on branch %{branch}"
msgstr ""
msgid "PackageRegistry|Delete Package Version" msgid "PackageRegistry|Delete Package Version"
msgstr "" msgstr ""
...@@ -19711,10 +19711,16 @@ msgstr "" ...@@ -19711,10 +19711,16 @@ msgstr ""
msgid "PackageRegistry|Package Registry" msgid "PackageRegistry|Package Registry"
msgstr "" msgstr ""
msgid "PackageRegistry|Pip Command" msgid "PackageRegistry|Package has %{number} archived update"
msgstr "" msgstr ""
msgid "PackageRegistry|Pipeline %{link} triggered %{datetime} by %{author}" msgid "PackageRegistry|Package has %{number} archived updates"
msgstr ""
msgid "PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}"
msgstr ""
msgid "PackageRegistry|Pip Command"
msgstr "" msgstr ""
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}" msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
......
...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import { GlLink, GlSprintf } from '@gitlab/ui'; import { GlLink, GlSprintf } from '@gitlab/ui';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue'; import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
import component from '~/packages/details/components/package_history.vue'; import component from '~/packages/details/components/package_history.vue';
import { mavenPackage, mockPipelineInfo } from '../../mock_data'; import { mavenPackage, mockPipelineInfo } from '../../mock_data';
...@@ -13,6 +14,9 @@ describe('Package History', () => { ...@@ -13,6 +14,9 @@ describe('Package History', () => {
packageEntity: { ...mavenPackage }, packageEntity: { ...mavenPackage },
}; };
const createPipelines = amount =>
[...Array(amount)].map((x, index) => ({ ...mockPipelineInfo, id: index + 1 }));
const mountComponent = props => { const mountComponent = props => {
wrapper = shallowMount(component, { wrapper = shallowMount(component, {
propsData: { ...defaultProps, ...props }, propsData: { ...defaultProps, ...props },
...@@ -56,55 +60,58 @@ describe('Package History', () => { ...@@ -56,55 +60,58 @@ describe('Package History', () => {
expect.arrayContaining(['timeline', 'main-notes-list', 'notes']), expect.arrayContaining(['timeline', 'main-notes-list', 'notes']),
); );
}); });
describe.each` describe.each`
name | icon | text | timeAgoTooltip | link name | amount | icon | text | timeAgoTooltip | link
${'created-on'} | ${'clock'} | ${'Test package version 1.0.0 was created'} | ${mavenPackage.created_at} | ${null} ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'Test package version 1.0.0 was first created'} | ${mavenPackage.created_at} | ${null}
${'updated-at'} | ${'pencil'} | ${'Test package version 1.0.0 was updated'} | ${mavenPackage.updated_at} | ${null} ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit #sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url}
${'commit'} | ${'commit'} | ${'Commit sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url} ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url}
${'pipeline'} | ${'pipeline'} | ${'Pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url} ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null}
${'published'} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null} ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null}
`('history element $name', ({ name, icon, text, timeAgoTooltip, link }) => { ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null}
let element; ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit #sha-baz on branch branch-name, built by pipeline #3, and published to the registry'} | ${mavenPackage.created_at} | ${mockPipelineInfo.project.commit_url}
`(
beforeEach(() => { 'with $amount pipelines history element $name',
mountComponent({ packageEntity: { ...mavenPackage, pipeline: mockPipelineInfo } }); ({ name, icon, text, timeAgoTooltip, link, amount }) => {
element = findHistoryElement(name); let element;
});
beforeEach(() => {
it('has the correct icon', () => { mountComponent({
expect(element.props('icon')).toBe(icon); packageEntity: { ...mavenPackage, pipelines: createPipelines(amount) },
}); });
element = findHistoryElement(name);
it('has the correct text', () => { });
expect(element.text()).toBe(text);
}); it('exists', () => {
expect(element.exists()).toBe(true);
it('time-ago tooltip', () => { });
const timeAgo = findElementTimeAgo(element);
const exist = Boolean(timeAgoTooltip); it('has the correct icon', () => {
expect(element.props('icon')).toBe(icon);
expect(timeAgo.exists()).toBe(exist); });
if (exist) {
expect(timeAgo.props('time')).toBe(timeAgoTooltip); it('has the correct text', () => {
} expect(element.text()).toBe(text);
}); });
it('link', () => { it('time-ago tooltip', () => {
const linkElement = findElementLink(element); const timeAgo = findElementTimeAgo(element);
const exist = Boolean(link); const exist = Boolean(timeAgoTooltip);
expect(linkElement.exists()).toBe(exist); expect(timeAgo.exists()).toBe(exist);
if (exist) { if (exist) {
expect(linkElement.attributes('href')).toBe(link); expect(timeAgo.props('time')).toBe(timeAgoTooltip);
} }
}); });
});
it('link', () => {
describe('when pipelineInfo is missing', () => { const linkElement = findElementLink(element);
it.each(['commit', 'pipeline'])('%s history element is hidden', name => { const exist = Boolean(link);
mountComponent();
expect(findHistoryElement(name).exists()).toBe(false); expect(linkElement.exists()).toBe(exist);
}); if (exist) {
}); expect(linkElement.attributes('href')).toBe(link);
}
});
},
);
}); });
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