Add the artifact registry setup page claim form
What does this MR do and why?
The organization Artifact Registry landing route renders an owner-only mount point that stays empty. This fills it with the claim form.
- The handle field is framed by the registry origin it completes, so what is being claimed reads as an address rather than a bare word.
- Inline validation names one rule per refusal, transcribed from the Artifact Registry slug contract (
api/openapi/gitlab-v1.yaml, which states the rules in prose and carries no pattern to generate from). Artifact Registry stays the authority; refusing here only spares a round trip. - A disclosure shows where the handle will appear, with
.npmrc,settings.xml,.gitlab-ci.yml, Dockerfile and README examples that interpolate live as the field is edited. Before a character is typed they stand the field's placeholder in, so the panel is never a set of bare labels over empty space. - A permanence callout, an inert submitting state, and on success a redirect to the new registry's repositories route carrying a confirmation.
The registry URL is composed in one place. buildRegistryClientUrl is the origin plus the handle, and buildRepositoryClientUrl now delegates to it rather than joining paths in parallel, so the unsettled client path shape is one function to change instead of two that have to agree.
Scoped ahead of its backend
The claim submits against a local Apollo resolver. The activate mutation does not exist in the schema yet, so the document is entirely @client and graphql-verify skips it. The resolver, the typedefs and the bootstrap arguments come out together when the mutation lands; the recipe is in mock_resolvers.js.
The mock resolves every claim to the slug the repositories route currently serves, whatever was typed. Without that the redirect lands on a 404, because the route still validates against the stub slug rather than a resolved handle.
Design
Built against the onboarding prototype and the Figma frame. Four deliberate divergences:
- No billing or pricing copy. The usage-and-billing link is Phase 2, behind a dependency this slice does not have.
- Consecutive hyphens are refused. The prototype's validator accepts
org--inc; Artifact Registry does not, so matching it would ship a form that accepts handles the API rejects. - No Cancel control. The design shows one; it has no defined destination and the spec does not name it.
- The container path segment is
container, notdocker. One set of OCI Distribution Spec endpoints serves both formats, so a copy-pasteabledockerexample would not resolve.
How to set up and validate locally
The route answers not found with the flag off, so enable it first:
Feature.enable(:artifact_registry_ui)- As an organization owner, visit
/o/<organization>/-/artifact_registry. The claim form renders. - Type an invalid handle (
My-Registry,-acme,a--b,ab). Each is refused inline against the field, and no request is issued. - Expand Where the registry handle appears. The examples carry the handle as it is typed, and the field's placeholder before anything is.
- Claim a valid handle. The form goes inert while submitting, then the browser lands on the repositories route with a confirmation.
- Claim
taken-handleto see the refusal Artifact Registry would make, rendered against the field with the form still editable. - As a member without
update_organization, visit the same path. The response is a 404.
yarn jest ee/spec/frontend/packages_and_registries/artifact_registry
bundle exec rspec ee/spec/features/artifact_registry/setup_spec.rb \
ee/spec/helpers/organizations/artifact_registry_helper_spec.rb \
ee/spec/requests/organizations/artifact_registry_controller_spec.rbMR 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.
Related to #608395 (closed)