Fix duplicate paired hosts in worktree run target picker (#10218)

This commit is contained in:
OrcaWin 2026-07-23 13:01:28 -07:00 committed by GitHub
parent 5dc6799c48
commit 84968dfd9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 77 additions and 4 deletions

View File

@ -479,7 +479,9 @@ describe('fetchReposForAllHosts', () => {
await store.getState().fetchReposForAllHosts()
expectSharedProjectMetadata(store.getState().projects, sharedProjectId)
expect(store.getState().projectHostSetups).toEqual(
const setups = store.getState().projectHostSetups
expect(setups).toHaveLength(2)
expect(setups).toEqual(
expect.arrayContaining([
expect.objectContaining({
projectId: sharedProjectId,

View File

@ -74,7 +74,9 @@ it('preserves distinct SSH execution setups behind the same runtime owner', asyn
await store.getState().fetchRepos()
expect(store.getState().projectHostSetups).toEqual(
const setups = store.getState().projectHostSetups
expect(setups).toHaveLength(2)
expect(setups).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 'direct-setup',
@ -91,3 +93,67 @@ it('preserves distinct SSH execution setups behind the same runtime owner', asyn
])
)
})
it('prefers an authoritative paired-runtime setup over its repo-derived fallback', async () => {
const project: Project = {
id: `repo:${remoteRepo.id}`,
displayName: remoteRepo.displayName,
badgeColor: remoteRepo.badgeColor,
sourceRepoIds: [remoteRepo.id],
createdAt: 1,
updatedAt: 1
}
const setup: ProjectHostSetup = {
id: remoteRepo.id,
projectId: project.id,
hostId: 'local',
repoId: remoteRepo.id,
path: remoteRepo.path,
displayName: remoteRepo.displayName,
setupState: 'ready',
setupMethod: 'legacy-repo',
createdAt: 1,
updatedAt: 1
}
runtimeEnvironmentCall.mockImplementation(({ method }: { method: string }) => {
if (method === 'repo.list') {
return Promise.resolve({
id: 'repo-list',
ok: true,
result: { repos: [remoteRepo] },
_meta: { runtimeId: 'runtime-remote' }
})
}
if (method === 'project.list') {
return Promise.resolve({
id: 'project-list',
ok: true,
result: { projects: [project] },
_meta: { runtimeId: 'runtime-remote' }
})
}
if (method === 'projectHostSetup.list') {
return Promise.resolve({
id: 'setup-list',
ok: true,
result: { setups: [setup] },
_meta: { runtimeId: 'runtime-remote' }
})
}
throw new Error(`Unexpected method ${method}`)
})
const store = createTestStore()
store.setState({ settings: { activeRuntimeEnvironmentId: 'env-1' } as never })
await store.getState().fetchRepos()
expect(store.getState().projectHostSetups).toEqual([
{
...setup,
hostId: 'runtime:env-1',
executionHostId: 'runtime:env-1',
runtimeOwnerEnvironmentId: 'env-1',
connectionId: null
}
])
})

View File

@ -613,9 +613,9 @@ function mergeProjectHostSetupCompatibility(
derived: Pick<RepoSlice, 'projects' | 'projectHostSetups'>,
fetched: ProjectHostSetupProjection
): Pick<RepoSlice, 'projects' | 'projectHostSetups'> {
const fetchedSetupOwners = new Set(fetched.setups.map(getProjectHostSetupOwnerKey))
const fetchedRepoSetupKeys = new Set(fetched.setups.map(getRepoDerivedSetupKey))
const derivedSetups = derived.projectHostSetups.filter(
(setup) => !fetchedSetupOwners.has(getProjectHostSetupOwnerKey(setup))
(setup) => !fetchedRepoSetupKeys.has(getRepoDerivedSetupKey(setup))
)
const projectHostSetups = mergeProjectHostSetupsByOwner(derivedSetups, fetched.setups)
const setupProjectIds = new Set(projectHostSetups.map((setup) => setup.projectId))
@ -628,6 +628,11 @@ function mergeProjectHostSetupCompatibility(
}
}
function getRepoDerivedSetupKey(setup: ProjectHostSetup): string {
// Why: authoritative routing provenance may be absent from the repo-derived fallback it replaces.
return JSON.stringify([setup.hostId, setup.repoId || setup.id])
}
function getProjectHostSetupOwnerKey(setup: ProjectHostSetup): string {
return JSON.stringify([
setup.hostId,