pull-request-evaluator/lib/github-client/pr.js (154 lines of code) (raw):

/** * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const githubClient = require('../../lib/github-client/client'); const staticHelper = require('../../lib/config/statics'); const excludeHelper = require('../../lib/config/excluder'); /* Initial greet! */ async function createInitialPrComment(owner, repo, issue_number) { let body = staticHelper.getGreet(); await createPrComment(owner, repo, issue_number, body); } /* Help message */ async function createHelpPrComment(owner, repo, issue_number) { let body = staticHelper.getHelp(); await createPrComment(owner, repo, issue_number, body); } /* Create new comment in PR */ async function createPrComment(owner, repo, issue_number, body) { try { await githubClient.issues.createComment({ owner, repo, issue_number, body }); } catch (err) { console.log(err); return null; } } /* List commits from PR */ async function getAllCommitsId(owner, repo, pull_number) { const allCommits = [] let page = 1 let commits try { do { commits = await githubClient.pulls.listCommits({ owner, repo, pull_number, page }); allCommits.push(...commits.data.map(commit => commit.sha)); page++; } while (commits.data.length > 0) } catch (err) { console.log(err); return null; } return allCommits } /* The the Branch Diff */ async function getPrDiff(owner, repo, pull_request) { try { const targetBranchDiff = await githubClient.repos.compareCommits({ owner, repo, base: pull_request.data.base.sha, head: pull_request.data.head.sha }); return targetBranchDiff; } catch (err) { console.log(err); return null; } } /* Get the PR */ async function getPr(owner, repo, pull_request) { try { const pullRequest = await githubClient.rest.pulls.get({ owner, repo, pull_number: pull_request, }); return pullRequest; } catch (err) { console.log(err); return null; } } /* Load Original file and Diff */ async function getFileAndDiff(owner, repo, file, basesha) { let thisFile = { fileName: null, fileContent: null, newContent: null, fileDiff: null, diffSummary: null, changeStatus: null }; thisFile.fileName = file.filename; try { const contents = await githubClient.repos.getContent({ owner: owner, repo: repo, path: file.filename, ref: basesha }); if (contents.data != null) { if (!Array.isArray(contents.data)) { if (contents.data.type === 'file' && contents.data.content != null) { thisFile.fileContent = Buffer.from(contents.data.content, 'base64').toString(); } } } } catch (err) { /* Probably a 404, brand new file */ console.log(err); thisFile.fileContent = ""; } if (file.patch != null) { thisFile.fileDiff = file.patch; } return thisFile; } /* Get the resulting file (Original + Diff) */ async function getNewFileContent(owner, repo, file, diffsha) { let newContent = ""; try { const contents = await githubClient.repos.getContent({ owner: owner, repo: repo, path: file.filename, ref: diffsha }); if (contents.data != null) { if (!Array.isArray(contents.data)) { if (contents.data.type === 'file' && contents.data.content != null) { newContent = Buffer.from(contents.data.content, 'base64').toString(); } } } } catch (err) { console.log(err); return ""; } return newContent; } /* Load PR contents */ async function loadFullPr(owner, repo, pr_number) { let thisPr; let changeList = []; /* * We need to loop a little bit * because when we receive the * webhook, the PR is not ready for * us to consume every field. */ let targetBranchDiff; do { thisPr = await getPr(owner, repo, pr_number); targetBranchDiff = await getPrDiff(owner, repo, thisPr); } while (targetBranchDiff == null) const files = targetBranchDiff.data.files; /* Loading files */ for (const file of files) { if (await excludeHelper.filterPath(file.filename)) { thisFile = await getFileAndDiff(owner, repo, file, thisPr.data.sha); thisFile.newContent = await getNewFileContent(owner, repo, file, targetBranchDiff.data.sha); changeList.push(thisFile); } } return changeList; } module.exports.createPrComment = createPrComment; module.exports.createInitialPrComment = createInitialPrComment; module.exports.createHelpPrComment = createHelpPrComment; module.exports.getAllCommitsId = getAllCommitsId; module.exports.getPrDiff = getPrDiff; module.exports.getPr = getPr; module.exports.getFileAndDiff = getFileAndDiff; module.exports.getNewFileContent = getNewFileContent; module.exports.loadFullPr = loadFullPr;