feat(artifact-registry): resolve artifact registries in the Docker credential helper

Step 3 of artifact-registry#222. Depends on step 1 and step 2 (both merged into main), so this MR targets sshen/ar-get-token and stacks on top of it.

glab auth docker-helper get now tries an Artifact Registry token exchange before falling back to the existing container-registry credentials, so docker pull/push against an artifact-registry-backed domain authenticates without a new command. Precedence: artifact registry first; container registry only as a fallback; a domain configured only for artifact registry gets its real exchange error rather than "unknown domain".

Adds artifact_registry_domains, a per-host config key mirroring container_registry_domains but with no shipped default: glab config set artifact_registry_domains <domain> --host <host> is how a domain gets associated with a GitLab instance for this path.

A few things worth calling out up front:

  • The API client must not resolve the token from the environment. Docker runs this helper as a subprocess that inherits the user's shell environment, so a stray GITLAB_TOKEN/GITLAB_ACCESS_TOKEN must not decide which identity mints the artifact-registry token. api.WithoutTokenFromEnvironment() is a new option on NewClientFromConfig for this. job_token/CI_JOB_TOKEN is untouched.
  • readDomains/findAssociatedHostname are now generalized into findHostnameByDomain, parameterized by config key, so the container-registry and artifact-registry lookups share one host-iteration/error-collection loop instead of a third near-copy of it.
  • Read errors are reported as themselves, not as "unknown domain". A key that is simply unset reads back as "" with no error; an error from GetWithSource is a real read failure (broken YAML, a locked keyring), and one broken host's entry doesn't hide a match on a different host.
  • artifactregistry.DefaultGetTokenDuration is used only by this credential helper, not get-token (which validates and uses its own --duration flag defaulting to MinDuration). Docker gives the helper no way to pass a duration, and a token expiring mid-pull would hard-fail it, hence a longer default than MinDuration.
Edited by Sylvia Shen

Merge request reports

Loading
Loading