Skip to content
代码片段 群组 项目
未验证 提交 4cc3d0bd 编辑于 作者: Alper Akgun's avatar Alper Akgun 提交者: GitLab
浏览文件

Merge branch '523666-model-experiments-add-artifacts-list-component-to-runs' into 'master'

Model experiments: Add artifacts list component to runs

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183678



Merged-by: default avatarAlper Akgun <aakgun@gitlab.com>
Approved-by: default avatarChaoyue Zhao <czhao@gitlab.com>
Approved-by: default avatarSimon Knox <simon@gitlab.com>
Approved-by: default avatarAlper Akgun <aakgun@gitlab.com>
Reviewed-by: default avatarSimon Knox <simon@gitlab.com>
Reviewed-by: default avatarFred de Gier <fdegier@gitlab.com>
Reviewed-by: default avatarChaoyue Zhao <czhao@gitlab.com>
Reviewed-by: default avatarGitLab Duo <gitlab-duo@gitlab.com>
Co-authored-by: default avatarfdegier <fdegier@gitlab.com>
No related branches found
No related tags found
2 合并请求!3031Merge per-main-jh to main-jh by luzhiyuan,!3030Merge per-main-jh to main-jh
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import { isEmpty, maxBy, range } from 'lodash'; import { isEmpty, maxBy, range } from 'lodash';
import { __, s__, sprintf } from '~/locale'; import { __, s__, sprintf } from '~/locale';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_PACKAGES_PACKAGE } from '~/graphql_shared/constants';
export default { export default {
name: 'CandidateDetail', name: 'CandidateDetail',
...@@ -20,6 +22,8 @@ export default { ...@@ -20,6 +22,8 @@ export default {
GlTab, GlTab,
GlTabs, GlTabs,
GlTableLite, GlTableLite,
PackageFiles: () =>
import('~/packages_and_registries/package_registry/components/details/package_files.vue'),
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -34,6 +38,19 @@ export default { ...@@ -34,6 +38,19 @@ export default {
info() { info() {
return this.candidate.info; return this.candidate.info;
}, },
projectPath() {
return this.candidate.projectPath;
},
packageType() {
return 'ml_model';
},
packageId() {
if (!this.info?.pathToArtifact) return null;
return convertToGraphQLId(
TYPENAME_PACKAGES_PACKAGE,
this.info.pathToArtifact.split('/packages/')[1],
);
},
ciJob() { ciJob() {
return this.info.ciJob; return this.info.ciJob;
}, },
...@@ -179,13 +196,12 @@ export default { ...@@ -179,13 +196,12 @@ export default {
</section> </section>
</gl-tab> </gl-tab>
<gl-tab :title="$options.i18n.artifactsLabel" class="gl-pt-3" data-testid="artifacts"> <gl-tab :title="$options.i18n.artifactsLabel" class="gl-pt-3" data-testid="artifacts">
<gl-link <package-files
v-if="info.pathToArtifact" v-if="info.pathToArtifact"
:href="info.pathToArtifact" :project-path="projectPath"
data-testid="artifacts-link" :package-type="packageType"
> :package-id="packageId"
{{ $options.i18n.artifactsLabel }} />
</gl-link>
<div v-else class="gl-text-subtle">{{ $options.i18n.noArtifactsMessage }}</div> <div v-else class="gl-text-subtle">{{ $options.i18n.noArtifactsMessage }}</div>
</gl-tab> </gl-tab>
<gl-tab :title="$options.i18n.performanceLabel" class="gl-pt-3" data-testid="metrics"> <gl-tab :title="$options.i18n.performanceLabel" class="gl-pt-3" data-testid="metrics">
......
import { initSimpleApp } from '~/helpers/init_simple_app_helper'; import { initSimpleApp } from '~/helpers/init_simple_app_helper';
import MlCandidateShow from '~/ml/experiment_tracking/routes/candidates/show'; import MlCandidateShow from '~/ml/experiment_tracking/routes/candidates/show';
initSimpleApp('#js-show-ml-candidate', MlCandidateShow, { name: 'MlCandidateShow' }); initSimpleApp('#js-show-ml-candidate', MlCandidateShow, {
withApolloProvider: true,
name: 'MlCandidateShow',
});
import { GlAvatarLabeled, GlButton } from '@gitlab/ui'; import { GlAvatarLabeled, GlButton } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { mountExtended } from 'helpers/vue_test_utils_helper'; import { mountExtended } from 'helpers/vue_test_utils_helper';
import CandidateDetail from '~/ml/experiment_tracking/routes/candidates/show/candidate_detail.vue'; import CandidateDetail from '~/ml/experiment_tracking/routes/candidates/show/candidate_detail.vue';
import { newCandidate } from 'jest/ml/model_registry/mock_data'; import { newCandidate } from 'jest/ml/model_registry/mock_data';
import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
import createMockApollo from 'helpers/mock_apollo_helper';
Vue.use(VueApollo);
describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', () => { describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', () => {
let wrapper; let wrapper;
...@@ -10,8 +16,10 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', ( ...@@ -10,8 +16,10 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', (
candidate: newCandidate(), candidate: newCandidate(),
}; };
const createWrapper = (props = {}) => { const createWrapper = (props = {}, mountFn = mountExtended) => {
return mountExtended(CandidateDetail, { const apolloProvider = createMockApollo();
return mountFn(CandidateDetail, {
apolloProvider,
propsData: { propsData: {
...defaultProps, ...defaultProps,
...props, ...props,
...@@ -27,7 +35,7 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', ( ...@@ -27,7 +35,7 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', (
const findMetadata = () => wrapper.findByTestId('metadata'); const findMetadata = () => wrapper.findByTestId('metadata');
const findMlflowRunId = () => wrapper.findByTestId('mlflow-run-id'); const findMlflowRunId = () => wrapper.findByTestId('mlflow-run-id');
const findCiJobPathLink = () => wrapper.findByTestId('ci-job-path'); const findCiJobPathLink = () => wrapper.findByTestId('ci-job-path');
const findArtifactLink = () => wrapper.findByTestId('artifacts-link'); const findPackageFiles = () => wrapper.findComponent(PackageFiles);
const findAvatarLabeled = () => wrapper.findComponent(GlAvatarLabeled); const findAvatarLabeled = () => wrapper.findComponent(GlAvatarLabeled);
const findParametersSection = () => wrapper.findByTestId('parameters'); const findParametersSection = () => wrapper.findByTestId('parameters');
const findParametersTable = () => wrapper.findByTestId('parameters-table'); const findParametersTable = () => wrapper.findByTestId('parameters-table');
...@@ -169,9 +177,15 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', ( ...@@ -169,9 +177,15 @@ describe('ml/experiment_tracking/routes/candidates/show/candidate_detail.vue', (
}); });
describe('Artifacts tab', () => { describe('Artifacts tab', () => {
it('renders artifact link when available', () => { it('renders files', () => {
wrapper = createWrapper(); wrapper = createWrapper({});
expect(findArtifactLink().attributes('href')).toBe('path_to_artifact'); expect(findPackageFiles().props()).toEqual({
packageId: 'gid://gitlab/Packages::Package/12',
projectPath: 'some/project',
packageType: 'ml_model',
canDelete: false,
deleteAllFiles: false,
});
}); });
it('shows no artifacts message when artifact path is missing', () => { it('shows no artifacts message when artifact path is missing', () => {
......
...@@ -18,7 +18,7 @@ export const newCandidate = (withModel = true) => ({ ...@@ -18,7 +18,7 @@ export const newCandidate = (withModel = true) => ({
iid: 'candidate_iid', iid: 'candidate_iid',
eid: 'abcdefg', eid: 'abcdefg',
gid: 'gid://gitlab/Ml::Candidate/1', gid: 'gid://gitlab/Ml::Candidate/1',
pathToArtifact: 'path_to_artifact', pathToArtifact: 'path_to_artifact/packages/12',
experimentName: 'The Experiment', experimentName: 'The Experiment',
pathToExperiment: 'path/to/experiment', pathToExperiment: 'path/to/experiment',
status: 'SUCCESS', status: 'SUCCESS',
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册