1import { Octokit, RestEndpointMethodTypes } from '@octokit/rest'; 2 3const octokit = new Octokit({ 4 auth: process.env.GITHUB_TOKEN, 5}); 6 7// Predefine some params used across almost all requests. 8const owner = 'expo'; 9const repo = 'expo'; 10 11/** 12 * Returns public informations about the currently authenticated (by GitHub API token) user. 13 */ 14export async function getAuthenticatedUserAsync() { 15 const { data } = await octokit.users.getAuthenticated(); 16 return data; 17} 18 19/** 20 * Requests for the pull request object. 21 */ 22export async function getPullRequestAsync(pull_number: number): Promise<PullRequest> { 23 const { data } = await octokit.pulls.get({ 24 owner, 25 repo, 26 pull_number, 27 }); 28 return data; 29} 30 31/** 32 * Gets a list of reviews left in the pull request with given ID. 33 */ 34export async function listPullRequestReviewsAsync( 35 pull_number: number 36): Promise<PullRequestReview[]> { 37 const { data } = await octokit.pulls.listReviews({ 38 owner, 39 repo, 40 pull_number, 41 }); 42 return data; 43} 44 45/** 46 * Creates pull request review. By default the review is pending which needs to be submitted in order to be visible for other users. 47 * Provide `event` option to create and submit at once. 48 */ 49export async function createPullRequestReviewAsync<T>( 50 pull_number: number, 51 options?: T 52): Promise<PullRequestReview> { 53 const { data } = await octokit.pulls.createReview({ 54 owner, 55 repo, 56 pull_number, 57 ...options, 58 }); 59 return data; 60} 61 62/** 63 * Updates pull request review with a new main comment. 64 */ 65export async function updatePullRequestReviewAsync( 66 pull_number: number, 67 review_id: number, 68 body: string 69) { 70 const { data } = await octokit.pulls.updateReview({ 71 owner, 72 repo, 73 pull_number, 74 review_id, 75 body, 76 }); 77 return data; 78} 79 80/** 81 * Gets a list of comments in review. 82 */ 83export async function listPullRequestReviewCommentsAsync(pull_number: number, review_id: number) { 84 const { data } = await octokit.pulls.listReviewComments({ 85 owner, 86 repo, 87 pull_number, 88 review_id, 89 }); 90 return data; 91} 92 93/** 94 * Deletes a comment left under pull request review. 95 */ 96export async function deletePullRequestReviewCommentAsync(comment_id: number) { 97 const { data } = await octokit.pulls.deleteReviewComment({ 98 owner, 99 repo, 100 comment_id, 101 }); 102 return data; 103} 104 105/** 106 * Deletes all comments from given review. 107 */ 108export async function deleteAllPullRequestReviewCommentsAsync( 109 pull_number: number, 110 review_id: number 111) { 112 const comments = await listPullRequestReviewCommentsAsync(pull_number, review_id); 113 114 await Promise.all( 115 comments 116 .filter((comment) => comment.pull_request_review_id === review_id) 117 .map((comment) => deletePullRequestReviewCommentAsync(comment.id)) 118 ); 119} 120 121/** 122 * Requests given users to review the pull request. 123 * If the user already reviewed the PR, it resets his review state. 124 */ 125export async function requestPullRequestReviewersAsync(pull_number: number, reviewers: string[]) { 126 const { data } = await octokit.pulls.requestReviewers({ 127 owner, 128 repo, 129 pull_number, 130 reviewers, 131 }); 132 return data; 133} 134 135/** 136 * Adds labels to the issue. Throws an error when any of given labels doesn't exist. 137 */ 138export async function addIssueLabelsAsync(issue_number: number, labels: string[]) { 139 const { data } = await octokit.issues.addLabels({ 140 owner, 141 repo, 142 issue_number, 143 labels, 144 }); 145 return data; 146} 147 148/** 149 * Removes single label from the issue. 150 * Throws an error when given label doesn't exist and when the label isn't added. 151 */ 152export async function removeIssueLabelAsync(issue_number: number, name: string) { 153 const { data } = await octokit.issues.removeLabel({ 154 owner, 155 repo, 156 issue_number, 157 name, 158 }); 159 return data; 160} 161 162// Octokit's types are autogenerated and so inconvenient to use if you want to refer to them. 163// We re-export some of them to make it easier. 164export type PullRequestReviewEvent = 'COMMENT' | 'APPROVE' | 'REQUEST_CHANGES'; 165export type PullRequest = RestEndpointMethodTypes['pulls']['get']['response']['data']; 166export type PullRequestReview = RestEndpointMethodTypes['pulls']['getReview']['response']['data']; 167