|
| 1 | +/** |
| 2 | + * Create or modify a GitHub comment using the mongodb-drivers-comment-bot. |
| 3 | + */ |
| 4 | +import * as fs from "fs"; |
| 5 | +import * as process from "process"; |
| 6 | +import { program } from 'commander'; |
| 7 | +import { App } from "octokit"; |
| 8 | + |
| 9 | +const appId = process.env.GITHUB_APP_ID; |
| 10 | +const privateKey = process.env.GITHUB_SECRET_KEY.replace(/\\n/g, '\n'); |
| 11 | +if (appId == '' || privateKey == '') { |
| 12 | + console.error("Missing GitHub App auth information"); |
| 13 | + process.exit(1) |
| 14 | +} |
| 15 | + |
| 16 | +// Handle cli. |
| 17 | +program |
| 18 | + .version('1.0.0', '-v, --version') |
| 19 | + .usage('[OPTIONS]...') |
| 20 | + .requiredOption('-o, --repo-owner <owner>', 'The owner of the repo (e.g. mongodb).') |
| 21 | + .requiredOption('-n, --repo-name <name>', 'The name of the repo (e.g. mongo-go-driver).') |
| 22 | + .requiredOption('-m, --body-match <string>', 'The comment body to match') |
| 23 | + .requiredOption('-c, --comment-path <path>', 'The path to the comment body file') |
| 24 | + .requiredOption('-h, --head-sha <sha>', 'The sha of the head commit') |
| 25 | + .parse(process.argv); |
| 26 | + |
| 27 | +const options = program.opts(); |
| 28 | +const { |
| 29 | + repoOwner: owner, |
| 30 | + repoName: repo, |
| 31 | + bodyMatch, |
| 32 | + commentPath, |
| 33 | + headSha: targetSha |
| 34 | + } = options; |
| 35 | +const bodyText = fs.readFileSync(commentPath, { encoding: 'utf8' }); |
| 36 | + |
| 37 | +// Set up the app. |
| 38 | +const installId = process.env['GITHUB_APP_INSTALL_ID_' + owner.toUpperCase()]; |
| 39 | +if (installId == '') { |
| 40 | + console.error(`Missing install id for ${owner}`) |
| 41 | + process.exit(1) |
| 42 | +} |
| 43 | +const app = new App({ appId, privateKey }); |
| 44 | +const octokit = await app.getInstallationOctokit(installId); |
| 45 | +const headers = { |
| 46 | + "x-github-api-version": "2022-11-28", |
| 47 | +}; |
| 48 | + |
| 49 | +// Find the matching pull request. |
| 50 | +let resp = await octokit.request("GET /repos/{owner}/{repo}/pulls?state=open&per_page=100", { |
| 51 | + owner, |
| 52 | + repo, |
| 53 | + headers |
| 54 | +}); |
| 55 | +const issue = resp.data.find(pr => pr.head.sha === targetSha); |
| 56 | +if (issue == null) { |
| 57 | + console.error(`ERROR: Could not find matching pull request for sha ${targetSha}`) |
| 58 | + process.exit(1) |
| 59 | +} |
| 60 | +const { number: issueNumber } = issue |
| 61 | + |
| 62 | +// Find a matching comment if it exists, and update it. |
| 63 | +resp = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}/comments", { |
| 64 | + owner, |
| 65 | + repo, |
| 66 | + issue_number: issueNumber, |
| 67 | + headers |
| 68 | +}); |
| 69 | +const comment = resp.data.find(comment => comment.body.includes(bodyMatch)); |
| 70 | +if (!comment) { |
| 71 | + // create comment. |
| 72 | + await octokit.request("POST /repos/{owner}/{repo}/issues/{issue_number}/comments", { |
| 73 | + owner, |
| 74 | + repo, |
| 75 | + issue_number: issueNumber, |
| 76 | + body: bodyText, |
| 77 | + headers |
| 78 | + }); |
| 79 | +} else { |
| 80 | + // update comment. |
| 81 | + await octokit.request("PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}", { |
| 82 | + owner, |
| 83 | + repo, |
| 84 | + body: bodyText, |
| 85 | + comment_id: comment.id, |
| 86 | + headers |
| 87 | + }); |
| 88 | + |
| 89 | +} |
0 commit comments