Files
orca/src/main/github/issue-field-options.ts
T
Brennan Benson 40f9d2a246 Keep desktop fork pull requests on their opened repository (#36172)
* Keep opened GitHub work items bound to their exact repository

* Bind GitHub work item ownership through consumers and dispatch

* Keep empty mention lists from consuming selection keys

* Preserve GitHub action and consumer ownership across resource changes

* Exercise repository account updates through their production store action

* Exercise account publication and cache settlement through GitHub consumers

* Simplify fork PR contract verification

* Make contract verification imports and clocks deterministic

* Correct mobile task test fixtures and model types

* Correct task recording fixtures and CI types

* Correct task fixture types and static checks

* Consolidate replay test RPC imports

* Separate GitHub metadata imports from Linear hooks

* Scope mobile PR sidebar reads to the selected resource

* Separate desktop GitHub changes from phone updates

* Fix relay authority probe census across topology cases

* Repair repository owner proof fixtures and compiler allocation

* Preserve repository row observation in host lookup

* Seed metadata fixture before server-side store acquisition

* Preserve nullable fixture settings and discover mixed test types

* Preserve GitHub detail argument types and optional capabilities

* Let keyed details queries own pending read replacement

* Repair GitHub RPC and relay test fixture boundaries

* Verify expected GitHub account at repository execution capture

* Preserve captured GitHub account expectations through client dispatch

* Retain observed runtime status after switching environments

* Fix account contract fixture types and RPC setup timing

* Restore the negative-capability switch probe assertion

* Align account fixtures with runtime identity and configured origin

* Consolidate details test imports

* Drop duplicate fork pull request identity tests
2026-11-02 13:22:48 -08:00

128 lines
3.3 KiB
TypeScript

import type { GhAccountBinding } from '../../shared/github/account-binding'
import type { GitHubAssignableUser, GitHubOwnerRepo } from '../../shared/github/pull-request-types'
import type { IssueSourcePreference } from '../../shared/repo-types'
import type { LocalGitExecOptions } from './gh-utils'
import {
resolveGitHubRepoExecution,
resolveIssueGitHubApiRepositorySource
} from './github-api-repository'
import { acquire, ghExecFileAsync, release } from './gh-utils'
export async function listLabels(
repoPath: string,
preference?: IssueSourcePreference,
connectionId?: string | null,
localGitOptions: LocalGitExecOptions = {},
repositoryOverride?: GitHubOwnerRepo | null,
expectedGhAccount?: GhAccountBinding | null
): Promise<string[]> {
const { ownerRepo, ghOptions } = await resolveGitHubRepoExecution(
repoPath,
repositoryOverride ??
(async () =>
(
await resolveIssueGitHubApiRepositorySource(
repoPath,
preference,
connectionId,
localGitOptions
)
).source),
connectionId,
localGitOptions,
expectedGhAccount
)
if (!ownerRepo) {
return []
}
await acquire()
try {
const { stdout } = await ghExecFileAsync(
[
'api',
'--paginate',
`repos/${ownerRepo.owner}/${ownerRepo.repo}/labels`,
'--jq',
'.[].name'
],
ghOptions
)
return stdout
.trim()
.split('\n')
.filter((l) => l.length > 0)
} catch {
return []
} finally {
release()
}
}
export async function listAssignableUsers(
repoPath: string,
preference?: IssueSourcePreference,
connectionId?: string | null,
localGitOptions: LocalGitExecOptions = {},
repositoryOverride?: GitHubOwnerRepo | null,
expectedGhAccount?: GhAccountBinding | null
): Promise<GitHubAssignableUser[]> {
const { ownerRepo, ghOptions } = await resolveGitHubRepoExecution(
repoPath,
repositoryOverride ??
(async () =>
(
await resolveIssueGitHubApiRepositorySource(
repoPath,
preference,
connectionId,
localGitOptions
)
).source),
connectionId,
localGitOptions,
expectedGhAccount
)
if (!ownerRepo) {
return []
}
await acquire()
try {
// REST pagination covers all assignees; jq emits NDJSON instead of concatenated page arrays.
const { stdout } = await ghExecFileAsync(
[
'api',
'--paginate',
`repos/${ownerRepo.owner}/${ownerRepo.repo}/assignees?per_page=100`,
'--jq',
'.[] | {login, avatar_url}'
],
ghOptions
)
type RESTAssignee = { login?: string; avatar_url?: string | null }
const users: GitHubAssignableUser[] = []
for (const line of stdout.split('\n')) {
const trimmed = line.trim()
if (!trimmed) {
continue
}
try {
const user = JSON.parse(trimmed) as RESTAssignee
if (user.login) {
users.push({
login: user.login,
name: null,
avatarUrl: user.avatar_url ?? ''
})
}
} catch {
// Skip malformed NDJSON lines defensively.
}
}
return users
} catch {
return []
} finally {
release()
}
}