Git Repo URL telemetry link fix: only Https (#5202)

* https parsing in URL sanatizing for git repo

* fix: remove duplicate JSDoc and add SSH to HTTPS conversion test

- Remove duplicate JSDoc comment from convertGitUrlToHttps function
- Add test case to verify getGitRepositoryInfo converts SSH URLs to HTTPS format

---------

Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
This commit is contained in:
Will Li 2025-06-28 06:32:27 -07:00 • committed by GitHub
parent 8bb7ef083f
commit dc44e7a40b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 124 additions and 1 deletions

View file

@ -12,6 +12,7 @@ import {
extractRepositoryName,
getWorkspaceGitInfo,
GitRepositoryInfo,
convertGitUrlToHttps,
} from "../git"
import { truncateOutput } from "../../integrations/misc/extract-text"
@ -560,6 +561,89 @@ describe("getGitRepositoryInfo", () => {
repositoryName: "RooCodeInc/Roo-Code",
})
})
it("should convert SSH URLs to HTTPS format", async () => {
// Clear previous mocks
vitest.clearAllMocks()
// Create a spy to track the implementation
const gitSpy = vitest.spyOn(fs.promises, "readFile")
// Mock successful access to .git directory
vitest.mocked(fs.promises.access).mockResolvedValue(undefined)
// Mock git config file with SSH URL
const mockConfig = `
[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = git@github.com:RooCodeInc/Roo-Code.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
`
// Mock HEAD file content
const mockHead = "ref: refs/heads/main"
// Setup the readFile mock to return different values based on the path
gitSpy.mockImplementation((path: any, encoding: any) => {
if (path === configPath) {
return Promise.resolve(mockConfig)
} else if (path === headPath) {
return Promise.resolve(mockHead)
}
return Promise.reject(new Error(`Unexpected path: ${path}`))
})
const result = await getGitRepositoryInfo(workspaceRoot)
// Verify that the SSH URL was converted to HTTPS
expect(result).toEqual({
repositoryUrl: "https://github.com/RooCodeInc/Roo-Code.git",
repositoryName: "RooCodeInc/Roo-Code",
defaultBranch: "main",
})
})
})
describe("convertGitUrlToHttps", () => {
it("should leave HTTPS URLs unchanged", () => {
const url = "https://github.com/RooCodeInc/Roo-Code.git"
const converted = convertGitUrlToHttps(url)
expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git")
})
it("should convert SSH URLs to HTTPS format", () => {
const url = "git@github.com:RooCodeInc/Roo-Code.git"
const converted = convertGitUrlToHttps(url)
expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git")
})
it("should convert SSH URLs with ssh:// prefix to HTTPS format", () => {
const url = "ssh://git@github.com/RooCodeInc/Roo-Code.git"
const converted = convertGitUrlToHttps(url)
expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git")
})
it("should handle URLs without git@ prefix", () => {
const url = "ssh://github.com/RooCodeInc/Roo-Code.git"
const converted = convertGitUrlToHttps(url)
expect(converted).toBe("https://github.com/RooCodeInc/Roo-Code.git")
})
it("should handle invalid URLs gracefully", () => {
const url = "not-a-valid-url"
const converted = convertGitUrlToHttps(url)
expect(converted).toBe("not-a-valid-url")
})
})
describe("sanitizeGitUrl", () => {

View file

@ -51,7 +51,8 @@ export async function getGitRepositoryInfo(workspaceRoot: string): Promise<GitRe
if (urlMatch && urlMatch[1]) {
const url = urlMatch[1].trim()
gitInfo.repositoryUrl = sanitizeGitUrl(url)
// Sanitize the URL and convert to HTTPS format for telemetry
gitInfo.repositoryUrl = convertGitUrlToHttps(sanitizeGitUrl(url))
const repositoryName = extractRepositoryName(url)
if (repositoryName) {
gitInfo.repositoryName = repositoryName
@ -88,6 +89,44 @@ export async function getGitRepositoryInfo(workspaceRoot: string): Promise<GitRe
}
}
/**
* Converts a git URL to HTTPS format
* @param url The git URL to convert
* @returns The URL in HTTPS format, or the original URL if conversion is not possible
*/
export function convertGitUrlToHttps(url: string): string {
try {
// Already HTTPS, just return it
if (url.startsWith("https://")) {
return url
}
// Handle SSH format: git@github.com:user/repo.git -> https://github.com/user/repo.git
if (url.startsWith("git@")) {
const match = url.match(/git@([^:]+):(.+)/)
if (match && match.length === 3) {
const [, host, path] = match
return `https://${host}/${path}`
}
}
// Handle SSH with protocol: ssh://git@github.com/user/repo.git -> https://github.com/user/repo.git
if (url.startsWith("ssh://")) {
const match = url.match(/ssh:\/\/(?:git@)?([^\/]+)\/(.+)/)
if (match && match.length === 3) {
const [, host, path] = match
return `https://${host}/${path}`
}
}
// Return original URL if we can't convert it
return url
} catch {
// If parsing fails, return original
return url
}
}
/**
* Sanitizes a git URL to remove sensitive information like tokens
* @param url The original git URL