import * as core from '@actions/core' import axios from 'axios' import type {AxiosInstance} from 'axios' import {JobParameters} from './inputs' // JobDetails are information about the repository and dependencies to be updated export type JobDetails = { 'allowed-updates': Array<{ 'dependency-type': string }> id: string 'package-manager': string } export type JobError = { 'error-type': string 'error-details': { 'action-error': string } } export type Credential = { type: string host: string username?: string password?: string token?: string } export class CredentialFetchingError extends Error {} export class ApiClient { constructor( private readonly client: AxiosInstance, readonly params: JobParameters ) {} // We use a static unknown SHA when marking a job as complete from the action // to remain in parity with the existing runner. UnknownSha = { 'base-commit-sha': 'unknown' } async getJobDetails(): Promise<JobDetails> { const detailsURL = `/update_jobs/${this.params.jobId}/details` const res: any = await this.client.get(detailsURL, { headers: {Authorization: this.params.jobToken} }) if (res.status !== 200) { throw new Error(`Unexpected status code: ${res.status}`) } return res.data.data.attributes } async getCredentials(): Promise<Credential[]> { const credentialsURL = `/update_jobs/${this.params.jobId}/credentials` try { const res: any = await this.client.get(credentialsURL, { headers: {Authorization: this.params.credentialsToken} }) // Mask any secrets we've just retrieved from Actions logs for (const credential of res.data.data.attributes.credentials) { if (credential.password) { core.setSecret(credential.password) } if (credential.token) { core.setSecret(credential.token) } } return res.data.data.attributes.credentials } catch (error: unknown) { if (axios.isAxiosError(error)) { const err = error throw new CredentialFetchingError( `fetching credentials: received code ${ err.response?.status }: ${JSON.stringify(err.response?.data)}` ) } else { throw error } } } async reportJobError(error: JobError): Promise<void> { const recordErrorURL = `/update_jobs/${this.params.jobId}/record_update_job_error` const res = await this.client.post( recordErrorURL, {data: error}, { headers: {Authorization: this.params.jobToken} } ) if (res.status !== 204) { throw new Error(`Unexpected status code: ${res.status}`) } } async markJobAsProcessed(): Promise<void> { const markAsProcessedURL = `/update_jobs/${this.params.jobId}/mark_as_processed` const res = await this.client.patch( markAsProcessedURL, {data: this.UnknownSha}, { headers: {Authorization: this.params.jobToken} } ) if (res.status !== 204) { throw new Error(`Unexpected status code: ${res.status}`) } } }