import * as github from '@actions/github' ; import { Octokit , RestEndpointMethodTypes } from '@octokit/rest' ; import { inject , injectable } from 'inversify' ; import { isEmpty , isNil } from 'lodash' ; import { Logger , ProgressReporter , ReportMarkdownConvertor , productTitle } from '@accessibility-insights-action/shared' ; import { CombinedReportParameters } from 'accessibility-insights-report' ; import { GitHubIocTypes } from '../ioc/gh-ioc-types' ; type ListCommentsResponseItem = RestEndpointMethodTypes [ 'issues' ] [ 'listComments' ] [ 'response' ] [ 'data' ] [ 0 ] ; @ injectable ( ) export class PullRequestCommentCreator extends ProgressReporter { constructor ( @ inject ( ReportMarkdownConvertor ) private readonly reportMarkdownConvertor , @ inject ( Octokit ) private readonly octokit , @ inject ( GitHubIocTypes . Github ) private readonly githubObj , @ inject ( Logger ) private readonly logger ) { super ( ) ; } public async start ( ) { } public async completeRun ( combinedReportResult ) { if ( ! this . isSupported ( ) ) { return ; } const pullRequest = this . githubObj . context . payload . pull_request ; const existingComment = await this . findComment ( pullRequest . number ) ; const reportMarkdown = this . reportMarkdownConvertor . convert ( combinedReportResult ) ; this . traceMarkdown ( reportMarkdown ) ; if ( isNil ( existingComment ) ) { this . logMessage ( 'Creating new comment' ) ; await this . invoke ( async ( ) => await this . octokit . issues . createComment ( { owner : this . githubObj . context . repo . owner , repo : this . githubObj . context . repo . repo , body : reportMarkdown , issue_number : pullRequest . number , } ) ) ; } else { this . logMessage ( 'Updating existing comment' ) ; await this . invoke ( async ( ) => await this . octokit . issues . updateComment ( { owner : this . githubObj . context . repo . owner , repo : this . githubObj . context . repo . repo , body : reportMarkdown , comment_id : existingComment . id , } ) ) ; } } public async failRun ( message ) { if ( ! this . isSupported ( ) ) { return ; } throw message ; } private isSupported ( ) { return this . githubObj . context . eventName === 'pull_request' ; } private async findComment ( pullRequestNumber ) { const commentsResponse = await this . invoke ( async ( ) => await this . octokit . issues . listComments ( { issue_number : pullRequestNumber , owner : this . githubObj . context . repo . owner , repo : this . githubObj . context . repo . repo , } ) ) ; const comments = commentsResponse . data ; return comments . find ( ( c ) => ! isEmpty ( c . body ) && ! isEmpty ( c . user ) && c . user . login === 'github-actions[bot]' && c . body . includes ( productTitle ( ) ) ) ; } private logMessage ( message ) { this . logger . logInfo ( `${ message }` ) ; } }