1import { Command } from '@expo/commander'; 2import chalk from 'chalk'; 3 4import { link } from '../Formatter'; 5import { commentOnIssueAsync } from '../GitHubActions'; 6import logger from '../Logger'; 7 8type ActionOptions = { 9 payload: string; 10}; 11 12export type CommentatorComment = { 13 issue: number; 14 body: string; 15}; 16 17export type CommentatorPayload = CommentatorComment[]; 18 19export default (program: Command) => { 20 program 21 .command('commentator') 22 .alias('comment') 23 .option( 24 '-p, --payload <payload>', 25 'Serialized and escaped JSON array describing what and where to comment.' 26 ) 27 .description( 28 `To add "Hello!" comment on issue #1234, run it with ${chalk.blue.italic( 29 `--payload "[{\\"issue\\": 1234, \\"body\\": \\"Hello!\\"}]"` 30 )}` 31 ) 32 .asyncAction(main); 33}; 34 35async function main(options: ActionOptions) { 36 const payload = parsePayload(options.payload); 37 const commentedIssues: number[] = []; 38 39 if (!Array.isArray(payload)) { 40 throw new Error(`Payload must be an array.`); 41 } 42 for (const comment of payload) { 43 if (!comment.issue || !comment.body) { 44 logger.error('Comment payload is incomplete:', comment); 45 continue; 46 } 47 try { 48 await commentOnIssueAsync(comment.issue, comment.body); 49 commentedIssues.push(comment.issue); 50 } catch (e) { 51 logger.error(`Failed to comment on issue #${comment.issue}:`, e); 52 } 53 } 54 if (commentedIssues.length > 0) { 55 logger.log( 56 '✍️ Commented on the following issues: %s', 57 commentedIssues 58 .map((issue) => 59 link(chalk.blue('#' + issue), `https://github.com/expo/expo/issues/${issue}`) 60 ) 61 .join(', ') 62 ); 63 } else { 64 logger.log('✍️ Nothing to comment.'); 65 } 66} 67 68function parsePayload(payloadString: string): CommentatorPayload { 69 const payload = JSON.parse(payloadString); 70 return payload; 71} 72