Add GraphQL files connection to version details type (monolith/S06 plan: 6/22)
What does this MR do and why?
Step 6 of the monolith/S06 "version detail" plan (work item #623231): the GraphQL files connection for a version in GitLab Artifact Registry, feeding the version detail Files tab.
What it adds:
- A
fileskeyset connection onArtifactRegistryVersionDetails, resolved by a newVersionFilesResolver. It mounts on the detail type, not the plain version element type: graphql-ruby emits the detail subclass as an unrelated type, so the connection is unnameable under theversionslist connection, which keeps a per-row fan-out from being expressible. The resolver also carries its ownFieldCallCountlimit of 1 for aliased re-selection. - Two format-specific file element types,
ArtifactRegistryMavenVersionFileandArtifactRegistryNpmVersionFile, and aArtifactRegistryVersionFileunion over them. The union'sresolve_typedispatches on the file value-object class and fails closed on an unknown one. Both element types take their id from theExposesElementIdconcern. - Three nullable fields for distinct reasons: Maven
md5because a deploy may store none; MavencreatedAtbecause the file resource withholds the column until Artifact Registry serializes it; npmcreatedAtbecause a remote cached row carries none.
The resolver reads the repository, format, organization, and version id off the version presenter and forwards only the standard keyset arguments; the endpoint sorts by file name alone, so there is no sort argument. A version deleted between the repository read and the files read resolves the connection null rather than erroring, without failing the version's sibling fields.
Behind the shared artifact_registry_ui feature flag, dark. Schema text only, so no changelog and no user-facing i18n. The GraphQL reference docs, introspection schema, and possible_types.json are regenerated.
References
- Work item: #623231
- Plan: https://gitlab.com/gitlab-org/ops/artifact-registry/-/blob/main/docs/plans/monolith/2026-08-18-version-detail.md (Step 6)
- Spec: https://gitlab.com/gitlab-org/ops/artifact-registry/-/blob/main/docs/specs/monolith/S06-version-detail.md (files connection)
- Stacked below: !253909 (merged) (Step 7)
How to set up and validate locally
The union that routes each file to its element type is a pure dispatch, so it validates without an Artifact Registry request. Run in rails runner (or paste into rails console):
union = ::Types::ArtifactRegistry::VersionFileType
maven = ::ArtifactRegistry::MavenFile.new('file_name' => 'app-1.0.jar', 'size_bytes' => '42')
npm = ::ArtifactRegistry::NpmFile.new('file_name' => 'demo-1.0.tgz', 'size_bytes' => '7')
# 1. each file value object resolves to its own element type
raise 'expected Maven file type' unless union.resolve_type(maven, {}) == ::Types::ArtifactRegistry::MavenVersionFileType
raise 'expected npm file type' unless union.resolve_type(npm, {}) == ::Types::ArtifactRegistry::NpmVersionFileType
# 2. fail closed: an unknown value-object class raises rather than resolving to a wrong arm
begin
union.resolve_type(Object.new, {})
raise 'expected TypeNotSupportedError for an unknown file class'
rescue ::Types::ArtifactRegistry::VersionFileType::TypeNotSupportedError
# expected
end
# 3. the union covers exactly the two file element types
names = union.possible_types.map(&:graphql_name).sort
raise "unexpected members: #{names}" unless names == %w[ArtifactRegistryMavenVersionFile ArtifactRegistryNpmVersionFile]
puts 'OK: files union dispatch validated (Maven, npm, fail-closed, membership)'Expected output: OK: files union dispatch validated (Maven, npm, fail-closed, membership).
Suggested labels
~"type::feature" ~backend ~frontend ~"Category:Artifact Registry" ~"group::container registry"
Screenshots or screen recordings
N/A. Schema text only, behind a dark feature flag, with no rendered UI change in this MR.