diff --git a/apps/server/src/git/GitManager.test.ts b/apps/server/src/git/GitManager.test.ts index a71f19e6a973b..350cb9e8340aa 100644 --- a/apps/server/src/git/GitManager.test.ts +++ b/apps/server/src/git/GitManager.test.ts @@ -3091,6 +3091,56 @@ it.layer(layerGitManagerTest)("GitManager", (it) => { }), ); + it.effect("create_pr reports a created PR when the lookup after creation fails", () => + Effect.gen(function* () { + const repoDir = yield* makeTempDir("t3code-git-manager-"); + yield* initRepo(repoDir); + yield* runGit(repoDir, ["checkout", "-b", "feature/lookup-after-create"]); + const remoteDir = yield* createBareRemote(); + yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); + NodeFS.writeFileSync(NodePath.join(repoDir, "lookup.txt"), "lookup\n"); + yield* runGit(repoDir, ["add", "lookup.txt"]); + yield* runGit(repoDir, ["commit", "-m", "Lookup after create"]); + yield* runGit(repoDir, ["push", "-u", "origin", "feature/lookup-after-create"]); + + const { service: github } = createFakeSourceControlProvider(); + let created = false; + const { manager } = yield* makeManager({ + sourceControlProvider: { + ...github, + createChangeRequest: (input) => + github.createChangeRequest(input).pipe( + Effect.tap(() => + Effect.sync(() => { + created = true; + }), + ), + ), + listChangeRequests: (input) => + created + ? Effect.fail( + new SourceControlProviderFailure({ + provider: github.kind, + operation: "listChangeRequests", + cwd: input.cwd, + detail: "GitHub API rate limit exceeded.", + }), + ) + : github.listChangeRequests(input), + }, + }); + + const result = yield* runStackedAction(manager, { cwd: repoDir, action: "create_pr" }); + + expect(created).toBe(true); + expect(result.pr).toMatchObject({ + status: "created", + headBranch: "feature/lookup-after-create", + }); + expect(result.pr.url).toBeUndefined(); + }), + ); + it.effect("returns existing PR metadata for commit/push/pr action", () => Effect.gen(function* () { const repoDir = yield* makeTempDir("t3code-git-manager-"); diff --git a/apps/server/src/git/GitManager.ts b/apps/server/src/git/GitManager.ts index 95f5187b1a303..6715f9fd65ed0 100644 --- a/apps/server/src/git/GitManager.ts +++ b/apps/server/src/git/GitManager.ts @@ -2339,7 +2339,15 @@ export const make = Effect.gen(function* () { }) .pipe(Effect.ensuring(fileSystem.remove(bodyFile).pipe(Effect.ignore))); - const created = yield* findOpenPr(cwd, headContext); + // The PR already exists at this point, so a failed lookup only loses its metadata. + const created = yield* findOpenPr(cwd, headContext).pipe( + Effect.catch((error) => + Effect.logWarning("GitManager.runPrStep lookup after create failed", { + provider: provider.kind, + errorTag: error._tag, + }).pipe(Effect.as(null)), + ), + ); if (!created) { return { status: "created" as const,