Skip to content

Commit ddbfba3

Browse files
authored
fix(rereview): fallback to app reviewer when team request fails (#27)
If team reviewer requests fail (including aireview/ai-review alias retries), request the app user as fallback so @kodiai recheck still retriggers review without thread noise.
1 parent 71cc6f0 commit ddbfba3

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

src/handlers/mention.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ export function createMentionHandler(deps: {
588588
repo: mention.repo,
589589
prNumber: mention.prNumber,
590590
configuredTeam,
591+
fallbackReviewer: githubApp.getAppSlug(),
591592
logger,
592593
});
593594

src/handlers/rereview-team.test.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ describe("rereview-team helpers", () => {
5959
rest: {
6060
pulls: {
6161
listRequestedReviewers: async () => ({ data: { users: [], teams: [] } }),
62-
requestReviewers: async (params: { team_reviewers: string[] }) => {
63-
const slug = params.team_reviewers[0] ?? "";
62+
requestReviewers: async (params: { team_reviewers: string[]; reviewers?: string[] }) => {
63+
const slug = params.team_reviewers[0] ?? params.reviewers?.[0] ?? "";
6464
attempted.push(slug);
6565
if (slug === "aireview") {
6666
const err = new Error("Validation failed") as Error & { status: number };
@@ -83,4 +83,38 @@ describe("rereview-team helpers", () => {
8383
expect(result.requestedTeam).toBe("ai-review");
8484
expect(result.alreadyRequested).toBe(false);
8585
});
86+
87+
test("requestRereviewTeamBestEffort requests fallback reviewer when teams fail", async () => {
88+
const attemptedTeams: string[] = [];
89+
let fallbackReviewer: string | undefined;
90+
91+
await requestRereviewTeamBestEffort({
92+
octokit: {
93+
rest: {
94+
pulls: {
95+
listRequestedReviewers: async () => ({ data: { users: [], teams: [] } }),
96+
requestReviewers: async (params: { team_reviewers: string[]; reviewers?: string[] }) => {
97+
if (params.team_reviewers.length > 0) {
98+
attemptedTeams.push(params.team_reviewers[0] ?? "");
99+
const err = new Error("team failed") as Error & { status: number };
100+
err.status = 422;
101+
throw err;
102+
}
103+
fallbackReviewer = params.reviewers?.[0];
104+
return { data: {} };
105+
},
106+
},
107+
},
108+
},
109+
owner: "xbmc",
110+
repo: "kodiai",
111+
prNumber: 3,
112+
configuredTeam: "aireview",
113+
fallbackReviewer: "kodiai",
114+
logger: createNoopLogger(),
115+
});
116+
117+
expect(attemptedTeams).toEqual(["aireview", "ai-review"]);
118+
expect(fallbackReviewer).toBe("kodiai");
119+
});
86120
});

src/handlers/rereview-team.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export async function requestRereviewTeamBestEffort(options: {
3636
owner: string;
3737
repo: string;
3838
pull_number: number;
39+
reviewers?: string[];
3940
team_reviewers: string[];
4041
}) => Promise<unknown>;
4142
};
@@ -45,9 +46,10 @@ export async function requestRereviewTeamBestEffort(options: {
4546
repo: string;
4647
prNumber: number;
4748
configuredTeam: string;
49+
fallbackReviewer?: string;
4850
logger: Logger;
4951
}): Promise<{ requestedTeam?: string; alreadyRequested: boolean }> {
50-
const { octokit, owner, repo, prNumber, configuredTeam, logger } = options;
52+
const { octokit, owner, repo, prNumber, configuredTeam, fallbackReviewer, logger } = options;
5153
const candidates = buildRereviewTeamCandidates(configuredTeam);
5254
if (candidates.length === 0) return { alreadyRequested: false };
5355

@@ -100,5 +102,27 @@ export async function requestRereviewTeamBestEffort(options: {
100102
}
101103
}
102104

105+
const reviewer = (fallbackReviewer ?? "").trim();
106+
if (reviewer.length > 0) {
107+
try {
108+
await octokit.rest.pulls.requestReviewers({
109+
owner,
110+
repo,
111+
pull_number: prNumber,
112+
reviewers: [reviewer],
113+
team_reviewers: [],
114+
});
115+
logger.info(
116+
{ owner, repo, prNumber, reviewer },
117+
"Requested fallback reviewer after rereview team request failure",
118+
);
119+
} catch (err) {
120+
logger.warn(
121+
{ err, owner, repo, prNumber, reviewer },
122+
"Failed to request fallback reviewer after rereview team request failure",
123+
);
124+
}
125+
}
126+
103127
return { alreadyRequested: false };
104128
}

src/handlers/review.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ export function createReviewHandler(deps: {
296296
repo: apiRepo,
297297
prNumber: pr.number,
298298
configuredTeam: config.review.uiRereviewTeam,
299+
fallbackReviewer: githubApp.getAppSlug(),
299300
logger,
300301
});
301302
}

0 commit comments

Comments
 (0)