fix(gitlab): drive self-hosted GitLab out-of-the-box with glab v1.5x#326
fix(gitlab): drive self-hosted GitLab out-of-the-box with glab v1.5x#326karotkriss wants to merge 2 commits into
Conversation
Make the GitLab backend work against self-hosted instances and the current glab CLI without manual configuration, for the direct branch -> MR flow. Self-hosted detection: - DetectProvider falls back to glab's configured hosts (config.yml, honoring GLAB_CONFIG_DIR / XDG_CONFIG_HOME) when a remote's hostname carries no "gitlab" marker, matching on the host key or its api_host. It reads only what the user configured, hardcodes no host, and fails closed to ProviderUnknown on any read/parse error. - Add scm.ExtractHost to recover the host (sans port, lowercased) from scp-style, URL, and ssh:// remotes, including IPv6 literals and '@'-in-path. glab v1.5x backend fixes: - Scope `glab auth status` with --hostname <host>. Unscoped, it checks every configured instance and exits non-zero if any has a stale token, falsely reporting an authenticated repo as unauthenticated. Falls back to the unscoped check when the host is unknown (fail-safe). - Drop the removed `--state opened` flag from `glab mr list`; open is the default in v1.5x and passing the unknown flag fails the whole command. - Read pipeline jobs via the branch-independent REST endpoint (`glab api projects/<group%2Fproject>/pipelines/<id>/jobs`) so they work in the daemon's detached-HEAD worktree, where `glab ci get` refuses to run. --paginate walks every page; the decoder handles the resulting concatenated JSON documents and a corrupt later page surfaces as an error rather than a silent partial that could hide a failed job. Maps finished_at into Check.CompletedAt for CI re-run detection. The legacy `glab ci get` path remains as the fallback when no project path is known. Structure, mirroring the GitHub backend: - The GitLab project-path parser lives in the gitlab package as exported gitlab.ProjectPath, next to the Host that consumes it, mirroring github.RepoSlug. - The Host is scoped via positional constructor params New(cmd, cliAvailable, host, projectPath); passing "", "" reproduces the legacy unscoped behavior. Escapes each project-path segment with url.PathEscape (rejoined with %2F).
… glab v1.5x Document that self-hosted GitLab is detected out of the box even when the hostname carries no "gitlab" marker, by consulting glab's configured hosts (with the GLAB_CONFIG_DIR / XDG_CONFIG_HOME precedence and fail-closed behavior), and note that the backend is pinned against glab v1.5x.
|
@kunchenguid I had some problem using This is one of the best tools I've ever integrated into my SDLC at work, I thank you for open sourcing this. |
|
Thanks for the contribution, @karotkriss! One process note on this repo: PRs need to be raised through no-mistakes ( If working from a fork was the blocker, that's fixed as of v1.30.0 (#306). Per CONTRIBUTING.md: point I won't be merging PRs that bypass the gate going forward, but I'd genuinely love to land your work once it's re-raised. Thanks for understanding! 🙏 |
Thank you for responding to my PR so quick, I will close this and reraise the pr to comply with the contribution guideline. |
Summary
Makes
no-mistakesdrive a self-hosted GitLab instance out of the box for the directbranch -> MRflow, working with the currentglab v1.5xCLI. No manual configuration beyond a normalglab auth login.Problem
On a machine with
glab v1.5xand more than one configured glab host, the pipeline pushed the branch but then silently skipped MR creation and never read CI - the run still reported success, so it looked like it shipped. Three version-driven incompatibilities caused it:glab auth status(no host) checks every configured instance and exits non-zero if any has a stale token, so a healthy repo is judged unauthenticated and the MR step skips.glab mr listno longer accepts--state opened(open is the default in v1.5x); the unknown flag fails the whole command.glab ci getrefuses to run there, so CI checks can never be read.What this changes
--hostname <host>toglab auth statusso an unrelated instance's stale token can't poison this repo's check. Unknown host falls back to the unscoped check (fail-safe).--state- rely onglab mr list's open-by-default behavior instead of the flag that v1.5x removed.glab api(REST) - when the project path is known, list jobs throughglab api projects/<group%2Fproject>/pipelines/<id>/jobs. This is branch-independent (works in the detached-HEAD worktree), paginated, and mapsfinished_atintoCheck.CompletedAtfor CI re-run detection. The legacyglab ci getpath stays as a fallback when no project path is known.Plus:
gitlabmarker (e.g.git.example.com), consult glab's configured hosts (config.yml, honoringGLAB_CONFIG_DIR/XDG_CONFIG_HOME) and treat it as GitLab if the host matches a configured host or itsapi_host. Reads only user config, hardcodes nothing, and fails closed to unsupported.gitlab.ProjectPathlives in the gitlab backend package, mirroringgithub.RepoSlug.gitlab.New(cmd, cliAvailable, host, projectPath), matching the GitHub backend's shape.Compatibility
New(cmd, cliAvailable, host, projectPath). Passing"", ""reproduces the legacy unscoped behavior.glab apioutput surfaces as an error rather than a silent partial that could hide a failed job.Testing
go test ./...,go vet ./..., andgofmtare clean.glab v1.53.0and a multi-host glab config (one host carrying an unrelated stale token): the fullpush -> MR -> CIflow works end to end - host-scoped auth survives the stale token, the MR is created, and CI jobs are read via the paginatedglab apipath in the detached-HEAD worktree (MR mergeable, pipeline green).