From 23ef147f92bf2d823f5515f1477c56c6d984f60c Mon Sep 17 00:00:00 2001 From: whilefoo Date: Thu, 23 Nov 2023 20:25:20 +0100 Subject: [PATCH 1/2] feat: replace issue helpers with paginate --- src/helpers/issue.ts | 320 ++++++++++++++++--------------------------- 1 file changed, 116 insertions(+), 204 deletions(-) diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index 2e9422dae..481da2af9 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -7,46 +7,18 @@ import { StreamlinedComment, UserType, } from "../types"; -import { checkRateLimitGit } from "../utils"; import { LogReturn } from "../adapters/supabase"; import { Payload, Context } from "../types"; type PromiseType = T extends Promise ? U : never; async function getAllIssueEvents(context: Context) { - type Event = PromiseType>["data"][0]; + if (!context.payload.issue) return; - const payload = context.event.payload as Payload; - if (!payload.issue) return; - - let shouldFetch = true; - let page = 1; - - const events = [] as Event[]; - - while (shouldFetch) { - // Fetch issue events - - const repo = payload.repository.name; - const owner = payload.repository.owner.login; - - const response = await context.event.octokit.issues.listEvents({ - owner: owner, - repo: repo, - issue_number: payload.issue.number, - per_page: 100, - page: page, - }); - - await checkRateLimitGit(response?.headers); - - if (response.data.length > 0) { - events.push(...(response.data as Event[])); - page++; - } else { - shouldFetch = false; - } - } + const events = await context.octokit.paginate(context.octokit.issues.listEvents, { + ...context.event.issue(), + per_page: 100, + }); return events; } @@ -58,7 +30,7 @@ export async function getAllLabeledEvents(context: Context) { } export async function clearAllPriceLabelsOnIssue(context: Context) { - const payload = context.event.payload as Payload; + const payload = context.payload; if (!payload.issue) return; const labels = payload.issue.labels; @@ -68,9 +40,7 @@ export async function clearAllPriceLabelsOnIssue(context: Context) { // try { await context.event.octokit.issues.removeLabel({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: payload.issue.number, + ...context.event.issue(), name: issuePrices[0].name, }); // } catch (e: unknown) { @@ -79,16 +49,14 @@ export async function clearAllPriceLabelsOnIssue(context: Context) { } export async function addLabelToIssue(context: Context, labelName: string) { - const payload = context.event.payload as Payload; + const payload = context.payload; if (!payload.issue) { throw context.logger.error("Issue object is null"); } try { - await context.event.octokit.issues.addLabels({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: payload.issue.number, + await context.octokit.issues.addLabels({ + ...context.event.issue(), labels: [labelName], }); } catch (e: unknown) { @@ -104,8 +72,8 @@ async function listIssuesAndPullsForRepo( sort: "created" | "updated" | "comments" = "created", direction: "desc" | "asc" = "desc" ) { - const payload = context.event.payload as Payload; - const response = await context.event.octokit.issues.listForRepo({ + const payload = context.payload; + const response = await context.octokit.issues.listForRepo({ owner: payload.repository.owner.login, repo: payload.repository.name, state, @@ -115,8 +83,6 @@ async function listIssuesAndPullsForRepo( direction, }); - await checkRateLimitGit(response.headers); - if (response.status === 200) { return response.data; } else { @@ -124,22 +90,22 @@ async function listIssuesAndPullsForRepo( } } -export async function listAllIssuesAndPullsForRepo(context: Context, state: "open" | "closed" | "all") { - const issuesArr = [] as Issue[]; - const perPage = 100; - let fetchDone = false; - let curPage = 1; - while (!fetchDone) { - const issues = (await listIssuesAndPullsForRepo(context, state, perPage, curPage)) as Issue[]; - - // push the objects to array - issuesArr.push(...issues); - - if (issues.length < perPage) fetchDone = true; - else curPage++; - } - - return issuesArr; +export async function listAllIssuesAndPullsForRepo( + context: Context, + state: "open" | "closed" | "all", + sort: "created" | "updated" | "comments" = "created", + direction: "desc" | "asc" = "desc" +) { + const payload = context.payload; + const issues = (await context.octokit.paginate(context.octokit.issues.listForRepo, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + sort, + direction, + per_page: 100, + })) as Issue[]; + return issues; } export async function addCommentToIssue(context: Context, message: HandlerReturnValuesNoVoid, issueNumber: number) { @@ -154,9 +120,9 @@ export async function addCommentToIssue(context: Context, message: HandlerReturn comment = comment.concat(metadataSerializedAsComment); } - const payload = context.event.payload as Payload; + const payload = context.payload; try { - await context.event.octokit.issues.createComment({ + await context.octokit.issues.createComment({ owner: payload.repository.owner.login, repo: payload.repository.name, issue_number: issueNumber, @@ -183,8 +149,8 @@ export async function getIssueDescription( issueNumber: number, format: "raw" | "html" | "text" = "raw" ): Promise { - const payload = context.event.payload as Payload; - const response = await context.event.octokit.rest.issues.get({ + const payload = context.payload; + const response = await context.octokit.rest.issues.get({ owner: payload.repository.owner.login, repo: payload.repository.name, issue_number: issueNumber, @@ -193,8 +159,6 @@ export async function getIssueDescription( }, }); - await checkRateLimitGit(response?.headers); - let result = response.data.body; if (format === "html") { @@ -215,72 +179,36 @@ export async function getAllIssueComments( issueNumber: number, format: "raw" | "html" | "text" | "full" = "raw" ): Promise { - const payload = context.event.payload as Payload; - const result: Comment[] = []; - let shouldFetch = true; - let page_number = 1; - try { - while (shouldFetch) { - const response = await context.event.octokit.rest.issues.listComments({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: issueNumber, - per_page: 100, - page: page_number, - mediaType: { - format, - }, - }); + const payload = context.payload; - await checkRateLimitGit(response?.headers); - - // Fixing infinite loop here, it keeps looping even when its an empty array - if (response?.data?.length > 0) { - response.data.forEach((item) => { - result.push(item as Comment); - }); - page_number++; - } else { - shouldFetch = false; - } - } - } catch (e: unknown) { - shouldFetch = false; - } + const comments = (await context.octokit.paginate(context.octokit.rest.issues.listComments, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + issue_number: issueNumber, + per_page: 100, + mediaType: { + format, + }, + })) as Comment[]; - return result; + return comments; } export async function getAllIssueAssignEvents(context: Context, issueNumber: number): Promise { - const payload = context.event.payload as Payload; - const result: AssignEvent[] = []; - let shouldFetch = true; - let page_number = 1; - try { - while (shouldFetch) { - const response = await context.event.octokit.rest.issues.listEvents({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: issueNumber, - per_page: 100, - page: page_number, - }); - - await checkRateLimitGit(response?.headers); + const payload = context.payload; - // Fixing infinite loop here, it keeps looping even when its an empty array - if (response?.data?.length > 0) { - response.data.filter((item) => item.event === "assigned").forEach((item) => result?.push(item as AssignEvent)); - page_number++; - } else { - shouldFetch = false; - } - } - } catch (e: unknown) { - shouldFetch = false; - } + const events = (await context.octokit.paginate( + context.octokit.issues.listEvents, + { + owner: payload.repository.owner.login, + repo: payload.repository.name, + issue_number: issueNumber, + per_page: 100, + }, + (response) => response.data.filter((item) => item.event === "assigned") + )) as AssignEvent[]; - return result.sort((a, b) => (new Date(a.created_at) > new Date(b.created_at) ? -1 : 1)); + return events.sort((a, b) => (new Date(a.created_at) > new Date(b.created_at) ? -1 : 1)); } export async function checkUserPermissionForRepoAndOrg(context: Context, username: string): Promise { @@ -292,9 +220,9 @@ export async function checkUserPermissionForRepoAndOrg(context: Context, usernam } async function checkUserPermissionForRepo(context: Context, username: string): Promise { - const payload = context.event.payload as Payload; + const payload = context.payload; try { - const res = await context.event.octokit.rest.repos.checkCollaborator({ + const res = await context.octokit.rest.repos.checkCollaborator({ owner: payload.repository.owner.login, repo: payload.repository.name, username, @@ -308,7 +236,7 @@ async function checkUserPermissionForRepo(context: Context, username: string): P } async function checkUserPermissionForOrg(context: Context, username: string): Promise { - const payload = context.event.payload as Payload; + const payload = context.payload; if (!payload.organization) return false; try { @@ -328,7 +256,7 @@ export async function isUserAdminOrBillingManager( context: Context, username: string ): Promise<"admin" | "billing_manager" | false> { - const payload = context.event.payload as Payload; + const payload = context.payload; const isAdmin = await checkIfIsAdmin(); if (isAdmin) return "admin"; @@ -338,7 +266,7 @@ export async function isUserAdminOrBillingManager( return false; async function checkIfIsAdmin() { - const response = await context.event.octokit.rest.repos.getCollaboratorPermissionLevel({ + const response = await context.octokit.rest.repos.getCollaboratorPermissionLevel({ owner: payload.repository.owner.login, repo: payload.repository.name, username, @@ -352,7 +280,7 @@ export async function isUserAdminOrBillingManager( async function checkIfIsBillingManager() { if (!payload.organization) throw context.logger.error(`No organization found in payload!`); - const { data: membership } = await context.event.octokit.rest.orgs.getMembershipForUser({ + const { data: membership } = await context.octokit.rest.orgs.getMembershipForUser({ org: payload.organization.login, username: payload.repository.owner.login, }); @@ -367,9 +295,9 @@ export async function isUserAdminOrBillingManager( } export async function addAssignees(context: Context, issue: number, assignees: string[]) { - const payload = context.event.payload as Payload; + const payload = context.payload; try { - await context.event.octokit.rest.issues.addAssignees({ + await context.octokit.rest.issues.addAssignees({ owner: payload.repository.owner.login, repo: payload.repository.name, issue_number: issue, @@ -381,14 +309,14 @@ export async function addAssignees(context: Context, issue: number, assignees: s } export async function deleteLabel(context: Context, label: string) { - const payload = context.event.payload as Payload; + const payload = context.payload; try { - const response = await context.event.octokit.rest.search.issuesAndPullRequests({ + const response = await context.octokit.rest.search.issuesAndPullRequests({ q: `repo:${payload.repository.owner.login}/${payload.repository.name} label:"${label}" state:open`, }); if (response.data.items.length === 0) { //remove label - await context.event.octokit.rest.issues.deleteLabel({ + await context.octokit.rest.issues.deleteLabel({ owner: payload.repository.owner.login, repo: payload.repository.name, name: label, @@ -400,14 +328,14 @@ export async function deleteLabel(context: Context, label: string) { } export async function removeLabel(context: Context, name: string) { - const payload = context.event.payload as Payload; + const payload = context.payload; if (!payload.issue) { context.logger.debug("Invalid issue object"); return; } try { - await context.event.octokit.issues.removeLabel({ + await context.octokit.issues.removeLabel({ owner: payload.repository.owner.login, repo: payload.repository.name, issue_number: payload.issue.number, @@ -419,31 +347,26 @@ export async function removeLabel(context: Context, name: string) { } export async function getAllPullRequests(context: Context, state: "open" | "closed" | "all" = "open") { - type Pulls = PromiseType>["data"][0]; - const prArr = [] as Pulls[]; - let fetchDone = false; - const perPage = 100; - let curPage = 1; - while (!fetchDone) { - const prs = await getPullRequests(context, state, perPage, curPage); - - // push the objects to array - prArr.push(...prs); - - if (prs.length < perPage) fetchDone = true; - else curPage++; - } - return prArr; + const payload = context.payload; + + const pulls = await context.octokit.paginate(context.octokit.rest.pulls.list, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + per_page: 100, + }); + + return pulls; } -// Use `context.octokit.rest` to get the pull requests for the repository + async function getPullRequests( context: Context, state: "open" | "closed" | "all" = "open", per_page: number, page: number ) { - const payload = context.event.payload as Payload; - const { data: pulls } = await context.event.octokit.rest.pulls.list({ + const payload = context.payload; + const { data: pulls } = await context.octokit.rest.pulls.list({ owner: payload.repository.owner.login, repo: payload.repository.name, state, @@ -454,9 +377,9 @@ async function getPullRequests( } export async function closePullRequest(context: Context, pull_number: number) { - const payload = context.event.payload as Payload; + const payload = context.payload as Payload; try { - await context.event.octokit.rest.pulls.update({ + await context.octokit.rest.pulls.update({ owner: payload.repository.owner.login, repo: payload.repository.name, pull_number, @@ -472,21 +395,18 @@ export async function getAllPullRequestReviews( pull_number: number, format: "raw" | "html" | "text" | "full" = "raw" ) { - type Reviews = PromiseType>["data"][0]; - const prArr = [] as Reviews[]; - let fetchDone = false; - const perPage = 100; - let curPage = 1; - while (!fetchDone) { - const prs = await getPullRequestReviews(context, pull_number, perPage, curPage, format); - - // push the objects to array - prArr.push(...prs); - - if (prs.length < perPage) fetchDone = true; - else curPage++; - } - return prArr; + const payload = context.payload; + const reviews = await context.octokit.paginate(context.octokit.rest.pulls.listReviews, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + pull_number, + per_page: 100, + mediaType: { + format, + }, + }); + + return reviews; } async function getPullRequestReviews( @@ -496,9 +416,9 @@ async function getPullRequestReviews( page: number, format: "raw" | "html" | "text" | "full" = "raw" ) { - const payload = context.event.payload as Payload; + const payload = context.payload; try { - const { data: reviews } = await context.event.octokit.rest.pulls.listReviews({ + const { data: reviews } = await context.octokit.rest.pulls.listReviews({ owner: payload.repository.owner.login, repo: payload.repository.name, pull_number, @@ -517,7 +437,7 @@ async function getPullRequestReviews( export async function getReviewRequests(context: Context, pull_number: number, owner: string, repo: string) { try { - const response = await context.event.octokit.pulls.listRequestedReviewers({ + const response = await context.octokit.pulls.listRequestedReviewers({ owner: owner, repo: repo, pull_number: pull_number, @@ -528,11 +448,12 @@ export async function getReviewRequests(context: Context, pull_number: number, o return null; } } + // Get issues by issue number export async function getIssueByNumber(context: Context, issueNumber: number) { - const payload = context.event.payload as Payload; + const payload = context.payload; try { - const { data: issue } = await context.event.octokit.rest.issues.get({ + const { data: issue } = await context.octokit.rest.issues.get({ owner: payload.repository.owner.login, repo: payload.repository.name, issue_number: issueNumber, @@ -545,10 +466,8 @@ export async function getIssueByNumber(context: Context, issueNumber: number) { } export async function getPullByNumber(context: Context, pull: number) { - // const runtime = Runtime.getState(); - - const payload = context.event.payload as Payload; - const response = await context.event.octokit.rest.pulls.get({ + const payload = context.payload; + const response = await context.octokit.rest.pulls.get({ owner: payload.repository.owner.login, repo: payload.repository.name, pull_number: pull, @@ -558,27 +477,20 @@ export async function getPullByNumber(context: Context, pull: number) { // Get issues assigned to a username export async function getAssignedIssues(context: Context, username: string) { - type Issues = PromiseType>["data"][0]; - const issuesArr = [] as Issues[]; - let fetchDone = false; - const perPage = 100; - let curPage = 1; - while (!fetchDone) { - const issues = await listIssuesAndPullsForRepo(context, IssueType.OPEN, perPage, curPage); - - // push the objects to array - issuesArr.push(...issues); - - if (issues.length < perPage) fetchDone = true; - else curPage++; - } - - // get only issues assigned to username - const assigned_issues = issuesArr.filter( - (issue) => !issue.pull_request && issue.assignee && issue.assignee.login === username - ); + const payload = context.payload; + const issues = (await context.octokit.paginate( + context.octokit.issues.listForRepo, + { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state: IssueType.OPEN, + per_page: 1000, + }, + ({ data: issues }) => + issues.filter((issue) => !issue.pull_request && issue.assignee && issue.assignee.login === username) + )) as Issue[]; - return assigned_issues; + return issues; } export async function getOpenedPullRequestsForAnIssue(context: Context, issueNumber: number, userName: string) { From b700ce5ee8045ab4884e4f16283711c8bfabbfb2 Mon Sep 17 00:00:00 2001 From: whilefoo Date: Sat, 25 Nov 2023 18:30:01 +0100 Subject: [PATCH 2/2] feat: add paginate and catch everywhere --- .../issue/get-collaborator-ids-for-repo.ts | 36 +- src/handlers/wildcard/unassign/unassign.ts | 61 ++-- src/helpers/issue.ts | 308 ++++++++++-------- 3 files changed, 211 insertions(+), 194 deletions(-) diff --git a/src/handlers/comment/handlers/issue/get-collaborator-ids-for-repo.ts b/src/handlers/comment/handlers/issue/get-collaborator-ids-for-repo.ts index 751e1c674..ec59fb29d 100644 --- a/src/handlers/comment/handlers/issue/get-collaborator-ids-for-repo.ts +++ b/src/handlers/comment/handlers/issue/get-collaborator-ids-for-repo.ts @@ -1,31 +1,17 @@ -import { Context, Payload, User } from "../../../../types"; +import { Context, User } from "../../../../types"; export async function getCollaboratorsForRepo(context: Context): Promise { - const payload = context.event.payload as Payload; - const collaboratorUsers: User[] = []; + const payload = context.payload; try { - let page = 1; - let shouldFetch = true; - - while (shouldFetch) { - const res = await context.event.octokit.rest.repos.listCollaborators({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - per_page: 100, - page: page, - }); - - if (res.data.length > 0) { - res.data.forEach((collaborator) => collaboratorUsers.push(collaborator as User)); - page++; - } else { - shouldFetch = false; - } - } - } catch (e: unknown) { - context.logger.error("Fetching collaborator IDs for repo failed!", e); + const collaboratorUsers = (await context.octokit.paginate(context.octokit.rest.repos.listCollaborators, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + per_page: 100, + })) as User[]; + return collaboratorUsers; + } catch (err: unknown) { + context.logger.error("Failed to fetch lists of collaborators", err); + return []; } - - return collaboratorUsers; } diff --git a/src/handlers/wildcard/unassign/unassign.ts b/src/handlers/wildcard/unassign/unassign.ts index 23e9d3539..b0dba8538 100644 --- a/src/handlers/wildcard/unassign/unassign.ts +++ b/src/handlers/wildcard/unassign/unassign.ts @@ -310,55 +310,40 @@ function getActiveAssigneesInDisqualifyDuration( } async function getAllEvents({ context, owner, repo, issueNumber }: GetAllEvents) { - let allEvents: IssuesListEventsResponseData = []; - let page = 1; - let events = await context.event.octokit.issues.listEvents({ - owner, - repo, - issue_number: issueNumber, - per_page: 100, - page: page, - }); - - while (events.data.length > 0) { - allEvents = allEvents.concat(events.data.filter(isCorrectType) as IssuesListEventsResponseData); - - events = await context.event.octokit.issues.listEvents({ - owner, - repo, - issue_number: issueNumber, - per_page: 100, - page: ++page, - }); + try { + const events = (await context.octokit.paginate( + context.octokit.rest.issues.listEvents, + { + owner, + repo, + issue_number: issueNumber, + per_page: 100, + }, + (response) => response.data.filter((event) => isCorrectType(event as IssuesListEventsResponseData[0])) + )) as IssuesListEventsResponseData; + return events; + } catch (err: unknown) { + context.logger.error("Failed to fetch lists of events", err); + return []; } - return allEvents; } async function getAllCommitsFromPullRequest({ context, owner, repo, pullNumber }: GetAllCommits) { - let allCommits = [] as Commit[]; - let commitPage = 1; - let hasMoreCommits = true; - - while (hasMoreCommits) { - const commits = await context.event.octokit.pulls.listCommits({ + try { + const commits = (await context.octokit.paginate(context.octokit.pulls.listCommits, { owner, repo, pull_number: pullNumber, per_page: 100, - page: commitPage, - }); - - if (commits.data.length === 0) { - hasMoreCommits = false; - } else { - allCommits = allCommits.concat(commits.data as Commit[]); - commitPage++; - } + })) as Commit[]; + return commits; + } catch (err: unknown) { + context.logger.error("Failed to fetch lists of commits", err); + return []; } - return allCommits; } -function isCorrectType(event: any): event is IssuesListEventsResponseData { +function isCorrectType(event: IssuesListEventsResponseData[0]) { return event && typeof event.id === "number"; } diff --git a/src/helpers/issue.ts b/src/helpers/issue.ts index 481da2af9..555492fdf 100644 --- a/src/helpers/issue.ts +++ b/src/helpers/issue.ts @@ -15,12 +15,16 @@ type PromiseType = T extends Promise ? U : never; async function getAllIssueEvents(context: Context) { if (!context.payload.issue) return; - const events = await context.octokit.paginate(context.octokit.issues.listEvents, { - ...context.event.issue(), - per_page: 100, - }); - - return events; + try { + const events = await context.octokit.paginate(context.octokit.issues.listEvents, { + ...context.event.issue(), + per_page: 100, + }); + return events; + } catch (err: unknown) { + context.logger.error("Failed to fetch lists of events", err); + return []; + } } export async function getAllLabeledEvents(context: Context) { @@ -38,14 +42,14 @@ export async function clearAllPriceLabelsOnIssue(context: Context) { if (!issuePrices.length) return; - // try { - await context.event.octokit.issues.removeLabel({ - ...context.event.issue(), - name: issuePrices[0].name, - }); - // } catch (e: unknown) { - // context.logger.debug("Clearing all price labels failed!", e); - // } + try { + await context.event.octokit.issues.removeLabel({ + ...context.event.issue(), + name: issuePrices[0].name, + }); + } catch (e: unknown) { + context.logger.error("Clearing all price labels failed!", e); + } } export async function addLabelToIssue(context: Context, labelName: string) { @@ -60,7 +64,7 @@ export async function addLabelToIssue(context: Context, labelName: string) { labels: [labelName], }); } catch (e: unknown) { - context.logger.debug("Adding a label to issue failed!", e); + context.logger.error("Adding a label to issue failed!", e); } } @@ -73,19 +77,20 @@ async function listIssuesAndPullsForRepo( direction: "desc" | "asc" = "desc" ) { const payload = context.payload; - const response = await context.octokit.issues.listForRepo({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - state, - per_page, - page, - sort, - direction, - }); - if (response.status === 200) { + try { + const response = await context.octokit.issues.listForRepo({ + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + per_page, + page, + sort, + direction, + }); return response.data; - } else { + } catch (err: unknown) { + context.logger.error("Failed to fetch lists of issues", err); return []; } } @@ -97,15 +102,20 @@ export async function listAllIssuesAndPullsForRepo( direction: "desc" | "asc" = "desc" ) { const payload = context.payload; - const issues = (await context.octokit.paginate(context.octokit.issues.listForRepo, { - owner: payload.repository.owner.login, - repo: payload.repository.name, - state, - sort, - direction, - per_page: 100, - })) as Issue[]; - return issues; + try { + const issues = (await context.octokit.paginate(context.octokit.issues.listForRepo, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + sort, + direction, + per_page: 100, + })) as Issue[]; + return issues; + } catch (err: unknown) { + context.logger.error("Listing all issues and pulls failed!", err); + return []; + } } export async function addCommentToIssue(context: Context, message: HandlerReturnValuesNoVoid, issueNumber: number) { @@ -140,7 +150,7 @@ export async function upsertLastCommentToIssue(context: Context, issue_number: n if (comments.length > 0 && comments[comments.length - 1].body !== commentBody) await addCommentToIssue(context, commentBody, issue_number); } catch (e: unknown) { - context.logger.debug("Upserting last comment failed!", e); + context.logger.error("Upserting last comment failed!", e); } } @@ -150,28 +160,29 @@ export async function getIssueDescription( format: "raw" | "html" | "text" = "raw" ): Promise { const payload = context.payload; - const response = await context.octokit.rest.issues.get({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: issueNumber, - mediaType: { - format, - }, - }); - let result = response.data.body; + try { + const response = await context.octokit.rest.issues.get({ + owner: payload.repository.owner.login, + repo: payload.repository.name, + issue_number: issueNumber, + mediaType: { + format, + }, + }); - if (format === "html") { - result = response.data.body_html; - } else if (format === "text") { - result = response.data.body_text; - } + let result = response.data.body; - if (!result) { - throw context.logger.error("Issue description is empty"); - } + if (format === "html") { + result = response.data.body_html; + } else if (format === "text") { + result = response.data.body_text; + } - return result; + return result as string; + } catch (e: unknown) { + throw context.logger.error("Fetching issue description failed!", e); + } } export async function getAllIssueComments( @@ -181,34 +192,43 @@ export async function getAllIssueComments( ): Promise { const payload = context.payload; - const comments = (await context.octokit.paginate(context.octokit.rest.issues.listComments, { - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: issueNumber, - per_page: 100, - mediaType: { - format, - }, - })) as Comment[]; - - return comments; + try { + const comments = (await context.octokit.paginate(context.octokit.rest.issues.listComments, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + issue_number: issueNumber, + per_page: 100, + mediaType: { + format, + }, + })) as Comment[]; + return comments; + } catch (e: unknown) { + context.logger.error("Fetching all issue comments failed!", e); + return []; + } } export async function getAllIssueAssignEvents(context: Context, issueNumber: number): Promise { const payload = context.payload; - const events = (await context.octokit.paginate( - context.octokit.issues.listEvents, - { - owner: payload.repository.owner.login, - repo: payload.repository.name, - issue_number: issueNumber, - per_page: 100, - }, - (response) => response.data.filter((item) => item.event === "assigned") - )) as AssignEvent[]; + try { + const events = (await context.octokit.paginate( + context.octokit.issues.listEvents, + { + owner: payload.repository.owner.login, + repo: payload.repository.name, + issue_number: issueNumber, + per_page: 100, + }, + (response) => response.data.filter((item) => item.event === "assigned") + )) as AssignEvent[]; - return events.sort((a, b) => (new Date(a.created_at) > new Date(b.created_at) ? -1 : 1)); + return events.sort((a, b) => (new Date(a.created_at) > new Date(b.created_at) ? -1 : 1)); + } catch (err: unknown) { + context.logger.error("Fetching all issue assign events failed!", err); + return []; + } } export async function checkUserPermissionForRepoAndOrg(context: Context, username: string): Promise { @@ -304,7 +324,7 @@ export async function addAssignees(context: Context, issue: number, assignees: s assignees, }); } catch (e: unknown) { - context.logger.debug("Adding assignees failed!", e); + context.logger.error("Adding assignees failed!", e); } } @@ -323,7 +343,7 @@ export async function deleteLabel(context: Context, label: string) { }); } } catch (e: unknown) { - context.logger.debug("Deleting label failed!", e); + context.logger.error("Deleting label failed!", e); } } @@ -342,21 +362,25 @@ export async function removeLabel(context: Context, name: string) { name: name, }); } catch (e: unknown) { - context.logger.debug("Removing label failed!", e); + context.logger.error("Removing label failed!", e); } } export async function getAllPullRequests(context: Context, state: "open" | "closed" | "all" = "open") { const payload = context.payload; - const pulls = await context.octokit.paginate(context.octokit.rest.pulls.list, { - owner: payload.repository.owner.login, - repo: payload.repository.name, - state, - per_page: 100, - }); - - return pulls; + try { + const pulls = await context.octokit.paginate(context.octokit.rest.pulls.list, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + per_page: 100, + }); + return pulls; + } catch (err: unknown) { + context.logger.error("Fetching all pull requests failed!", err); + return []; + } } async function getPullRequests( @@ -366,14 +390,20 @@ async function getPullRequests( page: number ) { const payload = context.payload; - const { data: pulls } = await context.octokit.rest.pulls.list({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - state, - per_page, - page, - }); - return pulls; + + try { + const { data: pulls } = await context.octokit.rest.pulls.list({ + owner: payload.repository.owner.login, + repo: payload.repository.name, + state, + per_page, + page, + }); + return pulls; + } catch (err: unknown) { + context.logger.error("Fetching pull requests failed!", err); + return []; + } } export async function closePullRequest(context: Context, pull_number: number) { @@ -385,8 +415,8 @@ export async function closePullRequest(context: Context, pull_number: number) { pull_number, state: "closed", }); - } catch (e: unknown) { - context.logger.debug("Closing pull requests failed!", e); + } catch (err: unknown) { + context.logger.error("Closing pull requests failed!", err); } } @@ -396,17 +426,22 @@ export async function getAllPullRequestReviews( format: "raw" | "html" | "text" | "full" = "raw" ) { const payload = context.payload; - const reviews = await context.octokit.paginate(context.octokit.rest.pulls.listReviews, { - owner: payload.repository.owner.login, - repo: payload.repository.name, - pull_number, - per_page: 100, - mediaType: { - format, - }, - }); - return reviews; + try { + const reviews = await context.octokit.paginate(context.octokit.rest.pulls.listReviews, { + owner: payload.repository.owner.login, + repo: payload.repository.name, + pull_number, + per_page: 100, + mediaType: { + format, + }, + }); + return reviews; + } catch (err: unknown) { + context.logger.error("Fetching all pull request reviews failed!", err); + return []; + } } async function getPullRequestReviews( @@ -429,8 +464,8 @@ async function getPullRequestReviews( }, }); return reviews; - } catch (e: unknown) { - context.logger.debug("Fetching pull request reviews failed!", e); + } catch (err: unknown) { + context.logger.error("Fetching pull request reviews failed!", err); return []; } } @@ -443,8 +478,8 @@ export async function getReviewRequests(context: Context, pull_number: number, o pull_number: pull_number, }); return response.data; - } catch (e: unknown) { - context.logger.error("Could not get requested reviewers", e); + } catch (err: unknown) { + context.logger.error("Could not get requested reviewers", err); return null; } } @@ -460,37 +495,48 @@ export async function getIssueByNumber(context: Context, issueNumber: number) { }); return issue; } catch (e: unknown) { - context.logger.debug("Fetching issue failed!", e); + context.logger.error("Fetching issue failed!", e); return; } } export async function getPullByNumber(context: Context, pull: number) { const payload = context.payload; - const response = await context.octokit.rest.pulls.get({ - owner: payload.repository.owner.login, - repo: payload.repository.name, - pull_number: pull, - }); - return response.data; + + try { + const response = await context.octokit.rest.pulls.get({ + owner: payload.repository.owner.login, + repo: payload.repository.name, + pull_number: pull, + }); + return response.data; + } catch (err: unknown) { + context.logger.error("Fetching pull request failed!", err); + return; + } } // Get issues assigned to a username export async function getAssignedIssues(context: Context, username: string) { const payload = context.payload; - const issues = (await context.octokit.paginate( - context.octokit.issues.listForRepo, - { - owner: payload.repository.owner.login, - repo: payload.repository.name, - state: IssueType.OPEN, - per_page: 1000, - }, - ({ data: issues }) => - issues.filter((issue) => !issue.pull_request && issue.assignee && issue.assignee.login === username) - )) as Issue[]; - - return issues; + + try { + const issues = (await context.octokit.paginate( + context.octokit.issues.listForRepo, + { + owner: payload.repository.owner.login, + repo: payload.repository.name, + state: IssueType.OPEN, + per_page: 1000, + }, + ({ data: issues }) => + issues.filter((issue) => !issue.pull_request && issue.assignee && issue.assignee.login === username) + )) as Issue[]; + return issues; + } catch (err: unknown) { + context.logger.error("Fetching assigned issues failed!", err); + return []; + } } export async function getOpenedPullRequestsForAnIssue(context: Context, issueNumber: number, userName: string) {