fix(tasks): resolve PR work items upstream-first under 'auto' like issues (#8727)

This commit is contained in:
moseoh 2026-07-24 15:20:52 +09:00 committed by GitHub
parent 91884b6d5f
commit 832aa69ce8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 56 additions and 2 deletions

View File

@ -696,6 +696,58 @@ describe('GitHub issue source split', () => {
})
})
it("preference='auto' + upstream exists → PRs query upstream too", async () => {
// Why: fork-contribution PRs live on the upstream repo — the fork's own
// PR list is almost always empty. 'auto' must resolve PRs upstream-first
// like issues, or the PRs tab renders "No matching GitHub work" on forks.
resolveIssueSourceMock.mockResolvedValueOnce({
source: { owner: 'stablyai', repo: 'orca' },
fellBack: false
})
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'fork', repo: 'orca' })
mockUpstreamCandidate({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '[]' }).mockResolvedValueOnce({
stdout: '[]'
})
const result = await listWorkItems('/repo-root', 10, undefined, undefined, 'auto')
expect(ghExecFileAsyncMock).toHaveBeenNthCalledWith(
2,
expect.arrayContaining(['--repo', 'stablyai/orca']),
{ cwd: '/repo-root' }
)
expect(result.sources).toEqual({
issues: { owner: 'stablyai', repo: 'orca' },
prs: { owner: 'stablyai', repo: 'orca' },
originCandidate: { owner: 'fork', repo: 'orca' },
upstreamCandidate: { owner: 'stablyai', repo: 'orca' }
})
})
it('collapses the default count to one query when auto resolves both sides to upstream', async () => {
getIssueOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' })
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'fork', repo: 'orca' })
mockUpstreamCandidate({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '11\n' })
const count = await countWorkItems('/repo-root')
expect(count).toBe(11)
expect(ghExecFileAsyncMock).toHaveBeenCalledTimes(1)
expect(ghExecFileAsyncMock).toHaveBeenCalledWith(
[
'api',
'--cache',
'120s',
`search/issues?q=${encodeURIComponent('repo:stablyai/orca is:open')}&per_page=1`,
'--jq',
'.total_count'
],
{ cwd: '/repo-root' }
)
})
it("preference='upstream' + upstream exists → queries upstream", async () => {
resolveIssueSourceMock.mockResolvedValueOnce({
source: { owner: 'stablyai', repo: 'orca' },

View File

@ -1109,8 +1109,10 @@ async function resolvePrWorkItemSource(
getOriginGitHubApiRepository(repoPath, connectionId, localGitOptions),
getGitHubApiRepositoryForRemote(repoPath, 'upstream', connectionId, localGitOptions)
])
const source =
preference === 'upstream' ? (upstreamCandidate ?? originCandidate) : originCandidate
// Why: fork-contribution PRs live on the upstream repo (the fork's own PR
// list is almost always empty), so 'auto' resolves upstream-first exactly
// like the issue side. Only an explicit 'origin' pick pins PRs to the fork.
const source = preference === 'origin' ? originCandidate : (upstreamCandidate ?? originCandidate)
return { source, originCandidate, upstreamCandidate }
}