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-retryonly. 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. TheGitlab.config.artifact_registrystanza 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
AuthorizationErrorbefore issuing any request (fail closed); the consuming slice injects the functional token provider (any object responding tocall(slug:)). - First
ee/gems/gem: the rootGemfilegates bundling withinstall_ifon theee/directory while the shared lockfile keeps the entry;doc/development/gems.mdgains an "EE-only gems" section documenting the pattern. - Top-level constants in gem code are fully qualified (
::Faraday,::ERB,::DateTime): inside the monolith, an unqualifiedFaradayresolves to the host'sGitlab::Faradaymodule once the autoloader defines it — a runtime collision the gem's standalone specs cannot catch (found by exercising the gem inrails 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 rspecTo 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.
- Bring up the caproni AR rig, then seed a namespace and repository (
scripts/seed-namespace.sh; namespacegitlab-org, repositorytest). - 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 - 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::AuthorizationErrorRelated to #605077 (closed)