Fix duplicate paired hosts in worktree run target picker (#10218)
This commit is contained in:
parent
5dc6799c48
commit
84968dfd9e
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
])
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue