From ccccf0749144bde49ad18390ad2414ef3c49badd Mon Sep 17 00:00:00 2001 From: Thomas Durieux <5577568+tdurieux@users.noreply.github.com> Date: Wed, 7 Oct 2026 11:41:48 +0000 Subject: [PATCH] fix: save renamed source together with reconnected access --- src/server/routes/github-app.ts | 5 ++++- test/app-reinstall-recovery.test.js | 14 ++++++++++++++ test/github-app.test.js | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/server/routes/github-app.ts b/src/server/routes/github-app.ts index b6edecc..5fdd784 100644 --- a/src/server/routes/github-app.ts +++ b/src/server/routes/github-app.ts @@ -208,7 +208,10 @@ router.post("/connections/migrate", async (req, res) => { if (preview === true) return res.json({ eligible: true, connection }); const filter = { _id: model._id, owner: user.id, status: model.status, source: model.source, githubAccess: model.githubAccess ? model.githubAccess : { $exists: false } }; - const change = { $set: { githubAccess: selected.binding } }; + const change = { $set: { githubAccess: selected.binding, + ...(selected.fullName && selected.fullName !== name + ? { [isRepo ? "source.repositoryName" : "source.repositoryFullName"]: selected.fullName } : {}), + } }; const result = isRepo ? await RepositoryModel.updateOne(filter, change) : await PullRequestModel.updateOne(filter, change); if (!result.modifiedCount) throw appError("connection_changed", 409); res.json({ connection }); diff --git a/test/app-reinstall-recovery.test.js b/test/app-reinstall-recovery.test.js index e3b2f63..6f3b292 100644 --- a/test/app-reinstall-recovery.test.js +++ b/test/app-reinstall-recovery.test.js @@ -57,6 +57,20 @@ for (const type of ["repository", "pull-request"]) { expect(writes[0].filter.source).to.deep.equal(model.source); expect(checks).to.deep.equal([{ url: type === "repository" ? "/repos/owner/private/commits/saved-sha" : "/repos/owner/private/pulls/7", token: "fresh-token" }]); }); + it("saves a resolved rename atomically with the binding after preview", async function () { + selected.fullName = "owner/renamed"; + await run(true); + expect(writes).to.have.length(0); + await run(); + expect(writes).to.have.length(1); + expect(writes[0].update).to.deep.equal({ $set: { + githubAccess: selected.binding, + [type === "repository" ? "source.repositoryName" : "source.repositoryFullName"]: "owner/renamed", + } }); + expect(writes[0].filter.source).to.deep.equal(model.source); + expect(writes[0].filter.githubAccess).to.deep.equal(model.githubAccess); + expect(checks.every(check => check.url.startsWith("/repos/owner/renamed/"))).to.equal(true); + }); it("rejects a replacement repository at the same name", async function () { selected.binding.repositoryId = 99; await fails("connection_changed"); expect(checks).to.have.length(0); }); diff --git a/test/github-app.test.js b/test/github-app.test.js index feaccd1..390b51a 100644 --- a/test/github-app.test.js +++ b/test/github-app.test.js @@ -543,7 +543,8 @@ describeMongo("GitHub App credential and repository integration", function () { const repaired = await PRs.findById(resource.id); expect(repaired.githubAccess.repositoryId).to.equal(42); expect(repaired.githubAccess.installationId).to.equal(4); - expect(repaired.source.repositoryFullName).to.equal("owner/old-name"); + expect(repaired.source.repositoryFullName).to.equal("owner/new-name"); + expect(repaired.source.pullRequestId).to.equal(7); expect(repaired.pullRequestId).to.equal("renamed-pr"); });