From 7c50d6371d9a5baffde1b593e8a9307adc075864 Mon Sep 17 00:00:00 2001 From: systemBlue Date: Tue, 2 Jun 2026 15:38:46 -0400 Subject: [PATCH] fix: don't open a duplicate PR when the reviewer request fails createPullRequest created the PR and then requested reviewers in the same submit. If the reviewer request threw, the sheet stayed open with no record that the PR already existed, so tapping Create again ran the whole flow and opened a second PR. Track the created PR number and skip re-creation on retry, only re-requesting reviewers. Co-Authored-By: Claude Opus 4.8 (1M context) --- Forji/Forji/Views/PullRequestCreateView.swift | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Forji/Forji/Views/PullRequestCreateView.swift b/Forji/Forji/Views/PullRequestCreateView.swift index 38f2b33..e3cc200 100644 --- a/Forji/Forji/Views/PullRequestCreateView.swift +++ b/Forji/Forji/Views/PullRequestCreateView.swift @@ -20,6 +20,7 @@ struct PullRequestCreateView: View { @State private var selectedMilestoneID: Int? @State private var selectedAssigneeLogins: Set = [] @State private var selectedReviewerLogins: Set = [] + @State private var createdPRNumber: Int? @Environment(\.dismiss) private var dismiss private let prService: PullRequestService? @@ -175,24 +176,33 @@ struct PullRequestCreateView: View { guard let prService else { return } isSubmitting = true do { - let trimmedBody = bodyText.trimmingCharacters(in: .whitespacesAndNewlines) - let createdPR = try await prService.createPullRequest( - owner: owner, - repo: repo, - title: title.trimmingCharacters(in: .whitespacesAndNewlines), - head: headBranch, - base: baseBranch, - body: trimmedBody.isEmpty ? nil : trimmedBody, - labels: selectedLabelIDs.isEmpty ? nil : Array(selectedLabelIDs), - milestone: selectedMilestoneID, - assignees: selectedAssigneeLogins.isEmpty ? nil : Array(selectedAssigneeLogins), - ) + // Reuse the already-created PR on retry so a failed reviewer request + // doesn't open a duplicate PR when the user taps Create again. + let prNumber: Int + if let existingNumber = createdPRNumber { + prNumber = existingNumber + } else { + let trimmedBody = bodyText.trimmingCharacters(in: .whitespacesAndNewlines) + let createdPR = try await prService.createPullRequest( + owner: owner, + repo: repo, + title: title.trimmingCharacters(in: .whitespacesAndNewlines), + head: headBranch, + base: baseBranch, + body: trimmedBody.isEmpty ? nil : trimmedBody, + labels: selectedLabelIDs.isEmpty ? nil : Array(selectedLabelIDs), + milestone: selectedMilestoneID, + assignees: selectedAssigneeLogins.isEmpty ? nil : Array(selectedAssigneeLogins), + ) + createdPRNumber = createdPR.number + prNumber = createdPR.number + } if !selectedReviewerLogins.isEmpty { do { try await prService.requestReviewers( owner: owner, repo: repo, - index: createdPR.number, + index: prNumber, reviewers: Array(selectedReviewerLogins), ) } catch {