From 316ed8fff2a9357ef8a51eee21b22126bb45e05b Mon Sep 17 00:00:00 2001 From: Gourav Kumar Dhiman Date: Tue, 27 Oct 2026 09:12:35 +0530 Subject: [PATCH 1/3] fix(source-control): a forge's SSH-only host keys to the same repository as its web host Co-Authored-By: Claude Sonnet 5.5 --- packages/client-runtime/src/sourceControlClients.test.ts | 4 ++++ packages/source-control-bitbucket/src/shared/definition.ts | 5 +++++ .../src/server/gitHubRepositoryResolution.test.ts | 1 + .../src/server/gitHubRepositoryResolution.ts | 4 +++- packages/source-control-github/src/shared/definition.ts | 5 +++++ packages/source-control-gitlab/src/shared/definition.ts | 5 +++++ 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/client-runtime/src/sourceControlClients.test.ts b/packages/client-runtime/src/sourceControlClients.test.ts index 6954dd979cc8d..bd20c85a9ad3a 100644 --- a/packages/client-runtime/src/sourceControlClients.test.ts +++ b/packages/client-runtime/src/sourceControlClients.test.ts @@ -290,6 +290,10 @@ describe("sourceControlClients repository keys", () => { ["git@ssh.dev.azure.com:v3/o/p", "ssh.dev.azure.com/v3/o/p"], ["ssh.dev.azure.com/v3/o/p/r", "ssh.dev.azure.com/v3/o/p/r"], ["C:/repos/project", "c:/repos/project"], + ["git@ssh.bitbucket.org:Owner/Repo.git", "bitbucket.org/owner/repo"], + ["ssh://git@ssh.github.com:443/Owner/Repo.git", "github.com/owner/repo"], + ["git@altssh.gitlab.com:Group/Sub/Repo.git", "gitlab.com/group/sub/repo"], + ["git@ssh.example.com:Owner/Repo.git", "ssh.example.com/owner/repo"], ])("keys %s as %s", (remote, key) => { expect(sourceControlClients.repositoryKeyFromRemote(remote)).toBe(key); }); diff --git a/packages/source-control-bitbucket/src/shared/definition.ts b/packages/source-control-bitbucket/src/shared/definition.ts index 946098b166d34..00123e4faedcf 100644 --- a/packages/source-control-bitbucket/src/shared/definition.ts +++ b/packages/source-control-bitbucket/src/shared/definition.ts @@ -111,6 +111,11 @@ export const definition = defineSourceControl({ baseUrl: `https://${host}`, } : null, + // `ssh.bitbucket.org` is the SSH-only host for networks that block port 22; it serves the web host's repositories. + repositoryKeyFromRemote: (key) => { + const match = /^ssh\.bitbucket\.org\/(.+)$/u.exec(key); + return match === null ? null : `bitbucket.org/${match[1]}`; + }, isChangeRequestInRepository: (identity, link) => isChangeRequestInProjectRepository(projectChangeRequestHost(identity, KIND), identity, link), canReadChangeRequestOnHost: (identity, link) => diff --git a/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts b/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts index c78c1fd7612f8..c1952d8b258b4 100644 --- a/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts +++ b/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts @@ -82,6 +82,7 @@ describe("selectGitHubBaseRepository", () => { describe("gitHubApiHostForRemote", () => { it("reads an SSH alias through github.com and a real host as itself", () => { assert.strictEqual(gitHubApiHostForRemote("git@github:acme/web.git"), "github.com"); + assert.strictEqual(gitHubApiHostForRemote("git@ssh.github.com:acme/web.git"), "github.com"); assert.strictEqual( gitHubApiHostForRemote("git@github.example.com:a/b.git"), "github.example.com", diff --git a/packages/source-control-github/src/server/gitHubRepositoryResolution.ts b/packages/source-control-github/src/server/gitHubRepositoryResolution.ts index da97bd96b0a61..80610efc590d7 100644 --- a/packages/source-control-github/src/server/gitHubRepositoryResolution.ts +++ b/packages/source-control-github/src/server/gitHubRepositoryResolution.ts @@ -152,7 +152,9 @@ export function gitHubApiHostForRemote(remoteUrl: string): string | null { if (isSshRemoteUrl(remoteUrl) && !host.includes(".")) { return host.includes("github") ? "github.com" : null; } - return definition.recognizeRemote(remote) === null ? null : host; + if (definition.recognizeRemote(remote) === null) return null; + // GitHub's SSH-over-443 host has no API; gh reads that remote through github.com. + return host === "ssh.github.com" ? "github.com" : host; } function apiHostForHint(host: string): string { diff --git a/packages/source-control-github/src/shared/definition.ts b/packages/source-control-github/src/shared/definition.ts index 170395bb7eef5..282dc6221d139 100644 --- a/packages/source-control-github/src/shared/definition.ts +++ b/packages/source-control-github/src/shared/definition.ts @@ -132,6 +132,11 @@ export const definition = defineSourceControl({ baseUrl: `https://${host}`, } : null, + // `ssh.github.com` is the SSH-only host for networks that block port 22; it serves the web host's repositories. + repositoryKeyFromRemote: (key) => { + const match = /^ssh\.github\.com\/(.+)$/u.exec(key); + return match === null ? null : `github.com/${match[1]}`; + }, isChangeRequestInRepository: (identity, link) => isChangeRequestInProjectRepository(projectChangeRequestHost(identity, KIND), identity, link), canReadChangeRequestOnHost: (identity, link) => diff --git a/packages/source-control-gitlab/src/shared/definition.ts b/packages/source-control-gitlab/src/shared/definition.ts index 1a3c417641ce4..e51c9e1724982 100644 --- a/packages/source-control-gitlab/src/shared/definition.ts +++ b/packages/source-control-gitlab/src/shared/definition.ts @@ -68,6 +68,11 @@ export const definition = defineSourceControl({ baseUrl: `https://${host}`, } : null, + // `altssh.gitlab.com` is the SSH-only host for networks that block port 22; it serves the web host's repositories. + repositoryKeyFromRemote: (key) => { + const match = /^altssh\.gitlab\.com\/(.+)$/u.exec(key); + return match === null ? null : `gitlab.com/${match[1]}`; + }, isChangeRequestInRepository: (identity, link) => isChangeRequestInProjectRepository(projectChangeRequestHost(identity, KIND), identity, link), canReadChangeRequestOnHost: (identity, link) => From d058e7a3f91e011f389e1bfdd6684b63ee07ec06 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Fri, 30 Oct 2026 15:20:45 +0000 Subject: [PATCH 2/3] fix(github): normalize SSH hosts in repository resolution --- .../server/gitHubRepositoryResolution.test.ts | 21 +++++++++++++++++++ .../src/server/gitHubRepositoryResolution.ts | 8 +++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts b/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts index c1952d8b258b4..d57f479c94da1 100644 --- a/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts +++ b/packages/source-control-github/src/server/gitHubRepositoryResolution.test.ts @@ -2,6 +2,7 @@ import { assert, describe, it } from "@effect/vitest"; import { gitHubApiHostForRemote, + resolveGitHubRepository, selectGitHubBaseRepository, } from "./gitHubRepositoryResolution.ts"; @@ -27,6 +28,26 @@ describe("selectGitHubBaseRepository", () => { owner: "me", name: "web", }); + const sshFork = fork.replace( + "git@github.com:me/web.git", + "ssh://git@ssh.github.com:443/me/web.git", + ); + assert.deepStrictEqual( + select({ remotes: sshFork, resolved: "remote.origin.gh-resolved base" }), + { + owner: "me", + name: "web", + }, + ); + assert.deepStrictEqual( + resolveGitHubRepository({ + remotes: sshFork, + resolved: "remote.origin.gh-resolved base", + hostHint: "ssh.github.com", + defaultHost: "github.com", + }), + { host: "github.com", locator: { host: "github.com", owner: "me", name: "web" } }, + ); assert.deepStrictEqual( select({ remotes: fork, resolved: "remote.origin.gh-resolved acme/other" }), { owner: "acme", name: "other" }, diff --git a/packages/source-control-github/src/server/gitHubRepositoryResolution.ts b/packages/source-control-github/src/server/gitHubRepositoryResolution.ts index 80610efc590d7..c1c28041e0144 100644 --- a/packages/source-control-github/src/server/gitHubRepositoryResolution.ts +++ b/packages/source-control-github/src/server/gitHubRepositoryResolution.ts @@ -30,7 +30,8 @@ export function selectGitHubBaseRepository(input: { const repositories = new Map(); for (const remote of parseFetchRemotes(input.remotes)) { const [remoteHost, owner, name, ...rest] = normalizeGitRemoteUrl(remote.url).split("/"); - if (remoteHost !== host || !owner || !name || rest.length > 0) return null; + const apiHost = remoteHost === "ssh.github.com" ? "github.com" : remoteHost; + if (apiHost !== host || !owner || !name || rest.length > 0) return null; repositories.set(remote.name, { owner, name }); } const marks = input.resolved @@ -159,5 +160,8 @@ export function gitHubApiHostForRemote(remoteUrl: string): string | null { function apiHostForHint(host: string): string { const normalized = host.toLowerCase(); - return !normalized.includes(".") && normalized.includes("github") ? "github.com" : normalized; + return normalized === "ssh.github.com" || + (!normalized.includes(".") && normalized.includes("github")) + ? "github.com" + : normalized; } From 767b7f0a6f2e1aeff1144f781fead17ccaa7a83a Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Sun, 1 Nov 2026 01:29:26 +0000 Subject: [PATCH 3/3] fix(bitbucket): normalize alternate SSH host repository keys --- packages/client-runtime/src/sourceControlClients.test.ts | 2 +- packages/source-control-bitbucket/src/shared/definition.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client-runtime/src/sourceControlClients.test.ts b/packages/client-runtime/src/sourceControlClients.test.ts index fcc27527f41bf..abb633a7563b3 100644 --- a/packages/client-runtime/src/sourceControlClients.test.ts +++ b/packages/client-runtime/src/sourceControlClients.test.ts @@ -290,7 +290,7 @@ describe("sourceControlClients repository keys", () => { ["git@ssh.dev.azure.com:v3/o/p", "ssh.dev.azure.com/v3/o/p"], ["ssh.dev.azure.com/v3/o/p/r", "ssh.dev.azure.com/v3/o/p/r"], ["C:/repos/project", "c:/repos/project"], - ["git@ssh.bitbucket.org:Owner/Repo.git", "bitbucket.org/owner/repo"], + ["git@altssh.bitbucket.org:Owner/Repo.git", "bitbucket.org/owner/repo"], ["ssh://git@ssh.github.com:443/Owner/Repo.git", "github.com/owner/repo"], ["git@altssh.gitlab.com:Group/Sub/Repo.git", "gitlab.com/group/sub/repo"], ["git@ssh.example.com:Owner/Repo.git", "ssh.example.com/owner/repo"], diff --git a/packages/source-control-bitbucket/src/shared/definition.ts b/packages/source-control-bitbucket/src/shared/definition.ts index 6a44fc053e72c..5b55c3f8d8751 100644 --- a/packages/source-control-bitbucket/src/shared/definition.ts +++ b/packages/source-control-bitbucket/src/shared/definition.ts @@ -127,9 +127,9 @@ export const definition = defineSourceControl({ baseUrl: `https://${host}`, } : null, - // `ssh.bitbucket.org` is the SSH-only host for networks that block port 22; it serves the web host's repositories. + // `altssh.bitbucket.org` is the SSH-only host for networks that block port 22; it serves the web host's repositories. repositoryKeyFromRemote: (key) => { - const match = /^ssh\.bitbucket\.org\/(.+)$/u.exec(key); + const match = /^altssh\.bitbucket\.org\/(.+)$/u.exec(key); return match === null ? null : `bitbucket.org/${match[1]}`; }, isChangeRequestInRepository: (identity, link) =>