19d43b932STomasz Sapetaimport { Command } from '@expo/commander';
29d43b932STomasz Sapetaimport chalk from 'chalk';
39d43b932STomasz Sapeta
4*a272999eSBartosz Kaszubowskiimport { link } from '../Formatter';
59d43b932STomasz Sapetaimport { commentOnIssueAsync } from '../GitHubActions';
69d43b932STomasz Sapetaimport logger from '../Logger';
79d43b932STomasz Sapeta
89d43b932STomasz Sapetatype ActionOptions = {
99d43b932STomasz Sapeta  payload: string;
109d43b932STomasz Sapeta};
119d43b932STomasz Sapeta
129d43b932STomasz Sapetaexport type CommentatorComment = {
139d43b932STomasz Sapeta  issue: number;
149d43b932STomasz Sapeta  body: string;
159d43b932STomasz Sapeta};
169d43b932STomasz Sapeta
179d43b932STomasz Sapetaexport type CommentatorPayload = CommentatorComment[];
189d43b932STomasz Sapeta
199d43b932STomasz Sapetaexport default (program: Command) => {
209d43b932STomasz Sapeta  program
219d43b932STomasz Sapeta    .command('commentator')
229d43b932STomasz Sapeta    .alias('comment')
239d43b932STomasz Sapeta    .option(
249d43b932STomasz Sapeta      '-p, --payload <payload>',
259d43b932STomasz Sapeta      'Serialized and escaped JSON array describing what and where to comment.'
269d43b932STomasz Sapeta    )
279d43b932STomasz Sapeta    .description(
289d43b932STomasz Sapeta      `To add "Hello!" comment on issue #1234, run it with ${chalk.blue.italic(
299d43b932STomasz Sapeta        `--payload "[{\\"issue\\": 1234, \\"body\\": \\"Hello!\\"}]"`
309d43b932STomasz Sapeta      )}`
319d43b932STomasz Sapeta    )
329d43b932STomasz Sapeta    .asyncAction(main);
339d43b932STomasz Sapeta};
349d43b932STomasz Sapeta
359d43b932STomasz Sapetaasync function main(options: ActionOptions) {
369d43b932STomasz Sapeta  const payload = parsePayload(options.payload);
379d43b932STomasz Sapeta  const commentedIssues: number[] = [];
389d43b932STomasz Sapeta
399d43b932STomasz Sapeta  if (!Array.isArray(payload)) {
409d43b932STomasz Sapeta    throw new Error(`Payload must be an array.`);
419d43b932STomasz Sapeta  }
429d43b932STomasz Sapeta  for (const comment of payload) {
439d43b932STomasz Sapeta    if (!comment.issue || !comment.body) {
449d43b932STomasz Sapeta      logger.error('Comment payload is incomplete:', comment);
459d43b932STomasz Sapeta      continue;
469d43b932STomasz Sapeta    }
479d43b932STomasz Sapeta    try {
489d43b932STomasz Sapeta      await commentOnIssueAsync(comment.issue, comment.body);
499d43b932STomasz Sapeta      commentedIssues.push(comment.issue);
509d43b932STomasz Sapeta    } catch (e) {
519d43b932STomasz Sapeta      logger.error(`Failed to comment on issue #${comment.issue}:`, e);
529d43b932STomasz Sapeta    }
539d43b932STomasz Sapeta  }
549d43b932STomasz Sapeta  if (commentedIssues.length > 0) {
559d43b932STomasz Sapeta    logger.log(
569d43b932STomasz Sapeta      '✍️  Commented on the following issues: %s',
579d43b932STomasz Sapeta      commentedIssues
589d43b932STomasz Sapeta        .map((issue) =>
599d43b932STomasz Sapeta          link(chalk.blue('#' + issue), `https://github.com/expo/expo/issues/${issue}`)
609d43b932STomasz Sapeta        )
619d43b932STomasz Sapeta        .join(', ')
629d43b932STomasz Sapeta    );
639d43b932STomasz Sapeta  } else {
649d43b932STomasz Sapeta    logger.log('✍️  Nothing to comment.');
659d43b932STomasz Sapeta  }
669d43b932STomasz Sapeta}
679d43b932STomasz Sapeta
689d43b932STomasz Sapetafunction parsePayload(payloadString: string): CommentatorPayload {
699d43b932STomasz Sapeta  const payload = JSON.parse(payloadString);
709d43b932STomasz Sapeta  return payload;
719d43b932STomasz Sapeta}
72