glab --repo ignores an authenticated host with a port and no dot, such as localhost:3000
Checklist
- I'm using the latest version of the extension (Run
glab --version)- Extension version:
glab 1.124.0 (a6fd50cec), built frommainat a6fd50ce.internal/glrepo/repo.go, where the cause is, is the same in the v1.124.0 release.
- Extension version:
- Operating system and version: Linux 6.1.0 x86_64
- Gitlab.com or self-managed instance? Self-managed: any instance whose host has a port and no dot, such as a local development instance on
localhost:3000 - GitLab version (if self-managed): not applicable. glab picks the wrong host before it sends any request, so I reproduced it against a local stub rather than an instance.
- I have performed
glab auth statusto check for authentication issues: not applicable, the host is authenticated in the configuration and glab never asks it. - Run the command in debug mode (like
GLAB_DEBUG=true glab mr list) and attach any useful output:GLAB_DEBUG=trueadds nothing to the output below.
Summary
When the --repo (-R) flag or GITLAB_REPO names an authenticated host that has a port but no dot, such as localhost:3000, glab does not recognize the host. It reads the whole value as a project path on the default host, so after glab auth login --hostname localhost:3000, glab issue list -R localhost:3000/OWNER/REPO asks gitlab.com for a project named localhost:3000/OWNER/REPO instead of asking localhost:3000 for OWNER/REPO. A host with a dot, such as example.org, works.
Environment
- OS: Linux 6.1.0-53-amd64 x86_64
- SHELL: /bin/bash (GNU bash 5.2.15)
- TERM: xterm
- GLAB: glab 1.124.0 (a6fd50ce)
Other: glab ran in an empty directory with a cleared environment (PATH, HOME, GLAB_CONFIG_DIR, GLAB_SEND_TELEMETRY=false, GLAB_CHECK_UPDATE=false, NO_COLOR=1 and the proxy variables below), so no GITLAB_* variable was set. Its configuration held one host, localhost:3123, with a token, api_protocol: http and api_host: localhost:3123. A small stub on localhost:3123 stood in for the instance, and HTTPS_PROXY pointed at a second stub that logs every CONNECT and refuses it, so no request left the machine.
Steps to reproduce
- Authenticate glab to an instance whose host has a port and no dot, for example
glab auth login --hostname localhost:3000, so the configuration has alocalhost:3000entry underhosts. - Outside any Git repository, run
glab issue list -R localhost:3000/OWNER/REPO, or setGITLAB_REPO=localhost:3000/OWNER/REPOand runglab issue list.
What is the current bug behavior?
glab sends the request to gitlab.com, for the project localhost:3000/OWNER/REPO. With the host localhost:3123 of my reproduction, glab prints (its line wrapping removed):
ERROR
Get "https://gitlab.com/api/v4/projects/localhost:3123%2FOWNER%2FREPO/issues?in=title%2Cdescription&order_by=created_at&page=1&per_page=30&sort=desc&state=opened": Forbidden.Forbidden is the proxy stub's answer. Its log has one line, CONNECT gitlab.com:443, and the stub on localhost:3123 saw no request. GITLAB_REPO=localhost:3123/OWNER/REPO glab issue list does the same.
What is the expected correct behavior?
glab asks localhost:3123 for the project OWNER/REPO, the same way example.org/OWNER/REPO goes to example.org when example.org is authenticated.
Relevant logs and/or screenshots
glrepo.FromFullName("localhost:3000/OWNER/REPO", "gitlab.com", cfg), with localhost:3000 in the configured hosts, returns host gitlab.com, group localhost:3000 and project localhost:3000/OWNER/REPO. A case added to TestFromFullName for it fails on main with:
expected host "localhost:3000", got "gitlab.com"Setting GITLAB_HOST=localhost:3123 works around it: the first segment then matches the default host, which FromFullName checks first, and the request reaches the stub on localhost:3123.
Possible fixes
FromFullName compares the first segment with the authenticated hosts only when it contains a dot, because dots are also allowed in group paths: https://gitlab.com/gitlab-org/cli/-/blob/a6fd50cecb4bbe630dfb03a621cbe2cedfef4aef/internal/glrepo/repo.go#L148-166
Running the same check when the segment contains a colon would fix it without changing how any group name is read, since a colon cannot appear in a GitLab group or project path (PATH_REGEX_STR in https://gitlab.com/gitlab-org/gitlab/-/blob/c421511b7a8c7df247695fc1e79c01e82033524c/lib/gitlab/path_regex.rb#L133-134). A segment with a colon that is not an authenticated host would keep its current meaning. I have a merge request ready for it.