Add version statistics field to Artifact Registry GraphQL

What does this MR do and why?

Step 7 of the monolith/S06 "version detail" plan (work item #623231): the GraphQL read-time statistics field for a version in GitLab Artifact Registry.

What it adds:

  • A statistics field on ArtifactRegistryVersionDetails, resolved by a new VersionStatisticsResolver, returning a new ArtifactRegistryVersionStatistics type. It mounts on the detail type (not the plain version element type) for the same reason as the files connection: the detail subclass is an unrelated schema type, so the field is unnameable under the versions list connection. The resolver carries its own FieldCallCount limit of 1 for aliased re-selection.
  • ArtifactRegistryVersionStatistics exposes filesCount alone (nullable BigInt). The endpoint also serves size_bytes and last_downloaded_at, but Phase 1 renders neither, so the type omits them, per the monolith/S04 rule to read only what the slice renders. filesCount is null when Artifact Registry's response omits the count, which is every deployment before the serialization patch lands.

Statistics are packages-only and hosted-only: the resolver holds the format and the kind ahead of the client call, so a container repository or a non-hosted (virtual or remote) one resolves null with no request rather than surfacing Artifact Registry's 404. A 404 or 501 from the endpoint also maps to a null count.

This MR also drops a now-dead local @client extension of the plain ArtifactRegistryVersion type from typedefs.graphql: no document selects gitCommitSha on it (the version list reads the SHA through the server commitSha field, and the version detail read selects it on the detail type), so the extension had no consumer.

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 resolver refuses a non-package or non-hosted repository before it calls Artifact Registry, so that guard validates without a request. Run in rails runner (or paste into rails console):

HOSTED = ::Resolvers::ArtifactRegistry::VersionStatisticsResolver::HOSTED_KIND
raise "expected 'hosted', got #{HOSTED.inspect}" unless HOSTED == 'hosted'

repo = ->(format, kind) { ::ArtifactRegistry::Repository.new('format' => format, 'kind' => kind) }
# mirror of the two guard clauses: `packages?` and `kind == HOSTED_KIND`
reaches_client = ->(r) { r.packages? && r.kind == HOSTED }

# 1. hosted maven / npm -> guard passes, resolver would call the client
raise 'hosted maven should pass the guard' unless reaches_client.call(repo.call('maven', 'hosted'))
raise 'hosted npm should pass the guard'   unless reaches_client.call(repo.call('npm', 'hosted'))

# 2. a container repository (non-package format) -> null with no call
raise 'docker should be refused (not a package format)' if reaches_client.call(repo.call('docker', 'hosted'))

# 3. a non-hosted package repository (virtual/remote) -> null with no call
raise 'virtual npm should be refused' if reaches_client.call(repo.call('npm', 'virtual'))
raise 'remote maven should be refused' if reaches_client.call(repo.call('maven', 'remote'))

puts 'OK: statistics guard validated (hosted packages pass; container and non-hosted refused with no call)'

Expected output: OK: statistics guard validated (hosted packages pass; container and non-hosted refused with no call).

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