Show Maven local upstreams in the registry upstream list
What does this MR do and why?
Related to #611501. The frontend is in !261005, stacked on this MR, for 19.6.
A Maven virtual registry upstream row points at either a remote or a local upstream, but GraphQL only exposes the remote one, through the non-null upstream field. When a registry has a local upstream, upstream is null on that row, the whole registry resolves to null, and the UI shows "No upstreams yet".
This MR adds:
targetUpstreamonMavenRegistryUpstreamWithUpstream. It returns theMavenTargetUpstreamunion (MavenUpstreamorMavenLocalUpstream): the remote upstream if set, otherwise the local one, likeresolved_upstreamand the REST API.MavenLocalUpstream. ItslocalGroupandlocalProjectfields expose onlyid,fullPathandwebUrl, and are null when the viewer can't read the target.
upstream is unchanged: non-null, remote only.
Why the frontend is separate:
@gl_introduced handles the missing targetUpstream field, but the old backend also lacks MavenLocalUpstream, so the inline fragment crashes query analysis instead of falling back to null.
Executing a tagged missing field containing ... on NoSuchType { id } raises:
NoMethodError: undefined method graphql_name' for nil graphql/analysis/field_usage.rb:15:in on_leave_field'
Follow-up: remove upstream once the frontend reads targetUpstream, as agreed in !253638 (comment 3975662077).
Performance
targetUpstream and the local target fields are batch loaded. The N+1 spec allows one extra query per added local row, for the read_group/read_project check. A registry has at most 20 upstreams.
How to set up and validate locally
-
In a top-level group, create a Maven virtual registry with a remote upstream, then attach a local upstream that targets a group or project.
-
In GraphiQL (
/-/graphql-explorer), run (replace<id>):{ virtualRegistriesPackagesMavenRegistry(id: "gid://gitlab/VirtualRegistries::Packages::Maven::Registry/<id>") { registryUpstreams { position targetUpstream { __typename ... on MavenUpstream { name url } ... on MavenLocalUpstream { name localGroup { fullPath } localProject { fullPath } } } } } } -
All rows return in position order: remote rows as
MavenUpstream, local rows asMavenLocalUpstreamwith their target path. -
On master,
targetUpstreamdoesn't exist. Queryingupstreaminstead returnsregistry: nullwith "Cannot return null for non-nullable field MavenRegistryUpstreamWithUpstream.upstream".upstreambehaves the same on this branch.
Recordings
Before: on master, the registry query returns registry: null with the non-null error
After: targetUpstream returns remote and local upstreams in position order
G1_RECORDING_PLACEHOLDER
Viewer who can't read the local targets: local upstreams return with their targets null and no errors