Add artifact registry client gem foundation and repository fetch

What does this MR do and why?

Adds the Artifact Registry client foundation and repository fetch, packaged as a self-contained EE path gem — gitlab-artifact_registry-client at ee/gems/gitlab-artifact_registry-client/ (module namespace Gitlab::ArtifactRegistry).

This supersedes !244245 (merged), which implemented the same S02 Step 1 slice under ee/lib/artifact_registry/. Reviewer direction there (!244245 (comment 3569734425)) was to package the client as a gem from the start (modular components, less coupling; ee/gems/ because the Artifact Registry is EE-only). This branch carries the reviewed ee/lib/ implementation plus the extraction into the gem:

  • The gem is self-contained: runtime dependencies are activesupport, faraday, faraday-retry only. Every deployment-specific input is constructor-injected (base_url:, user_agent:, correlation_id:, error_callback:, token_provider:); the gem reads no monolith configuration and calls no monolith error tracking. The Gitlab.config.artifact_registry stanza moves to the consuming slice (monolith/S03) with its first reader.
  • The credential seam's in-gem default returns no credential, so the client raises AuthorizationError before issuing any request (fail closed); the consuming slice injects the functional token provider (any object responding to call(slug:)).
  • First ee/gems/ gem: the root Gemfile gates bundling with install_if on the ee/ directory while the shared lockfile keeps the entry; doc/development/gems.md gains an "EE-only gems" section documenting the pattern.
  • Top-level constants in gem code are fully qualified (::Faraday, ::ERB, ::DateTime): inside the monolith, an unqualified Faraday resolves to the host's Gitlab::Faraday module once the autoloader defines it — a runtime collision the gem's standalone specs cannot catch (found by exercising the gem in rails runner).

Design source of truth: monolith/S02 spec and amended plan, Step 1 (amendment MR: gitlab-org/ops/artifact-registry!1043 (merged)).

Note: I have followed the process to reserve the gem name, and have added gitlab_rubygems as the owner.

How to set up and validate locally

Run the gem's standalone suite:

cd ee/gems/gitlab-artifact_registry-client && bundle install && bundle exec rspec

To exercise against a live Artifact Registry you'll need the caproni AR dev rig (https://gitlab.com/gitlab-com/gl-infra/sandbox/caproni-demo/-/tree/main/artifact-registry); the default base URL from a GDK rails console is http://localhost:8080.

  1. Bring up the caproni AR rig, then seed a namespace and repository (scripts/seed-namespace.sh; namespace gitlab-org, repository test).
  2. Pre-flight the backend directly: curl -s -H "Authorization: Bearer local-dev-not-a-secret" http://localhost:8080/api/v1/gitlab-org/repositories/test | jq
  3. In a rails console (token injected through a stand-in provider, since the in-gem default returns no credential):
client = Gitlab::ArtifactRegistry::Client.new(
  base_url: 'http://localhost:8080',
  token_provider: ->(slug:) { 'local-dev-not-a-secret' }
)
repo = client.repository(slug: 'gitlab-org', name: 'test')
[repo.class, repo&.name, repo&.format, repo&.kind, repo&.visibility]
# => [Gitlab::ArtifactRegistry::Repository, "test", "container", "hosted", "public"]
client.repository(slug: 'gitlab-org', name: 'nope') # => nil (404 path)

# Fail-closed default: no injected provider -> raises before any request
Gitlab::ArtifactRegistry::Client.new(base_url: 'http://localhost:8080')
  .repository(slug: 'gitlab-org', name: 'test')
# => raises Gitlab::ArtifactRegistry::Client::AuthorizationError

Related to #605077 (closed)

Edited by Fiona McCawley

Merge request reports

Loading
Loading