Add the versions table to the artifact version list

What does this MR do and why?

Note

Targets !249937 (merged), the artifact name link, which in turn targets !249847 (merged). Both merge first.

This change is behind the feature flag :artifact_registry_ui

The artifact version list page rendered a header and nothing else. This adds the table of a Maven or npm artifact's versions, with two columns: Version and Published. Docker and OCI artifacts address their versions through manifests, read through a document of their own in the next step, so the connection query is skipped for them and the page still renders header-only.

The design proposal's version table draws seven things. What happened to each:

Design column Status
Version Ships
Published Ships
Source Descoped — Source is out of the beta, so the three attribution fields the contract carries on a version are never declared
Tags Phase 2
Row menu A later step ships View pull command; nothing else is Phase 1
Downloads Not in the contract — api/openapi/v1.yaml's Version schema carries no download count
Size Not in the contract — size exists only per file, and the spec offers no aggregate

Version does carry last_downloaded_at, a nullable timestamp only npm writes today. That is a different thing from a download count, and not a column the design draws, so it stays out.

Changes

  • New version query. graphql/queries/get_artifact_versions.query.graphql, a per-connection document modelled on the merged get_repository_packages.query.graphql. It repeats artifactId on the @client parent because Apollo prunes only the @client field's own variables: a variable used solely by a nested field survives into the document sent to the server, which then rejects it as declared but unused. graphql/queries_spec.js already guards exactly that, and this document plus the parent step's get_artifact.query.graphql were both added to its table.
  • Typedefs. ArtifactRegistryVersion and ArtifactRegistryVersionConnection, and a versions field on both ArtifactRegistryMavenPackage and ArtifactRegistryNpmPackage — the package is a union rather than an interface, so a query reaches the field inside an inline fragment on each member. Only id, version, and createdAt are declared. The attribution fields were held back for the Source column, which has since been descoped, so they stay undeclared.
  • Mock resolver. A versions resolver under both package typenames, reusing the existing delay, paginate, and artifactKey helpers. It sorts newest-first before slicing, because Artifact Registry lists versions sort=created_at&order=desc by default and the ordering is the server's rather than the table's.
  • Seed data. A version ladder on each seeded Maven and npm artifact, held under publishedVersions rather than versions — mirroring how a repository holds artifacts and serves them as images or packages. Apollo falls back to a same-named property on the parent when it runs local resolvers in forced-only mode, so a raw array named versions got written where a connection belonged, producing six Missing field 'nodes' while writing result cache errors in the browser. Versions also mint ids from a sequence of their own, so adding versions cannot renumber the artifacts whose ids are the URLs the repository detail table links to, and an npm package's versionsCount is now derived from the ladder's length rather than declared.
  • New components. repositories/versions/versions_table.vue (the version string, and the publication date through the merged TimeAgoTooltip) and repositories/versions/versions_section.vue (skeleton, then error alert, then table, following the merged detail/artifacts_section.vue; the empty state joins as a branch in a later step).
  • Version list wiring. A second Apollo query with CACHE_AND_NETWORK and a skip() for container formats, its own error flag, and the table region under the existing page heading. The existing aria-live region reports the table region too rather than a second region being added.
  • Specs. The new table and section, the second query's skip, loading, and error paths per format family, the resolver's newest-first ordering, and a seed guard that every artifact and version id is distinct, since the Apollo cache normalizes both on id alone.

Keyset pagination is deliberately absent: the document asks for no page window, so the mock returns every row and nothing is silently truncated. A later step adds pageInfo, the pager, and the connection cache policy.

Screenshots or screen recordings

maven versions

How to set up and validate locally

  1. Enable the flag: Feature.enable(:artifact_registry_ui).
  2. Visit /o/<organization>/-/artifact_registry/acme/repositories.
  3. Open payment-core and click an artifact name. Confirm the table renders six versions newest-first, with relative publication times whose tooltips carry the absolute date.
  4. Open ui-components and click an artifact name. Confirm the same table, and that the Versions count on the repository table matches the number of rows.
  5. Open payment-service or oci-artifacts and click an artifact name. Confirm the page renders the header alone: no table, nothing left loading, and no error.

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.

Edited by Zack Cuddy

Merge request reports

Loading
Loading