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 mergedget_repository_packages.query.graphql. It repeatsartifactIdon the@clientparent because Apollo prunes only the@clientfield'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.jsalready guards exactly that, and this document plus the parent step'sget_artifact.query.graphqlwere both added to its table. - Typedefs.
ArtifactRegistryVersionandArtifactRegistryVersionConnection, and aversionsfield on bothArtifactRegistryMavenPackageandArtifactRegistryNpmPackage— the package is a union rather than an interface, so a query reaches the field inside an inline fragment on each member. Onlyid,version, andcreatedAtare declared. The attribution fields were held back for the Source column, which has since been descoped, so they stay undeclared. - Mock resolver. A
versionsresolver under both package typenames, reusing the existingdelay,paginate, andartifactKeyhelpers. It sorts newest-first before slicing, because Artifact Registry lists versionssort=created_at&order=descby 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
publishedVersionsrather thanversions— mirroring how a repository holdsartifactsand serves them asimagesorpackages. Apollo falls back to a same-named property on the parent when it runs local resolvers in forced-only mode, so a raw array namedversionsgot written where a connection belonged, producing sixMissing field 'nodes' while writing resultcache 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'sversionsCountis 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 mergedTimeAgoTooltip) andrepositories/versions/versions_section.vue(skeleton, then error alert, then table, following the mergeddetail/artifacts_section.vue; the empty state joins as a branch in a later step). - Version list wiring. A second Apollo query with
CACHE_AND_NETWORKand askip()for container formats, its own error flag, and the table region under the existing page heading. The existingaria-liveregion 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
How to set up and validate locally
- Enable the flag:
Feature.enable(:artifact_registry_ui). - Visit
/o/<organization>/-/artifact_registry/acme/repositories. - Open
payment-coreand click an artifact name. Confirm the table renders six versions newest-first, with relative publication times whose tooltips carry the absolute date. - Open
ui-componentsand click an artifact name. Confirm the same table, and that the Versions count on the repository table matches the number of rows. - Open
payment-serviceoroci-artifactsand 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.
