Skip to content

Commit b91ef48

Browse files
fix(gitlab): userless SCP remotes keep glab's remote host
The signed-in host fallback skipped remotes such as gitlab.com:team/app.git and set GITLAB_HOST over them. Share the provider's SCP-aware remote host parsing with the fallback guard. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent ca2fea1 commit b91ef48

3 files changed

Lines changed: 14 additions & 8 deletions

File tree

‎packages/source-control-gitlab/src/server/GitLabCli.test.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ layer("GitLabCli.layer", (it) => {
320320
hosts: ["gitlab.selfhosted.test"],
321321
remotes: ["[email protected]:team/app.git"],
322322
},
323+
{
324+
case: "the checkout has a userless SCP gitlab.com remote",
325+
hosts: ["gitlab.selfhosted.test"],
326+
remotes: ["gitlab.com:team/app.git"],
327+
},
323328
])("leaves the host to glab when $case", ({ hosts, remotes }) =>
324329
Effect.gen(function* () {
325330
mockGlab(hosts, remotes);

‎packages/source-control-gitlab/src/server/GitLabCli.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,12 @@ function parseRepositoryPath(repository: string): {
422422
return { namespacePath, projectPath };
423423
}
424424

425+
export function parseGitLabRemoteHost(remoteUrl: string) {
426+
// Remote host parsing does not recognize userless SCP remotes.
427+
const scpHost = /^([^@:/\\\s]{2,}):\/?[^/\s]+(?:\/[^/\s]+)+$/u.exec(remoteUrl.trim())?.[1];
428+
return parseGitRemoteHost(scpHost ? `ssh://${scpHost}` : remoteUrl);
429+
}
430+
425431
// glab prints a missing project or merge request as a bare 404.
426432
const classifyGlabFailure = (stderr: string): VcsProcessExitFailureKind | null => {
427433
const normalized = stderr.toLowerCase();
@@ -477,7 +483,7 @@ export const make = Effect.gen(function* () {
477483
Effect.orElseSucceed(() => []),
478484
);
479485
const followsRemote = remotes.some((remote) =>
480-
knownHosts.has(parseGitRemoteHost(remote.url)?.host ?? ""),
486+
knownHosts.has(parseGitLabRemoteHost(remote.url)?.host ?? ""),
481487
);
482488
return followsRemote ? undefined : { GITLAB_HOST: only.host };
483489
},

‎packages/source-control-gitlab/src/server/GitLabSourceControlProvider.ts‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ import * as Schema from "effect/Schema";
33
import * as Effect from "effect/Effect";
44
import * as Option from "effect/Option";
55
import { SourceControlProviderError, type ChangeRequest } from "@t3tools/contracts";
6-
import {
7-
parseGitRemoteHost,
8-
unknownRemoteProvider as unknownHostProvider,
9-
} from "@t3tools/source-control-core/shared/definition";
6+
import { unknownRemoteProvider as unknownHostProvider } from "@t3tools/source-control-core/shared/definition";
107

118
import * as GitLabCli from "./GitLabCli.ts";
129
import * as GitLabChangeRequestTemplate from "./gitLabChangeRequestTemplate.ts";
@@ -110,9 +107,7 @@ function refineUnknownGitLabRemote(input: SourceControlUnknownRemoteRefinementIn
110107

111108
/** The caller refines only an identity no host recognised, so its remote is on an unknown host. */
112109
function unknownRemoteProvider(remoteUrl: string) {
113-
// Remote host parsing does not recognize userless SCP remotes.
114-
const scpHost = /^([^@:/\\\s]{2,}):\/?[^/\s]+(?:\/[^/\s]+)+$/u.exec(remoteUrl.trim())?.[1];
115-
const remote = parseGitRemoteHost(scpHost ? `ssh://${scpHost}` : remoteUrl);
110+
const remote = GitLabCli.parseGitLabRemoteHost(remoteUrl);
116111
return remote === null ? null : unknownHostProvider(remote);
117112
}
118113

0 commit comments

Comments
 (0)