Mount the artifact registry setup page for an owner

What does this MR do and why?

The organization Artifact Registry landing route renders only a page title today. This gives it an owner-only mount point: the ability branch, the mount element, and its dataset. No form yet. The mount renders an empty shell, which is what makes it reviewable apart from the claim form.

The route already gates on the artifact_registry_ui feature flag and the read ability through ArtifactRegistryGating. This registers authorize_admin_organization! after that callback, so the flag-off and missing-read-ability refusals keep the response they already had. Every organization member holds the read ability, so the update ability is the real gate on claiming a handle, which is what authorize_admin_organization! checks despite its name.

The mount dataset carries the organization global ID and the client base URL, and no other key. The helper spec asserts the exact hash rather than a subset, so a key reaching the browser payload has to be a deliberate change.

The client base URL comes from the existing private artifact_registry_client_base_url, which merged with the repository copy-URL work. No new derivation.

The mount is named #js-artifact-registry-setup rather than -activation, because ArtifactRegistry|Activation already names the settings block on settings/artifact_registry#show, and two surfaces offering to activate a registry would be ambiguous. "Setup page" is what the route is called.

This MR also hides the "Go to Artifact Registry" link on the organization overview from a viewer without the update ability. Every member holds the read ability, so that link would otherwise offer a member a destination that now answers not-found. The empty-state description is deliberately unchanged: it points at the sidebar, which a member can still use.

Scoped ahead of its predecessors

This step is deliberately implemented before the organization-to-namespace mapping table exists. Three consequences, called out so they are not read as oversights:

  1. The mapping-row condition is not implemented. The mount renders for any update_organization holder rather than only for an organization without a registry. Once the mapping exists, an organization that has one no longer reaches this page. Until then the owner-success example passes for an already-activated organization, so it must gain a no-mapping-row context when that lands. A comment on #index records this against work item 603023.
  2. Criterion 24's byte-identical assertion is not included. Both refusal paths render errors/not_found through the same template and layout, so the assertion largely exercised framework behavior; the shared 'organization - not found response' example and the new hidden-mount example cover the member refusal. Literal response.body equality is not achievable here regardless, because errors/not_found embeds a per-response CSP nonce, so two identical requests differ. The two paths are also not identical for a .js request: render_404 has a format.js branch that access_denied! does not.
  3. The page bootstrap entry is not included. local-rules/page-entrypoint-must-execute rejects an import-only entrypoint, and there is nothing to invoke until the claim form's Vue application exists. Runtime is unaffected, because ViteHelper#vite_page_entrypoint_paths filters entrypoints missing from the manifest.

Everything here is behind artifact_registry_ui, which is default_enabled: false, so nothing is user-visible on merge. No changelog for that reason, and no documentation change for the same reason.

References

Screenshots or screen recordings

Not applicable. The mount renders an empty shell behind a disabled feature flag, so there is no visible change.

How to set up and validate locally

  1. Enable the flag in the Rails console:

    Feature.enable(:artifact_registry_ui)
  2. As an owner of an organization, visit /-/organizations/<organization-path>/artifact_registry. The page renders a #js-artifact-registry-setup element whose data-app-data carries organization_gid and client_base_url.

  3. As a member of the same organization who does not hold update_organization, visit the same path. The response is a 404 and the mount is absent.

  4. As that same member, visit the organization overview. The "Go to Artifact Registry" link is not offered.

  5. Disable the flag and repeat as an owner. The response is a 404.

Run the specs:

bundle exec rspec ee/spec/requests/organizations/artifact_registry_controller_spec.rb \
                  ee/spec/helpers/organizations/artifact_registry_helper_spec.rb
yarn jest ee/spec/frontend/organizations/show/components/app_spec.js

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