Bind the artifact registry client documents to the schema

What does this MR do and why?

Binds the Artifact Registry client's GraphQL documents to the real schema, and replaces the local seed store with a generator.

The repositories list, the repository create/update/delete mutations, the detail read, the image and package connections' parent, the edit prefill, the artifact read, and the artifact versions read all resolved against a local Apollo @client layer. Their schema surface has since landed, so each document now asks the server for what the server carries, and keeps @client only where the schema has nothing.

The mock layer that remains generates artifacts, and a version ladder per package, from the repository name rather than serving a fixed set of seeded repositories. Keying on the name is what lets a repository Artifact Registry actually holds render an artifact list, which a fixed set could not: it held four names of its own, so a real repository resolved nothing. Version dates count back from today, so a list reads as days or weeks old rather than years.

Binding the parents removed the local single-repository resolver, and with it the guard that kept a local answer from overriding a server-resolved one, the name-to-format convention, and the cache-aware format lookup. A repository the service does not hold now renders not-found because the server resolves it null, rather than because a local lookup missed.

Scope note

This is wider than one plan step. It carries the repositories list binding plus the repository mutations and the detail read, because binding the list exposed three browser-visible breaks in views that shared the same local layer — the images tab, the packages tab, and the edit prefill — each of which rendered nothing for a repository the real service holds. Splitting them would have left master with those views broken.

Deliberately not in this MR

  • The artifact and version connections stay @client. No assertion here claims a populated artifact or version list in a browser, because that would pin mock data through Capybara. That waits for their schema surface.
  • A Maven package renders no version count. versionsCount is npm-only in the typedefs, so the column correctly does not render for Maven. Worth confirming against the intended schema — if Maven gains one, the generator should carry it.

References

Related to #602638 (closed)

Plan: docs/plans/monolith/2026-07-28-repositories-list.md in the Artifact Registry project.

Screenshots or screen recordings

The whole surface sits behind the disabled artifact_registry_ui feature flag, so there is no user-visible change on master.

Rendered states were verified in a browser against a live local Artifact Registry (see the setup steps below), covering: the repositories list; the OCI and Maven detail pages with populated artifact tables; a populated version list (newest first, prerelease at the top, dates reading in hours through months); an image correctly rendering no versions table; a repository the service does not hold rendering Page not found; and detail → artifact → back navigation leaving the format and artifact tab unchanged. Zero console errors across every state.

Happy to attach captures if a reviewer would like them.

How to set up and validate locally

This surface talks to a real Artifact Registry, and the monolith's token exchange has not shipped yet. Two things are needed: a reachable Artifact Registry, and a temporary local token provider.

  1. Run Artifact Registry locally on http://localhost:8080, which is what Settings.artifact_registry['api_url'] defaults to in development. Note the AR_BOOTSTRAP_TOKEN it is started with and export it into your Rails environment:

    export AR_BOOTSTRAP_TOKEN='<the token your local Artifact Registry was started with>'
  2. Temporarily inject a token provider in ee/app/models/concerns/artifact_registry/caches_client.rb. This is a local-only change and must not be committed — it bypasses the real token exchange:

    # LOCAL DEV ONLY - DO NOT COMMIT
    class BootstrapTokenExchange
      def token_for(_current_user, _slug)
        ENV.fetch('AR_BOOTSTRAP_TOKEN')
      end
    end
    
    def artifact_registry_client(current_user:)
      strong_memoize_with(:artifact_registry_client, current_user) do
        ::ArtifactRegistry::Client.new(
          current_user: current_user,
          token_exchange: BootstrapTokenExchange.new # LOCAL DEV ONLY - DO NOT COMMIT
        )
      end
    end

    Read the token from the environment rather than inlining a literal, so a stray git add cannot commit a token string. Revert this file with git checkout -- before pushing.

  3. Enable the feature flag in the Rails console:

    Feature.enable(:artifact_registry_ui)
  4. Visit the repositories list at /o/<your-organization>/-/artifact_registry/<slug>/repositories and confirm it lists the repositories your local Artifact Registry serves.

  5. Open a repository, then a package, and confirm the version list renders rows with recent dates. Open an image instead and confirm no versions table renders.

  6. Visit a repository name your local Artifact Registry does not hold and confirm Page not found rather than a service-unavailable message.

If every artifact list comes back empty, the token provider above is missing or its token is wrong: a 401 from Artifact Registry maps to service-unavailable, not to not-found.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Rahul Chanila

Merge request reports

Loading
Loading