Fix GitHub Enterprise host identity loss across PR/work-item paths

- Thread `host` through mobile PR RPC params, IPC work-item lookups, and
  RPC schemas so GHES identity survives the renderer/mobile/main boundary
  instead of silently falling back to a same-named github.com repo.
- Qualify `--repo`/`-R` args for github.com too (not just GHES), since
  gh resolves bare shorthand against a process-level GH_HOST that can
  redirect pinned github.com commands.
- Cache `getOriginGitHubApiRepository` to avoid a per-call uncached
  `git remote get-url` round trip on connection-backed repos.
- Add a local-fork fallback in `getWorkItemDetails` so PRs living on a
  base repo (not visible via the origin slug) still resolve via cwd.
- Centralize the github.com-vs-GHES host predicate in
  `isDefaultGitHubHost` so cache keys, quota scoping, and identity
  checks can't drift out of sync.
This commit is contained in:
Jinjing
2026-07-16 22:32:04 -07:00
parent 5487dff295
commit 8bbbc62f3d
28 changed files with 275 additions and 70 deletions
+15 -11
View File
@@ -79,7 +79,6 @@ import {
rememberGhCwdResolutionFailure
} from './gh-cwd-repo-negative-cache'
import type { GitHubRepoContext } from './github-repository-identity'
import { getEnterpriseGitHubRepoSlug } from './github-enterprise-repository'
import {
getOriginGitHubApiRepository,
githubHostExecOptions,
@@ -111,7 +110,6 @@ import {
import { mapGraphQLReactionGroups, type GitHubGraphQLReactionGroup } from './comment-reactions'
import {
getRateLimit,
noteRateLimitSpend,
noteRepositoryRateLimitSpend,
rateLimitGuard,
repositoryRateLimitGuard,
@@ -1520,7 +1518,7 @@ async function countWorkItemsForQuery(
)
// Why: over-counts gh cache hits, which is the safe direction — the search
// bucket is only 30/min and the next probe corrects the estimate.
noteRateLimitSpend('search')
noteRepositoryRateLimitSpend(ownerRepo, 'search', 1, localGitOptions)
return Number.parseInt(stdout.trim(), 10) || 0
}
@@ -1580,8 +1578,11 @@ export async function countWorkItems(
// 30/min, so a multi-repo Tasks page must stop counting when the budget is
// gone instead of converting the remaining repos into 403 spawns. getRateLimit
// is 30s-cached and single-flight, so priming here is one spawn per window.
await getRateLimit()
if (rateLimitGuard('search').blocked) {
// Only shared github.com traffic consults the snapshot; other scopes bypass.
if (spendsSharedGitHubComQuota(ownerRepo, localGitOptions)) {
await getRateLimit()
}
if (repositoryRateLimitGuard(ownerRepo, 'search', localGitOptions).blocked) {
return 0
}
@@ -1876,11 +1877,14 @@ export async function createGitHubPullRequest(
}
}
// Why: github.com-only slug parsing returns null for GHES, so fall back to the
// enterprise resolver (gh-authenticated custom host) before giving up (#8312).
const ownerRepo =
(await getOwnerRepo(repoPath, connectionId, ...hostedReviewLocalGitOptionArgs(options))) ??
(await getEnterpriseGitHubRepoSlug(repoPath, connectionId, options))
// Why: the shared origin resolver covers GHES fallback and stamps
// host:'github.com' on dotcom slugs, keeping creation pinned against GH_HOST
// like every other PR path (#8312).
const ownerRepo = await getOriginGitHubApiRepository(
repoPath,
connectionId,
getHostedReviewLocalGitOptions(options)
)
if (!ownerRepo) {
return {
ok: false,
@@ -4359,7 +4363,7 @@ export async function getPRComments(
['pr', 'view', String(prNumber), '--json', 'comments'],
ghOptions
)
noteRateLimitSpend('graphql')
noteRepositoryRateLimitSpend(ownerRepo, 'graphql', 1, ghOptions)
const data = JSON.parse(stdout) as {
comments: {
author: { login: string }