refactor(providers): an ssh: route carries no provider and throws one typed error (#27477)

Co-authored-by: m4air <m4air@Mac.localdomain>
This commit is contained in:
OrcaWin
2026-10-11 06:25:41 -07:00
committed by GitHub
co-authored by m4air
parent e9279b613e
commit ec14775f93
50 changed files with 285 additions and 1633 deletions
@@ -155,24 +155,6 @@ describe('getPRForBranch SSH execution boundary', () => {
expect(outcome).toMatchObject({ kind: 'no-pr' })
})
it('rev-parses HEAD through the SSH provider when it is registered', async () => {
const sshGitProvider = {
exec: vi.fn(async (args: string[]) =>
args[0] === 'rev-parse' && args[1] === 'HEAD'
? { stdout: `${MERGED_HEAD_OID}\n`, stderr: '' }
: { stdout: '', stderr: '' }
)
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
mockMergedBranchPRLookup()
const pr = await getPRForBranch('/remote/repo', MERGED_BRANCH, null, 'ssh-1')
expect(sshGitProvider.exec).toHaveBeenCalledWith(['rev-parse', 'HEAD'], '/remote/repo')
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
expect(pr).toMatchObject({ number: 5875, state: 'merged', headSha: MERGED_HEAD_OID })
})
it('rev-parses HEAD through the local runtime for a WSL repository', async () => {
mockMergedBranchPRLookup()
gitExecFileAsyncMock.mockResolvedValue({ stdout: `${MERGED_HEAD_OID}\n`, stderr: '' })
@@ -227,25 +209,6 @@ describe('getPRForBranch SSH execution boundary', () => {
expect(outcome).toMatchObject({ kind: 'upstream-error', errorType: 'unknown' })
})
it('reads tracked upstreams through the SSH provider when it is registered', async () => {
const forEachRefArgs = ['for-each-ref', '--format=%(refname)%00%(upstream)', 'refs/heads']
const sshGitProvider = {
exec: vi.fn(async (args: string[]) =>
args[0] === 'for-each-ref'
? { stdout: `${MERGED_BRANCH}\0origin/contributor/original\n`, stderr: '' }
: { stdout: '', stderr: '' }
)
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
mockUpstreamOnlyPRLookup()
const pr = await getPRForBranch('/remote/repo', MERGED_BRANCH, null, 'ssh-1')
expect(sshGitProvider.exec).toHaveBeenCalledWith(forEachRefArgs, '/remote/repo')
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
expect(pr).toMatchObject({ number: 78, title: 'Hydrated upstream branch PR' })
})
it('reads tracked upstreams through the local runtime for a WSL repository', async () => {
const forEachRefArgs = ['for-each-ref', '--format=%(refname)%00%(upstream)', 'refs/heads']
mockUpstreamOnlyPRLookup()
@@ -31,11 +31,9 @@ import { resetPRForBranchMocks } from './client-test-harness'
const {
ghExecFileAsyncMock,
getOwnerRepoMock,
getOwnerRepoForRemoteMock,
resolvePRRepositoryCandidatesMock,
gitExecFileAsyncMock,
getSshGitProviderMock
gitExecFileAsyncMock
} = clientMocks
describe('getPRForBranch', () => {
@@ -200,178 +198,4 @@ describe('getPRForBranch', () => {
{ cwd: '/repo-root' }
)
})
it('checks the tracked upstream branch through the SSH git provider', async () => {
const sshGitProvider = {
exec: vi.fn().mockResolvedValue({
stdout: 'local-created-from-pr\0origin/contributor/original\n',
stderr: ''
})
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' })
getOwnerRepoForRemoteMock.mockResolvedValueOnce({ owner: 'acme', repo: 'widgets' })
ghExecFileAsyncMock
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({
stdout: JSON.stringify([
{
number: 78,
title: 'SSH upstream branch PR',
state: 'open',
html_url: 'https://github.com/acme/widgets/pull/78',
updated_at: '2026-03-28T00:00:00Z',
draft: false,
mergeable: true,
base: { ref: 'main', sha: 'base-oid' },
head: { ref: 'contributor/original', sha: 'upstream-head-oid' }
}
])
})
const pr = await getPRForBranch(
'/remote/repo-root',
'local-created-from-pr',
undefined,
'ssh-1'
)
expect(sshGitProvider.exec).toHaveBeenCalledWith(
['for-each-ref', '--format=%(refname)%00%(upstream)', 'refs/heads'],
'/remote/repo-root'
)
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
expect(ghExecFileAsyncMock).toHaveBeenNthCalledWith(
2,
['api', 'repos/acme/widgets/pulls?head=acme%3Acontributor%2Foriginal&state=all&per_page=1'],
{}
)
expect(pr).toMatchObject({ number: 78, title: 'SSH upstream branch PR' })
})
it('uses the same-name tracked upstream fork owner through the SSH git provider', async () => {
const sshGitProvider = {
exec: vi.fn().mockResolvedValue({
stdout: 'contributor/fix\0fork/contributor/fix\n',
stderr: ''
})
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
resolvePRRepositoryCandidatesMock.mockResolvedValueOnce({
candidates: [
{ owner: 'stablyai', repo: 'orca' },
{ owner: 'origin-owner', repo: 'orca' }
],
headRepo: { owner: 'origin-owner', repo: 'orca' }
})
getOwnerRepoForRemoteMock.mockResolvedValueOnce({ owner: 'fork-owner', repo: 'orca' })
ghExecFileAsyncMock
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({
stdout: JSON.stringify([
{
number: 79,
title: 'SSH same-name fork PR',
state: 'open',
html_url: 'https://github.com/stablyai/orca/pull/79',
updated_at: '2026-03-28T00:00:00Z',
draft: false,
mergeable: true,
base: { ref: 'main', sha: 'base-oid' },
head: { ref: 'contributor/fix', sha: 'same-name-ssh-head-oid' }
}
])
})
const pr = await getPRForBranch('/remote/repo-root', 'contributor/fix', undefined, 'ssh-1')
expect(getOwnerRepoForRemoteMock).toHaveBeenCalledWith('/remote/repo-root', 'fork', 'ssh-1')
expect(ghExecFileAsyncMock).toHaveBeenNthCalledWith(
3,
['api', 'repos/stablyai/orca/pulls?head=fork-owner%3Acontributor%2Ffix&state=all&per_page=1'],
{}
)
expect(pr).toMatchObject({
number: 79,
title: 'SSH same-name fork PR',
prRepo: { owner: 'stablyai', repo: 'orca' },
headRepo: { owner: 'fork-owner', repo: 'orca' }
})
})
it('caches positive tracked-upstream entries for unsigned SSH runtimes during PR refresh polling', async () => {
const sshGitProvider = {
exec: vi.fn().mockResolvedValue({
stdout: 'refs/heads/feature\0origin/contributor/original\n',
stderr: ''
})
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
getOwnerRepoMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' })
getOwnerRepoForRemoteMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' })
ghExecFileAsyncMock.mockResolvedValue({ stdout: JSON.stringify([]) })
await getPRForBranch('/remote/repo-root', 'feature', undefined, 'ssh-1')
await getPRForBranch('/remote/repo-root', 'feature', undefined, 'ssh-1')
await getPRForBranch('/remote/repo-root', 'feature', undefined, 'ssh-1')
expect(sshGitProvider.exec).toHaveBeenCalledTimes(1)
})
it('refreshes positive tracked-upstream entries for unsigned SSH runtimes after the TTL', async () => {
vi.useFakeTimers()
try {
const sshGitProvider = {
exec: vi
.fn()
.mockResolvedValueOnce({
stdout: 'refs/heads/feature\0origin/old-upstream\n',
stderr: ''
})
.mockResolvedValueOnce({
stdout: 'refs/heads/feature\0origin/contributor/original\n',
stderr: ''
})
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
getOwnerRepoMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' })
getOwnerRepoForRemoteMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' })
ghExecFileAsyncMock
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({ stdout: JSON.stringify([]) })
.mockResolvedValueOnce({
stdout: JSON.stringify([
{
number: 81,
title: 'Fresh SSH upstream PR',
state: 'open',
html_url: 'https://github.com/acme/widgets/pull/81',
updated_at: '2026-03-28T00:00:00Z',
draft: false,
mergeable: true,
base: { ref: 'main', sha: 'base-oid' },
head: { ref: 'contributor/original', sha: 'upstream-head-oid' }
}
])
})
await getPRForBranch('/remote/repo-root', 'feature', undefined, 'ssh-1')
await vi.advanceTimersByTimeAsync(30_001)
const pr = await getPRForBranch('/remote/repo-root', 'feature', undefined, 'ssh-1')
// Why: a found upstream PR also resolves the default branch (#26948); count snapshot probes only.
const snapshotProbes = sshGitProvider.exec.mock.calls.filter(([args]) =>
args.includes('refs/heads')
)
expect(snapshotProbes).toHaveLength(2)
expect(pr).toMatchObject({
number: 81,
title: 'Fresh SSH upstream PR'
})
} finally {
vi.useRealTimers()
}
})
})
@@ -39,7 +39,6 @@ const {
getOwnerRepoForRemoteMock,
resolvePRRepositoryCandidatesMock,
gitExecFileAsyncMock,
getSshGitProviderMock,
readLocalGitConfigSignatureMock
} = clientMocks
@@ -143,10 +142,6 @@ describe('getPRForBranch', () => {
})
it('releases tracked-upstream probe generations across runtime identities', async () => {
const sshGitProvider = {
exec: vi.fn().mockResolvedValue({ stdout: 'feature\0\n', stderr: '' })
}
getSshGitProviderMock.mockReturnValue(sshGitProvider)
getOwnerRepoMock.mockResolvedValue({ owner: 'acme', repo: 'widgets' })
ghExecFileAsyncMock.mockResolvedValue({ stdout: JSON.stringify([]) })
gitExecFileAsyncMock.mockResolvedValue({ stdout: 'feature\0\n', stderr: '' })
@@ -155,15 +150,13 @@ describe('getPRForBranch', () => {
await getPRForBranch('/repo-root', 'feature', null, null, null, {
localGitExecOptions: { wslDistro: 'Ubuntu' }
})
await getPRForBranch('/repo-root', 'feature', null, 'ssh-1')
expect(_getTrackedUpstreamBranchCacheSizesForTests()).toEqual({
snapshots: 3,
snapshots: 2,
inFlight: 0,
generations: 0
})
expect(gitExecFileAsyncMock).toHaveBeenCalledTimes(2)
expect(sshGitProvider.exec).toHaveBeenCalledTimes(1)
})
it('bounds unique tracked-upstream snapshots and sweeps expired identities', async () => {
@@ -218,11 +218,7 @@ export async function getCurrentHeadOid(
connectionId?: string | null,
localGitOptions: { wslDistro?: string; admissionTier?: GitAdmissionTier } = {}
): Promise<string | null> {
const route = requireReachableGitRoute(getConnectionExecutionHostId(connectionId))
if (route.kind === 'ssh') {
const result = await route.provider.exec(['rev-parse', 'HEAD'], repoPath)
return result.stdout.trim() || null
}
requireReachableGitRoute(getConnectionExecutionHostId(connectionId))
try {
const result = await gitExecFileAsync(['rev-parse', 'HEAD'], {
cwd: repoPath,
@@ -134,14 +134,7 @@ export async function probeTrackedUpstreamBranches(
upstreamsByBranchName: Map<string, TrackedUpstreamBranch | null>
}> {
const args = ['for-each-ref', '--format=%(refname)%00%(upstream)', 'refs/heads']
const route = requireReachableGitRoute(getConnectionExecutionHostId(connectionId))
if (route.kind === 'ssh') {
const result = await route.provider.exec(args, repoPath)
return {
probeFailed: false,
upstreamsByBranchName: parseTrackedUpstreamBranches(result.stdout)
}
}
requireReachableGitRoute(getConnectionExecutionHostId(connectionId))
try {
const result = await gitExecFileAsync(args, {
cwd: repoPath,
@@ -193,53 +193,6 @@ describe('#10284 SSH Host alias → github.com owner/repo', () => {
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
})
it('preserves a one-shot SSH remote failure through candidate discovery', async () => {
const failure = new Error('relay request failed')
const provider = {
exec: vi
.fn()
.mockRejectedValueOnce(failure)
.mockResolvedValueOnce({ stdout: 'git@github.com:team/orca.git\n', stderr: '' })
}
getSshGitProviderMock.mockReturnValue(provider)
await expect(
getOwnerRepoForRemote(
'/remote/repo',
'origin',
'ssh-1',
{},
{
requireVerifiedSshProbe: true
}
)
).rejects.toBe(failure)
await expect(getOwnerRepoForRemote('/remote/repo', 'origin', 'ssh-1')).resolves.toEqual({
owner: 'team',
repo: 'orca'
})
expect(provider.exec).toHaveBeenCalledTimes(2)
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
})
it('keeps failed SSH alias classification unverifiable', async () => {
const provider = sshProvider('')
getSshGitProviderMock.mockReturnValue(provider)
await expect(
getOwnerRepoForRemote(
'/remote/repo',
'origin',
'ssh-1',
{},
{
requireVerifiedSshProbe: true
}
)
).rejects.toThrow('Remote repository identity is unverifiable.')
expect(gitExecFileAsyncMock).not.toHaveBeenCalled()
})
it('isolates the same alias across native and WSL runtimes', async () => {
resolveWithSshGMock.mockResolvedValueOnce(sshConfig('github.com'))
commandExecFileAsyncMock.mockResolvedValueOnce({