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 files keyset connection on ArtifactRegistryVersionDetails, resolved by a new VersionFilesResolver. 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 the versions list connection, which keeps a per-row fan-out from being expressible. The resolver also carries its own FieldCallCount limit of 1 for aliased re-selection.
  • Two format-specific file element types, ArtifactRegistryMavenVersionFile and ArtifactRegistryNpmVersionFile, and a ArtifactRegistryVersionFile union over them. The union's resolve_type dispatches on the file value-object class and fails closed on an unknown one. Both element types take their id from the ExposesElementId concern.
  • Three nullable fields for distinct reasons: Maven md5 because a deploy may store none; Maven createdAt because the file resource withholds the column until Artifact Registry serializes it; npm createdAt because 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

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.

Edited by Rahul Chanila

Merge request reports

Loading
Loading