Skip to content

Commit

Permalink
fix: use paginate and use correct delay tolerance
Browse files Browse the repository at this point in the history
  • Loading branch information
jordan-ae committed Nov 6, 2024
1 parent f496b20 commit fadfb4e
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
7 changes: 4 additions & 3 deletions src/handlers/shared/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,16 @@ async function fetchUserIds(context: Context, username: string[]) {
}

async function handleTaskLimitChecks(username: string, context: Context, logger: Context["logger"], sender: string) {
const openedPullRequests = await getAvailableOpenedPullRequests(context, username);
const { approved, changes } = await getAvailableOpenedPullRequests(context, username);
const assignedIssues = await getAssignedIssues(context, username);
const { limit } = await getUserRoleAndTaskLimit(context, username);
const adjustedAssignedIssues = assignedIssues.length - approved.length + changes.length;

// check for max and enforce max
if (Math.abs(assignedIssues.length - openedPullRequests.length) >= limit) {
if (Math.abs(adjustedAssignedIssues) >= limit) {
logger.error(username === sender ? "You have reached your max task limit" : `${username} has reached their max task limit`, {
assignedIssues: assignedIssues.length,
openedPullRequests: openedPullRequests.length,
openedPullRequests: adjustedAssignedIssues,
limit,
});

Expand Down
61 changes: 52 additions & 9 deletions src/utils/issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export async function addAssignees(context: Context, issueNo: number, assignees:
async function getAllPullRequests(context: Context, state: Endpoints["GET /repos/{owner}/{repo}/pulls"]["parameters"]["state"] = "open", username: string) {
const { payload } = context;
const query: RestEndpointMethodTypes["search"]["issuesAndPullRequests"]["parameters"] = {
q: `org:${payload.repository.owner.login} author:${username} state:${state}`,
q: `org:${payload.repository.owner.login} author:${username} state:${state} is:pr`,
per_page: 100,
order: "desc",
sort: "created",
Expand Down Expand Up @@ -224,6 +224,24 @@ export async function getAllPullRequestReviews(context: Context, pullNumber: num
}
}

async function getReviewRequestsTimeline(context: Context, pullNumber: number, owner: string, repo: string) {
try {
const events = (await context.octokit.paginate(`GET /repos/${owner}/${repo}/issues/${pullNumber}/timeline`, {
owner,
repo,
issue_number: pullNumber,
})) as {
created_at: string | number | Date;
event: string;
}[];

return events.filter((event: { event: string }) => event.event === "review_requested" || event.event === "review_request_removed");
} catch (error) {
console.error("Error fetching review request timeline events:", error);
return [];
}
}

export function getOwnerRepoFromHtmlUrl(url: string) {
const parts = url.split("/");
if (parts.length < 5) {
Expand All @@ -237,29 +255,54 @@ export function getOwnerRepoFromHtmlUrl(url: string) {

export async function getAvailableOpenedPullRequests(context: Context, username: string) {
const { reviewDelayTolerance } = context.config;
if (!reviewDelayTolerance) return [];
if (!reviewDelayTolerance) return { approved: [], changes: [] };

const openedPullRequests = await getOpenedPullRequestsForUser(context, username);
const result: (typeof openedPullRequests)[number][] = [];
const approved = [] as unknown[];
const changes = [] as unknown[];

for (let i = 0; openedPullRequests && i < openedPullRequests.length; i++) {
const openedPullRequest = openedPullRequests[i];
if (!openedPullRequest) continue;
const { owner, repo } = getOwnerRepoFromHtmlUrl(openedPullRequest.html_url);
const reviews = await getAllPullRequestReviews(context, openedPullRequest.number, owner, repo);

if (reviews.length > 0) {
const approvedReviews = reviews.find((review) => review.state === "APPROVED");
if (approvedReviews) {
result.push(openedPullRequest);
// Determine the latest review state
const latestReview = reviews[reviews.length - 1];
const latestReviewState = latestReview?.state;

if (latestReviewState === "APPROVED") {
approved.push(openedPullRequest);
continue;
}

if (latestReviewState === "CHANGES_REQUESTED") {
changes.push(openedPullRequest);

// Track the time of the last "CHANGES_REQUESTED"s
const lastChangesRequestedTime = latestReview.submitted_at ? new Date(latestReview.submitted_at).getTime() : null;

// Fetch timeline or comments to check if reviewer has been re-requested
const reviewRequests = await getReviewRequestsTimeline(context, openedPullRequest.number, owner, repo);

// Find if any review request was made after the last changes requested
const isReviewRequestedAfterChanges = lastChangesRequestedTime
? reviewRequests.some((request) => new Date(request.created_at).getTime() > lastChangesRequestedTime)
: false;

if (isReviewRequestedAfterChanges) {
approved.push(openedPullRequest);
changes.pop();
continue;
}
}

if (reviews.length === 0 && new Date().getTime() - new Date(openedPullRequest.created_at).getTime() >= getTimeValue(reviewDelayTolerance)) {
result.push(openedPullRequest);
approved.push(openedPullRequest);
}
}
return result;

return { approved, changes };
}

export function getTimeValue(timeString: string): number {
Expand Down

0 comments on commit fadfb4e

Please sign in to comment.