mirror of
https://github.com/stablyai/orca.git
synced 2026-11-06 03:57:35 +00:00
* fix(github): resolve SSH host aliases for account binding An origin like git@github-personal:owner/repo kept the alias as the required gh host, so the Settings account list matched nothing. * fix(github): keep github.com filter for resolved aliases and resolve in the gh runtime Real canonical keys carry github.com, so an alias resolving to github.com must filter to github.com like a direct remote. Resolve via the runtime-scoped resolveSshConfigHostname (WSL distro aware) and keep Enterprise hosts exact. * fix(github): expand SSH aliases only for SSH-transport remotes * fix(github): resolve the SSH alias with its original case --------- Co-authored-by: orchardprior <342342873+orchardprior@users.noreply.github.com> Co-authored-by: Neil <neil@stably.ai>
54 lines
2.3 KiB
TypeScript
54 lines
2.3 KiB
TypeScript
import {
|
|
isUnresolvedSshHostAlias,
|
|
foldComparableGitHubHost
|
|
} from '../../shared/git-remote-host-alias'
|
|
import { githubHostFromIdentityKey } from '../../shared/github/repository-identity-key'
|
|
import { rawSshTransportHost, remoteUrlUsesSshTransport } from './github-remote-identity-parsing'
|
|
import {
|
|
resolveSshConfigHostname,
|
|
type SshConfigResolutionContext
|
|
} from './github-ssh-host-alias-resolution'
|
|
|
|
export type SshAliasHostnameResolver = (
|
|
alias: string,
|
|
context: SshConfigResolutionContext
|
|
) => Promise<{ hostname: string | null }>
|
|
|
|
/**
|
|
* Host filter for Settings GitHub account binding.
|
|
* `undefined` means do not filter.
|
|
*/
|
|
export async function resolveGhAccountRequiredHost(
|
|
repo: {
|
|
path: string
|
|
connectionId?: string | null
|
|
gitRemoteIdentity?: { canonicalKey: string; remoteUrl: string } | null
|
|
},
|
|
localGitOptions: { wslDistro?: string },
|
|
resolveAlias: SshAliasHostnameResolver = resolveSshConfigHostname
|
|
): Promise<string | undefined> {
|
|
const host = githubHostFromIdentityKey(repo.gitRemoteIdentity?.canonicalKey)
|
|
// Why: only SSH transport reads ~/.ssh/config; a dotless HTTPS host is literal.
|
|
const remoteUrl = repo.gitRemoteIdentity?.remoteUrl ?? ''
|
|
if (!host || !isUnresolvedSshHostAlias(host) || !remoteUrlUsesSshTransport(remoteUrl)) {
|
|
return host
|
|
}
|
|
// Why: `git@github-personal:owner/repo` keeps the OpenSSH alias in the identity key.
|
|
// No gh login is named after that alias, so filtering to it empties the dropdown.
|
|
// Resolve in the runtime that runs gh (WSL distro vs host) so both see the same ssh config.
|
|
const context: SshConfigResolutionContext = {
|
|
repoPath: repo.path,
|
|
connectionId: repo.connectionId ?? null,
|
|
...(localGitOptions.wslDistro ? { wslDistro: localGitOptions.wslDistro } : {})
|
|
}
|
|
// Why raw: the canonical key is lowercased, but OpenSSH matches Host patterns case-sensitively.
|
|
const alias = rawSshTransportHost(remoteUrl) ?? host
|
|
const resolved = await resolveAlias(alias, context).catch(() => null)
|
|
const hostname = resolved?.hostname?.trim().toLowerCase()
|
|
if (!hostname || isUnresolvedSshHostAlias(hostname)) {
|
|
return undefined
|
|
}
|
|
// Why: only github.com's SSH/www aliases fold; gh keys an Enterprise login by its exact host.
|
|
return foldComparableGitHubHost(hostname) === 'github.com' ? 'github.com' : hostname
|
|
}
|