authorgravatar for 132888838+arhxam@users.noreply.github.comArham Amin <132888838+arhxam@users.noreply.github.com> 2026-08-11 21:44:02+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-11 16:14:02+00:00
log220e573b14cea84b6662a7d69047129047433b63
tree002fa0ff1879d2fa26b707fe58fc29ebcb51f8d0
parent6befe42eb09633f3adb500ae906a0e1da3f15f64
signature Signed by PGP key B5690EEEBB952194

fix(shared): detect Azure DevOps SSH remotes (ssh.dev.azure.com) (#6187)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

2 files changed, 25 insertions(+), 1 deletions(-)

packages/shared/src/sourceControl.test.ts+16
......@@ -57,6 +57,22 @@ describe("detectSourceControlProviderFromRemoteUrl", () => {
5757 ).toBe("bitbucket");
5858 });
5959
60 it("detects Azure DevOps SSH remotes", () => {
61 // The default Azure DevOps SSH clone URL uses the ssh.dev.azure.com host.
62 expect(
63 detectSourceControlProviderFromRemoteUrl("git@ssh.dev.azure.com:v3/org/project/repo")?.kind,
64 ).toBe("azure-devops");
65 expect(
66 detectSourceControlProviderFromRemoteUrl("ssh://git@ssh.dev.azure.com:22/v3/org/project/repo")
67 ?.kind,
68 ).toBe("azure-devops");
69 // Legacy visualstudio.com SSH host stays classified too.
70 expect(
71 detectSourceControlProviderFromRemoteUrl("git@vs-ssh.visualstudio.com:v3/org/project/repo")
72 ?.kind,
73 ).toBe("azure-devops");
74 });
75
6076 it("preserves ports while classifying by hostname", () => {
6177 expect(
6278 detectSourceControlProviderFromRemoteUrl("https://gitlab.com:8443/group/repo.git"),
packages/shared/src/sourceControl.ts+9-1
......@@ -176,7 +176,15 @@ function isGitLabHost(host: string): boolean {
176176}
177177
178178function isAzureDevOpsHost(host: string): boolean {
179 return host === "dev.azure.com" || host.endsWith(".visualstudio.com");
179 // `ssh.dev.azure.com` is the default Azure DevOps SSH clone host
180 // (git@ssh.dev.azure.com:v3/org/project/repo), so match any `*.dev.azure.com`
181 // subdomain, not just the bare `dev.azure.com`. Legacy hosts stay under
182 // `.visualstudio.com` (including `vs-ssh.visualstudio.com`).
183 return (
184 host === "dev.azure.com" ||
185 host.endsWith(".dev.azure.com") ||
186 host.endsWith(".visualstudio.com")
187 );
180188}
181189
182190function isBitbucketHost(host: string): boolean {