native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #90 from supabitapp/fix/instant-pr-merge-refresh

Refresh PR state immediately after merge without synthetic MERGED status

authored by

khoi and committed by
GitHub
e3f0c7f9 da2ae6cc

+50
+7
supacode/Features/Repositories/Reducer/RepositoriesFeature.swift
··· 2045 2045 2046 2046 case .pullRequestAction(let worktreeID, let action): 2047 2047 guard let worktree = state.worktree(for: worktreeID), 2048 + let repositoryID = state.repositoryID(containing: worktreeID), 2049 + let repository = state.repositories[id: repositoryID], 2048 2050 let pullRequest = state.worktreeInfo(for: worktreeID)?.pullRequest 2049 2051 else { 2050 2052 return .send( ··· 2056 2058 } 2057 2059 let repoRoot = worktree.repositoryRootURL 2058 2060 let worktreeRoot = worktree.workingDirectory 2061 + let pullRequestRefresh = WorktreeInfoWatcherClient.Event.repositoryPullRequestRefresh( 2062 + repositoryRootURL: repoRoot, 2063 + worktreeIDs: repository.worktrees.map(\.id) 2064 + ) 2059 2065 let branchName = pullRequest.headRefName ?? worktree.name 2060 2066 let failingCheckDetailsURL = (pullRequest.statusCheckRollup?.checks ?? []).first { 2061 2067 $0.checkState == .failure && $0.detailsUrl != nil ··· 2152 2158 do { 2153 2159 try await githubCLI.mergePullRequest(worktreeRoot, pullRequest.number, strategy) 2154 2160 await send(.showToast(.success("Pull request merged"))) 2161 + await send(.worktreeInfoEvent(pullRequestRefresh)) 2155 2162 await send(.delayedPullRequestRefresh(worktreeID)) 2156 2163 } catch { 2157 2164 await send(.dismissToast)
+43
supacodeTests/RepositoriesFeatureTests.swift
··· 1379 1379 await store.finish() 1380 1380 } 1381 1381 1382 + @Test func pullRequestActionMergeRefreshesImmediatelyWithoutSyntheticMergedState() async { 1383 + let repoRoot = "/tmp/repo" 1384 + let mainWorktree = makeWorktree(id: repoRoot, name: "main", repoRoot: repoRoot) 1385 + let featureWorktree = makeWorktree( 1386 + id: "\(repoRoot)/feature", 1387 + name: "feature", 1388 + repoRoot: repoRoot 1389 + ) 1390 + let repository = makeRepository(id: repoRoot, worktrees: [mainWorktree, featureWorktree]) 1391 + let openPullRequest = makePullRequest(state: "OPEN", headRefName: featureWorktree.name, number: 12) 1392 + var state = makeState(repositories: [repository]) 1393 + state.githubIntegrationAvailability = .disabled 1394 + state.automaticallyArchiveMergedWorktrees = true 1395 + state.worktreeInfoByID[featureWorktree.id] = WorktreeInfoEntry( 1396 + addedLines: nil, 1397 + removedLines: nil, 1398 + pullRequest: openPullRequest 1399 + ) 1400 + let mergedNumbers = LockIsolated<[Int]>([]) 1401 + let store = TestStore(initialState: state) { 1402 + RepositoriesFeature() 1403 + } withDependencies: { 1404 + $0.githubIntegration.isAvailable = { true } 1405 + $0.githubCLI.mergePullRequest = { _, number, _ in 1406 + mergedNumbers.withValue { $0.append(number) } 1407 + } 1408 + } 1409 + store.exhaustivity = .off 1410 + 1411 + await store.send(.pullRequestAction(featureWorktree.id, .merge)) 1412 + await store.receive(\.showToast) { 1413 + $0.statusToast = .inProgress("Merging pull request…") 1414 + } 1415 + await store.receive(\.showToast) { 1416 + $0.statusToast = .success("Pull request merged") 1417 + } 1418 + await store.receive(\.worktreeInfoEvent) 1419 + #expect(store.state.worktreeInfoByID[featureWorktree.id]?.pullRequest?.state == "OPEN") 1420 + #expect(store.state.archivedWorktreeIDs.isEmpty) 1421 + #expect(mergedNumbers.value == [12]) 1422 + await store.finish() 1423 + } 1424 + 1382 1425 @Test func worktreeInfoEventRepositoryPullRequestRefreshMarksInFlightThenCompletes() async { 1383 1426 let repoRoot = "/tmp/repo" 1384 1427 let mainWorktree = makeWorktree(id: repoRoot, name: "main", repoRoot: repoRoot)