import * as core from '@actions/core' ; import { Octokit , PullsGetResponseData } from './octokit-client' ; import { Command , SlashCommandPayload } from './command-helper' ; import { inspect } from 'util' ; type ReposCreateDispatchEventParamsClientPayload = { [ key ] : ReposCreateDispatchEventParamsClientPayloadKeyString ; } ; type ReposCreateDispatchEventParamsClientPayloadKeyString = { } ; export interface ClientPayload extends ReposCreateDispatchEventParamsClientPayload { github : any ; pull_request ? : any ; slash_command ? : SlashCommandPayload | any ; } interface Repository { owner : string ; repo : string ; } type CollaboratorPermission = { repository : { collaborators : { edges : [ { permission : string ; } ] ; } ; } ; } ; export class GitHubHelper { private octokit : InstanceType < typeof Octokit > ; constructor ( token ) { this . octokit = new Octokit ( { auth : token , baseUrl : process . env [ 'GITHUB_API_URL' ] || 'https://api.github.com' } ) ; } private parseRepository ( repository ) { const [ owner , repo ] = repository . split ( '/' ) ; return { owner : owner , repo : repo } ; } async getActorPermission ( repo , actor ) { const query = `query CollaboratorPermission($owner: String!, $repo: String!, $collaborator: String) {
      repository(owner:$owner, name:$repo) {
        collaborators(query: $collaborator) {
          edges {
            permission
          }
        }
      }
    }` ; const collaboratorPermission = await this . octokit . graphql < CollaboratorPermission > ( query , { ... repo , collaborator : actor } ) ; core . debug ( `CollaboratorPermission: ${ inspect ( collaboratorPermission . repository . collaborators . edges ) }` ) ; return collaboratorPermission . repository . collaborators . edges . length > 0 ? collaboratorPermission . repository . collaborators . edges [ 0 ] . permission . toLowerCase ( ) : 'none' ; } async tryAddReaction ( repo , commentId , reaction ) { try { await this . octokit . rest . reactions . createForIssueComment ( { ... repo , comment_id : commentId , content : reaction } ) ; } catch ( error ) { core . debug ( error ) ; core . warning ( `Failed to set reaction on comment ID ${ commentId }.` ) ; } } async getPull ( repo , pullNumber ) { const { data : pullRequest } = await this . octokit . rest . pulls . get ( { ... repo , pull_number : pullNumber } ) ; return pullRequest ; } async createDispatch ( cmd , clientPayload ) { if ( cmd . dispatch_type == 'repository' ) { await this . createRepositoryDispatch ( cmd , clientPayload ) ; } else { await this . createWorkflowDispatch ( cmd , clientPayload ) ; } } private async createRepositoryDispatch ( cmd , clientPayload ) { const eventType = `${ cmd . command }${ cmd . event_type_suffix }` ; await this . octokit . rest . repos . createDispatchEvent ( { ... this . parseRepository ( cmd . repository ) , event_type : `${ cmd . command }${ cmd . event_type_suffix }` , client_payload : clientPayload } ) ; core . info ( `Command '${ cmd . command }' dispatched to '${ cmd . repository }' ` + `with event type '${ eventType }'.` ) ; } async createWorkflowDispatch ( cmd , clientPayload ) { const workflow = `${ cmd . command }${ cmd . event_type_suffix }.yml` ; const slashCommand = clientPayload . slash_command ; const ref = slashCommand . args . named . ref ? slashCommand . args . named . ref : await this . getDefaultBranch ( cmd . repository ) ; const inputs = { } ; let count = 0 ; for ( const key in slashCommand . args . named ) { if ( key != 'ref' ) { inputs [ key ] = slashCommand . args . named [ key ] ; count ++ ; } if ( count == 10 ) break ; } await this . octokit . request ( 'POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches' , { ... this . parseRepository ( cmd . repository ) , workflow_id : workflow , ref : ref , inputs : inputs } ) ; core . info ( `Command '${ cmd . command }' dispatched to workflow '${ workflow }' in '${ cmd . repository }'` ) ; } private async getDefaultBranch ( repository ) { const { data : repo } = await this . octokit . rest . repos . get ( { ... this . parseRepository ( repository ) } ) ; return repo . default_branch ; } }