diff options
| author | Matt Silverlock <[email protected]> | 2026-01-04 03:05:08 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-04 02:05:08 -0600 |
| commit | 4486174e4319b9523d134fda863677f35e740105 (patch) | |
| tree | a83ee60b875b48590c7b81c0714ddb33e017bc9d | |
| parent | 41cf45a16e0545f9882c8b2b2f258e8935ea19b4 (diff) | |
| download | opencode-4486174e4319b9523d134fda863677f35e740105.tar.gz opencode-4486174e4319b9523d134fda863677f35e740105.zip | |
github: handle duplicate PR creation when agent creates PR (#6777)
| -rw-r--r-- | packages/opencode/src/cli/cmd/github.ts | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/packages/opencode/src/cli/cmd/github.ts b/packages/opencode/src/cli/cmd/github.ts index fbd2506e0..4c1e5b0e0 100644 --- a/packages/opencode/src/cli/cmd/github.ts +++ b/packages/opencode/src/cli/cmd/github.ts @@ -1237,17 +1237,55 @@ Co-authored-by: ${actor} <${actor}@users.noreply.github.com>"` async function createPR(base: string, branch: string, title: string, body: string) { console.log("Creating pull request...") - const pr = await octoRest.rest.pulls.create({ - owner, - repo, - head: branch, - base, - title, - body, - }) + + // Check if an open PR already exists for this head→base combination + // This handles the case where the agent created a PR via gh pr create during its run + try { + const existing = await withRetry(() => + octoRest.rest.pulls.list({ + owner, + repo, + head: `${owner}:${branch}`, + base, + state: "open", + }), + ) + + if (existing.data.length > 0) { + console.log(`PR #${existing.data[0].number} already exists for branch ${branch}`) + return existing.data[0].number + } + } catch (e) { + // If the check fails, proceed to create - we'll get a clear error if a PR already exists + console.log(`Failed to check for existing PR: ${e}`) + } + + const pr = await withRetry(() => + octoRest.rest.pulls.create({ + owner, + repo, + head: branch, + base, + title, + body, + }), + ) return pr.data.number } + async function withRetry<T>(fn: () => Promise<T>, retries = 1, delayMs = 5000): Promise<T> { + try { + return await fn() + } catch (e) { + if (retries > 0) { + console.log(`Retrying after ${delayMs}ms...`) + await Bun.sleep(delayMs) + return withRetry(fn, retries - 1, delayMs) + } + throw e + } + } + function footer(opts?: { image?: boolean }) { const image = (() => { if (!shareId) return "" |
