mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 08:03:22 +00:00
Bound GHES identity caches and preserve non-default ports in host identity
Cap the origin-repo and host-auth caches like ownerRepoCache; keep ports from remote/link URLs so GHES on a non-default port is a distinct identity; make positional github.com slugs explicit against GH_HOST; compare work-item sources by host-aware identity key; bail cwd-less branch lookups when no repository candidate resolved; thread host through the renderer work-item slug lookup. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -15,6 +15,7 @@ export type GitHubApiRepository = GitHubOwnerRepo
|
||||
// round trip on connection-backed repos) — hot paths like per-file contents
|
||||
// and viewed-state toggles resolve per call, so cache like ownerRepoCache does.
|
||||
const ORIGIN_REPO_CACHE_TTL_MS = 30_000
|
||||
const ORIGIN_REPO_CACHE_MAX_ENTRIES = 512
|
||||
const originRepoCache = new Map<string, { value: GitHubApiRepository | null; expiresAt: number }>()
|
||||
const originRepoInFlight = new Map<string, Promise<GitHubApiRepository | null>>()
|
||||
|
||||
@@ -33,6 +34,26 @@ export function _resetOriginGitHubApiRepositoryCache(): void {
|
||||
originRepoInFlight.clear()
|
||||
}
|
||||
|
||||
/** @internal - exposed for cache-bound tests only */
|
||||
export function _getOriginGitHubApiRepositoryCacheSize(): number {
|
||||
return originRepoCache.size
|
||||
}
|
||||
|
||||
function pruneOriginRepoCache(now: number): void {
|
||||
for (const [key, entry] of originRepoCache) {
|
||||
if (entry.expiresAt <= now) {
|
||||
originRepoCache.delete(key)
|
||||
}
|
||||
}
|
||||
while (originRepoCache.size > ORIGIN_REPO_CACHE_MAX_ENTRIES) {
|
||||
const oldestKey = originRepoCache.keys().next().value
|
||||
if (oldestKey === undefined) {
|
||||
return
|
||||
}
|
||||
originRepoCache.delete(oldestKey)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Host-qualified repository identity for one remote: github.com remotes come
|
||||
* from the cached slug parser; any other GitHub-shaped host is auth-gated so a
|
||||
@@ -56,8 +77,10 @@ export async function getGitHubApiRepositoryForRemote(
|
||||
return { ...ownerRepo, host: 'github.com' }
|
||||
}
|
||||
const cacheKey = originRepoCacheKey(repoPath, remoteName, connectionId, localGitOptions)
|
||||
const now = Date.now()
|
||||
pruneOriginRepoCache(now)
|
||||
const cached = originRepoCache.get(cacheKey)
|
||||
if (cached && cached.expiresAt > Date.now()) {
|
||||
if (cached && cached.expiresAt > now) {
|
||||
return cached.value
|
||||
}
|
||||
const inFlight = originRepoInFlight.get(cacheKey)
|
||||
@@ -77,6 +100,7 @@ export async function getGitHubApiRepositoryForRemote(
|
||||
enterpriseOptions
|
||||
)
|
||||
originRepoCache.set(cacheKey, { value: slug, expiresAt: Date.now() + ORIGIN_REPO_CACHE_TTL_MS })
|
||||
pruneOriginRepoCache(Date.now())
|
||||
return slug
|
||||
})()
|
||||
originRepoInFlight.set(cacheKey, probe)
|
||||
@@ -241,11 +265,11 @@ export function githubRepositoryWebHost(repository: GitHubApiRepository): string
|
||||
/**
|
||||
* Positional `HOST/OWNER/REPO` argv value (e.g. `gh repo view <slug>`).
|
||||
* Positional slugs bypass the runner's `--repo` qualifier, so they must be
|
||||
* qualified here; github.com stays bare for compatibility with gh's default.
|
||||
* qualified here whenever the host is known.
|
||||
*/
|
||||
export function githubRepositorySlugArg(repository: GitHubApiRepository): string {
|
||||
const slug = `${repository.owner}/${repository.repo}`
|
||||
return repository.host && !isDefaultGitHubHost(repository.host)
|
||||
? `${repository.host}/${slug}`
|
||||
: slug
|
||||
// Why: github.com must be explicit too; otherwise process-level GH_HOST can
|
||||
// redirect positional `gh repo view OWNER/REPO` calls to an Enterprise host.
|
||||
return repository.host ? `${repository.host}/${slug}` : slug
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user