fix: recover renamed repositories by ID and hide archived actions

This commit is contained in:
Thomas Durieux committed 2026-10-07 11:10:30 +00:00
1 parent 3140ad3c45
commit a7ae790640
8 files changed
+54 -11

No files matched your search

+3 -2
View File
@@ -25,7 +25,8 @@ for (const type of ["repository", "pull-request"]) {
stub(config, "GITHUB_APP_ENABLED", true); stub(config, "GITHUB_APP_NEW_CONNECTIONS", true);
stub(utils, "getUser", async () => ({ id: owner }));
stub(utils, "handleError", error => { throw error; });
stub(app, "selectRepositoryAccess", async (id, name, connection) => {
stub(app, "selectRepositoryAccess", async (id, name, connection, repositoryId) => {
expect(repositoryId).to.equal(42);
expect([id, name, connection]).to.deep.equal(["owner", "owner/private", "github-app"]);
return selected;
});
@@ -54,7 +55,7 @@ for (const type of ["repository", "pull-request"]) {
expect(writes[0].update).to.deep.equal({ $set: { githubAccess: selected.binding } });
expect(writes[0].filter.githubAccess).to.deep.equal(model.githubAccess);
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" }]);
expect(checks).to.deep.equal([{ url: type === "repository" ? "/repositories/42/commits/saved-sha" : "/repositories/42/pulls/7", token: "fresh-token" }]);
});
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);
+28
View File
@@ -496,6 +496,34 @@ describeMongo("GitHub App credential and repository integration", function () {
expect(await Credentials.countDocuments()).to.equal(0);
expect(await Users.countDocuments()).to.equal(1);
});
it("recovers a renamed private pull request through its stable repository ID", async () => {
const PRs = require("../src/core/model/anonymizedPullRequests/anonymizedPullRequests.model").default;
await app.saveAppGrant(owner.id, data());
const resource = await PRs.create({ pullRequestId: "renamed-pr", owner: owner.id, status: "ready",
source: { repositoryFullName: "owner/old-name", pullRequestId: 7 }, options: { terms: ["owner"] },
githubAccess: { kind: "github-app", repositoryId: 42, installationId: 3, revision: "old" } });
mock(url => {
if (url.includes("/user/installations?")) return { installations: [{ id: 4, app_id: 123, account: { id: 10, login: "owner", type: "User" } }] };
if (url.includes("/user/installations/4/repositories")) return { repositories: [
{ id: 99, full_name: "owner/old-name", private: true }, { id: 42, full_name: "owner/new-name", private: true },
] };
if (url.endsWith("/repositories/42")) return { id: 42 };
if (url.endsWith("/app/installations/4")) return { app_id: 123, permissions: { contents: "read", metadata: "read" } };
if (url.endsWith("/access_tokens")) return { token: "ghs_reinstalled", expires_at: new Date(Date.now() + 3600000).toISOString() };
if (url.endsWith("/repositories/42/pulls/7")) return { number: 7 };
throw new Error("Unexpected request " + url);
});
const body = { type: "pull-request", id: resource.pullRequestId, connection: "github-app" };
expect((await request("/github/connections/migrate", { ...body, preview: true })).status).to.equal(200);
expect((await PRs.findById(resource.id)).githubAccess.installationId).to.equal(3);
expect((await request("/github/connections/migrate", body)).status).to.equal(200);
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.pullRequestId).to.equal("renamed-pr");
});
it("migrates only the owner's resource after checking its configured commit", async () => {
const Repos = require("../src/core/model/anonymizedRepositories/anonymizedRepositories.model").default;
await app.saveAppGrant(owner.id, data());
+11
View File
@@ -155,6 +155,17 @@ describe("Vue 3 UI", function () {
expect(ui.errors).to.deep.equal([]);
});
it("hides connection changes on archived resources", async function () {
ui = await browser("/connections", {
"/github/connections": { appEnabled: true, appConnected: true, oauthConnected: true,
resources: [{ type: "repository", id: "archived", connection: "github-app", status: "archived", eligible: true }] },
});
const resource = ui.window.document.querySelector(".connection-resource");
expect(resource).not.to.equal(null);
expect(resource.querySelectorAll("button")).to.have.length(0);
expect(ui.errors).to.deep.equal([]);
});
for (const connection of ["oauth", "github-app"]) {
it(`previews and saves ${connection} access with CSRF protection`, async function () {
const action = connection === "github-app" ? "Reconnect read-only access" : "Switch to read-only access";