Add the manifest detail sidebar
What does this MR do and why?
Adds manifest_sidebar.vue, mounted in DetailLayout's #sidebar slot on
the manifest detail page. Blocks render in this order: Repository (name
links back, kind rendered as a badge), Image, then either Platforms (an
index: one row per child, each labelled by its platform triple and linking
to that child's own manifest page) or Platform (a single image: its own
triple, stated in the singular), then Referenced by (links up to each
parent index), then Size, then Published.
Source and Downloads are deliberately not rendered, and the specs assert
they're absent. The design prototype shows both, but ContainerManifest
carries no created_by, project_id, or git_commit_sha, and nothing
stores a per-artifact download count. Following the merged rule, that's
designed out rather than shipped as a disabled placeholder.
Sidebar slot instead of a hand-rolled grid
The sibling Maven/npm page (version_detail.vue) builds its own two-column
layout with gl-grid plus a hand-rolled <aside>. DetailLayout already
provides that grid and a labelled sidebar region, so manifest_sidebar.vue
uses the #sidebar slot instead. There's no grid code in this component.
Edge cases follow the data, not the prototype
- A child whose platform triple is entirely null renders its digest alone, with no label. Dropping the row would contradict the children count; a placeholder would assert more than the data carries.
- Unlike a version, a manifest carries a real size on a remote repository, so there's no remote arm on the size guard — only a size that never arrived is withheld. An exact zero still renders as "0 B".
- A null
createdAtreads as "Unknown" rather than as the epoch.
platformLabel gap closed
This is the first thing in the app that calls platformLabel (in
utils.js, added in Step 0b). Its values are push-controlled and Artifact
Registry applies no charset filter, so a part carrying the / separator
was indistinguishable from two parts once joined: an architecture of
amd64/v8 rendered identically to an architecture amd64 with variant
v8. A part carrying a slash is now dropped, the same way a
whitespace-only part already was.
Query changes
get_manifest.query.graphql now also selects the repository kind (for
the badge) and, on the manifest, size, createdAt, architecture, os,
osVariant, children { digest architecture os osVariant }, and
parentDigests.
Adding kind reverses a deliberate Step 1 assertion in queries_spec.js
that the document asked for everything about the repository except the
kind. That test is updated and renamed, since the sidebar is what needed
it.
Testing gotcha: RouterLinkStub
manifest_detail_spec.js has several full-mount tests. Once the real
sidebar renders inside them it emits <router-link>, which isn't
registered in that spec, and the resulting errors cascaded into 23
unrelated failures across the suite. Fixed by stubbing
RouterLink: RouterLinkStub, the same way version_detail_spec.js already
does.
References
- Phase plan: gitlab-org/ops/artifact-registry!2461 (merged)
- Design prototype: https://gitlab-org.gitlab.io/ci-cd/package-stage/artifact-registry-design-proposal/
- Step 1, the manifest detail page this stacks on: !253776 (merged)
- Step 2, the tab bar (sibling, targets the same branch, touches a different slot): !254794 (merged)
Screenshots or screen recordings
There's no meaningful "before" — the sidebar didn't exist.
| Index manifest | Single image |
|---|---|
![]() |
![]() |
How to set up and validate locally
The manifest detail page isn't reachable by clicking yet — the container row link on the manifests table is Step 11, held until the GraphQL integration lands. So reach it by URL.
Image ids must come from the repository's own artifact list, since they're server-resolved, while manifest digests are derived from whatever image id they're handed. Pairing a derived image id with the page leaves the Image block empty, because the server doesn't know that id.
-
Enable the flags in the rails console:
Feature.enable(:artifact_registry_ui) Feature.enable(:org_stage_experimental) -
Visit the single image:
/o/default/-/artifact_registry/acme/repositories/docker-images/b7dad7c9-c3f8-9264-5f55-3619a3c720a4/manifests/sha256%3A2bae1fbf2bae1fc02bae1fc12bae1fc22bae1fc32bae1fc42bae1fc52bae1fc6 -
Visit the index that references it:
/o/default/-/artifact_registry/acme/repositories/docker-images/b7dad7c9-c3f8-9264-5f55-3619a3c720a4/manifests/sha256%3A5e30d0925e30d0935e30d0945e30d0955e30d0965e30d0975e30d0985e30d099 -
From the index, click a Platforms row to reach the child, then click Referenced by on the child to come back up.
Verification
Driven in the GDK against both variants. The index renders Repository
(docker-images, Hosted), Image (service-model), Platforms with three rows
(linux/amd64, linux/arm64/v8, linux/386) each linking to a child
digest, Size 356.62 MiB, Published Aug 14 2026. The single-image variant
renders Platform linux/amd64 in the singular plus Referenced by linking
up to the index. Clicking Referenced by navigates to the parent index,
whose Platforms list contains the child just left — the full round trip.
Zero console errors throughout.
Full artifact registry Jest suite on both Vue 2 and Vue 3: 2187 passing, 64
of 65 suites green. repository_detail_spec.js fails with 55 failures;
verified pre-existing by running it at the base commit with all changes
stashed and getting the identical 55 failures.
ESLint clean at --max-warnings 0, Prettier clean, locale/gitlab.pot
regenerated.
No changelog entry — the feature is dark behind artifact_registry_ui and
unreleased.
Stacked
Rebased onto master on 2026-09-10. Step 1
(!253776 (merged)) was squash-merged, so this
branch was cut off its old tip with git rebase --onto master rather than a plain rebase —
a squash leaves no matching patch ids, so a plain rebase would have tried to replay Step 1's
commits. This MR now targets master directly and carries only its own commit.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

