build(docs-infra): move to circleci v2 api for aio-builds (#45349)

Move to the CircleCI v2 api as the authentication fails for downloading artifacts using the v1 methods.

CircleCI v2 api now requires authentication to occur view the headers instead of being done in a
query parameter, all of the CircleCI interactions are now performed through one fetchFromCircleCi method
which ensures the token is provided in the headers as expected.

PR Close #45349
This commit is contained in:
Joey Perrott
2022-03-14 13:14:03 -07:00
committed by Alex Rickabaugh
parent 2a75754ee8
commit a049840e0d
5 changed files with 44 additions and 33 deletions
@@ -1,10 +1,10 @@
// Imports
import fetch from 'node-fetch';
import fetch, {RequestInit} from 'node-fetch';
import {assertNotMissingOrEmpty} from './utils';
// Constants
const CIRCLE_CI_API_URL = 'https://circleci.com/api/v1.1/project/github';
const CIRCLE_CI_API_URL = 'https://circleci.com/api/v2/project/gh';
// Interfaces - Types
export interface ArtifactInfo {
@@ -32,8 +32,6 @@ export interface BuildInfo {
* A Helper that can interact with the CircleCI API.
*/
export class CircleCiApi {
private tokenParam = `circle-token=${this.circleCiToken}`;
/**
* Construct a helper that can interact with the CircleCI REST API.
* @param githubOrg The Github organisation whose repos we want to access in CircleCI (e.g.
@@ -51,6 +49,15 @@ export class CircleCiApi {
assertNotMissingOrEmpty('circleCiToken', circleCiToken);
}
public async fetchFromCircleCi(url: string, params: RequestInit = {}) {
params.headers = {...params.headers, 'Circle-Token': this.circleCiToken};
const response = await fetch(url, params);
if (response.status !== 200) {
throw new Error(`${url}: ${response.status} - ${response.statusText}`);
}
return response;
}
/**
* Get the info for a build from the CircleCI API
* @param buildNumber The CircleCI build number that generated the artifact.
@@ -58,11 +65,8 @@ export class CircleCiApi {
*/
public async getBuildInfo(buildNumber: number): Promise<BuildInfo> {
try {
const baseUrl = `${CIRCLE_CI_API_URL}/${this.githubOrg}/${this.githubRepo}/${buildNumber}`;
const response = await fetch(`${baseUrl}?${this.tokenParam}`);
if (response.status !== 200) {
throw new Error(`${baseUrl}: ${response.status} - ${response.statusText}`);
}
const url = `${CIRCLE_CI_API_URL}/${this.githubOrg}/${this.githubRepo}/job/${buildNumber}`;
const response = await this.fetchFromCircleCi(url);
return response.json();
} catch (error) {
throw new Error(`CircleCI build info request failed (${(error as Error).message})`);
@@ -77,9 +81,9 @@ export class CircleCiApi {
public async getBuildArtifactUrl(buildNumber: number, artifactPath: string): Promise<string> {
const baseUrl = `${CIRCLE_CI_API_URL}/${this.githubOrg}/${this.githubRepo}/${buildNumber}`;
try {
const response = await fetch(`${baseUrl}/artifacts?${this.tokenParam}`);
const artifacts = await response.json() as ArtifactResponse;
const artifact = artifacts.find(item => item.path === artifactPath);
const response = await this.fetchFromCircleCi(`${baseUrl}/artifacts`);
const artifacts = await response.json() as {items: ArtifactResponse};
const artifact = artifacts.items.find(item => item.path === artifactPath);
if (!artifact) {
throw new Error(`Missing artifact (${artifactPath}) for CircleCI build: ${buildNumber}`);
}