Client: remote settings and the connection test (monolith/S07 Step 1)

Part of epic &22455 (Repository CRUD, monolith/S07). Covers Step 1 of the Phase 2 (remote) plan, docs/plans/monolith/2026-08-20-repository-crud-remote.md in the artifact-registry repo.

Extend the AR Ruby client for remote repositories: a settings argument on both write methods, and a repository-scoped connection test. Dark behind artifact_registry_ui; no changelog, no i18n.

Implementation details

Step 1: Client - remote settings and the connection test (type::feature)

  • ee/lib/artifact_registry/client.rb (Modify): settings on create_repository and update_repository, passed through without interpretation. The credential three-state is the caller's to express, so create_repository's .compact must not strip a supplied settings. Adds test_upstream_connection, posting to the repository's test path with no body, since AR answers 400 to a non-empty one.
  • ee/lib/artifact_registry/connection_test_result.rb (Create): value object over passed, the nullable upstream HTTP status, the stored health status, and the stored check timestamp. Includes ArtifactRegistry::TimeCoercion for the timestamp, the way Repository does.
  • Specs: ee/spec/lib/artifact_registry/client_spec.rb (Modify), ee/spec/lib/artifact_registry/connection_test_result_spec.rb (Create).

The client validates the settings hash in neither direction. The response half is covered by monolith/S02's compatibility rule, and the request half is AR's undefined-field 400.

Acceptance

  • Both write methods send settings when supplied and omit the key when not.
  • update_repository sends an explicit JSON null for a credentials key set to nil, and omits the key when the hash carries none.
  • test_upstream_connection posts to .../repositories/:name/test with no body and returns the parsed verdict.
  • A 404 from that route raises ApiError rather than resolving nil, because a hosted or virtual repository has no such route and that is a genuine not-found. The method therefore does not wrap its request in the client's nil_on_missing helper. There is no NotFoundError class, so the caller detects the status on the raised ApiError.
  • Tests cover the three credential shapes, the omitted-versus-nil credentials distinction, the no-body POST, and the 404, 500, and unreachable-verdict outcomes.

Dependencies

  • monolith/S02 (AR Ruby client) merged. This step extends it in place.
  • The Phase 2 plan merge request must merge before this merge request opens.
  • No AR contract gate. The method and the argument land against the declared test route.
  • Blocks the GraphQL surface issue (plan Steps 3 and 4).