Skip to content

fix(desktop): avoid stale historical PR matches#2906

Merged
Kitenite merged 1 commit into
mainfrom
toothsome-humidity
Mar 26, 2026
Merged

fix(desktop): avoid stale historical PR matches#2906
Kitenite merged 1 commit into
mainfrom
toothsome-humidity

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Mar 26, 2026

Summary

  • tighten desktop PR resolution so branch-name matches do not attach stale closed or merged PRs unless the workspace HEAD still matches that PR head commit
  • keep open PR matching behavior unchanged so active branch workflows continue to resolve normally
  • add targeted tests for open and historical PR matching behavior

Verification

  • bun test apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts
  • bunx biome check apps/desktop/src/lib/trpc/routers/workspaces/utils/github/pr-resolution.ts apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts

Task: ab8cd32a-0770-4add-9611-eaab15df7692


Summary by cubic

Stops stale PRs from auto-attaching in Desktop when a branch name is reused by only accepting closed/merged PRs if the workspace HEAD matches the PR head commit. Open PR matching stays the same.

  • Bug Fixes
    • Added shouldAcceptPRMatch to verify branch match and, for closed/merged PRs, require head SHA equality.
    • Passed headSha through tracking and search; replaced direct checks with shouldAcceptPRMatch.
    • Added tests for open vs. historical matching; aligns with Linear task ab8cd32a-0770-4add-9611-eaab15df7692.

Written for commit ec8d470. Summary will update on new commits.

Summary by CodeRabbit

  • Tests

    • Added comprehensive test coverage for pull request matching validation across different PR states.
  • Bug Fixes

    • Improved pull request detection to correctly handle OPEN, MERGED, and CLOSED pull requests with accurate branch state matching.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 26, 2026

📝 Walkthrough

Walkthrough

This change enhances PR matching logic to consider HEAD SHA when validating pull request candidates. A new shouldAcceptPRMatch function is introduced and integrated into PR resolution logic, with accompanying test coverage validating behavior across different PR states and SHA scenarios.

Changes

Cohort / File(s) Summary
Test Coverage
apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts
Added three test cases for shouldAcceptPRMatch, validating acceptance of OPEN PRs regardless of HEAD SHA variance, and rejection/acceptance of historical PR states based on SHA equality.
PR Resolution Logic
apps/desktop/src/lib/trpc/routers/workspaces/utils/github/pr-resolution.ts
Introduced shouldAcceptPRMatch predicate and isHistoricalPullRequestState helper; updated getPRForBranch, getPRByBranchTracking, and findPRByHeadBranch to apply SHA-aware filtering when matching PRs to local branches.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A PR to match, with SHA so bright,
Open states flow through without a fight,
But merged and closed must prove their trace—
Equal SHAs to win the race! 🔍✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main change: avoiding stale historical PR matches by adding a check for HEAD SHA equality in closed/merged PR resolution.
Description check ✅ Passed The PR description provides a clear summary of changes, verification steps, and testing instructions, though it does not follow the provided template structure with sections like 'Type of Change' and 'Related Issues'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch toothsome-humidity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts (1)

411-456: Consider adding test coverage for CLOSED state and undefined headSha.

The test suite covers the core scenarios well. Two optional additions would strengthen coverage:

  1. A test for state: "CLOSED" to explicitly verify it behaves identically to MERGED for historical PR rejection.
  2. A test where headSha is undefined to verify the fallback path (should accept any branch-matching PR regardless of state).
💡 Suggested additional test cases
 	test("accepts historical PR matches when the head commit still matches", () => {
 		expect(
 			shouldAcceptPRMatch({
 				localBranch: "feature/my-thing",
 				headSha: "same-head-sha",
 				pr: {
 					headRefName: "feature/my-thing",
 					headRefOid: "same-head-sha",
 					headRepositoryOwner: null,
 					state: "MERGED",
 				},
 			}),
 		).toBe(true);
 	});
+
+	test("rejects closed PR matches when the head commit differs", () => {
+		expect(
+			shouldAcceptPRMatch({
+				localBranch: "feature/my-thing",
+				headSha: "new-head-sha",
+				pr: {
+					headRefName: "feature/my-thing",
+					headRefOid: "old-pr-head-sha",
+					headRepositoryOwner: null,
+					state: "CLOSED",
+				},
+			}),
+		).toBe(false);
+	});
+
+	test("accepts historical PR when headSha is not provided", () => {
+		expect(
+			shouldAcceptPRMatch({
+				localBranch: "feature/my-thing",
+				headSha: undefined,
+				pr: {
+					headRefName: "feature/my-thing",
+					headRefOid: "any-sha",
+					headRepositoryOwner: null,
+					state: "MERGED",
+				},
+			}),
+		).toBe(true);
+	});
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts`
around lines 411 - 456, Add two unit tests for shouldAcceptPRMatch: one that
verifies PRs with state "CLOSED" are treated like "MERGED" by copying the
existing "rejects historical PR matches when the head commit differs" case but
using state: "CLOSED" and expecting toBe(false), and another that verifies when
local headSha is undefined the function accepts branch-matching PRs regardless
of PR state by adding a case with headSha: undefined, a matching headRefName, a
different pr.headRefOid and state: "MERGED" (or "CLOSED") and expecting
toBe(true); place both tests inside the existing describe("shouldAcceptPRMatch")
block near the other cases so they follow the same pattern and naming style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts`:
- Around line 411-456: Add two unit tests for shouldAcceptPRMatch: one that
verifies PRs with state "CLOSED" are treated like "MERGED" by copying the
existing "rejects historical PR matches when the head commit differs" case but
using state: "CLOSED" and expecting toBe(false), and another that verifies when
local headSha is undefined the function accepts branch-matching PRs regardless
of PR state by adding a case with headSha: undefined, a matching headRefName, a
different pr.headRefOid and state: "MERGED" (or "CLOSED") and expecting
toBe(true); place both tests inside the existing describe("shouldAcceptPRMatch")
block near the other cases so they follow the same pattern and naming style.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6b84bd35-60ee-4ad3-9c03-20c07dd58a09

📥 Commits

Reviewing files that changed from the base of the PR and between a256303 and ec8d470.

📒 Files selected for processing (2)
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/pr-resolution.ts

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@Kitenite Kitenite merged commit c5f00d3 into main Mar 26, 2026
6 of 7 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant