Skip to content

Commit

Permalink
feat: fallback to raw endpoint for manifest when rate limit is reached (
Browse files Browse the repository at this point in the history
  • Loading branch information
Shegox authored Mar 26, 2024
1 parent 9a7ac94 commit 10aa35a
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 3 deletions.
58 changes: 58 additions & 0 deletions __tests__/install-python.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
getManifest,
getManifestFromRepo,
getManifestFromURL
} from '../src/install-python';
import * as httpm from '@actions/http-client';
import * as tc from '@actions/tool-cache';

jest.mock('@actions/http-client');
jest.mock('@actions/tool-cache');

const mockManifest = [{version: '1.0.0'}];

describe('getManifest', () => {
it('should return manifest from repo', async () => {
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue(mockManifest);
const manifest = await getManifest();
expect(manifest).toEqual(mockManifest);
});

it('should return manifest from URL if repo fetch fails', async () => {
(tc.getManifestFromRepo as jest.Mock).mockRejectedValue(
new Error('Fetch failed')
);
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest
});
const manifest = await getManifest();
expect(manifest).toEqual(mockManifest);
});
});

describe('getManifestFromRepo', () => {
it('should return manifest from repo', async () => {
(tc.getManifestFromRepo as jest.Mock).mockResolvedValue(mockManifest);
const manifest = await getManifestFromRepo();
expect(manifest).toEqual(mockManifest);
});
});

describe('getManifestFromURL', () => {
it('should return manifest from URL', async () => {
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: mockManifest
});
const manifest = await getManifestFromURL();
expect(manifest).toEqual(mockManifest);
});

it('should throw error if unable to get manifest from URL', async () => {
(httpm.HttpClient.prototype.getJson as jest.Mock).mockResolvedValue({
result: null
});
await expect(getManifestFromURL()).rejects.toThrow(
'Unable to get manifest from'
);
});
});
32 changes: 30 additions & 2 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91388,11 +91388,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.installCpythonFromRelease = exports.getManifest = exports.findReleaseFromManifest = exports.MANIFEST_URL = void 0;
exports.installCpythonFromRelease = exports.getManifestFromURL = exports.getManifestFromRepo = exports.getManifest = exports.findReleaseFromManifest = exports.MANIFEST_URL = void 0;
const path = __importStar(__nccwpck_require__(1017));
const core = __importStar(__nccwpck_require__(2186));
const tc = __importStar(__nccwpck_require__(7784));
const exec = __importStar(__nccwpck_require__(1514));
const httpm = __importStar(__nccwpck_require__(6255));
const utils_1 = __nccwpck_require__(1314);
const TOKEN = core.getInput('token');
const AUTH = !TOKEN ? undefined : `token ${TOKEN}`;
Expand All @@ -91411,10 +91412,37 @@ function findReleaseFromManifest(semanticVersionSpec, architecture, manifest) {
}
exports.findReleaseFromManifest = findReleaseFromManifest;
function getManifest() {
return __awaiter(this, void 0, void 0, function* () {
try {
return yield getManifestFromRepo();
}
catch (err) {
core.debug('Fetching the manifest via the API failed.');
if (err instanceof Error) {
core.debug(err.message);
}
}
return yield getManifestFromURL();
});
}
exports.getManifest = getManifest;
function getManifestFromRepo() {
core.debug(`Getting manifest from ${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}@${MANIFEST_REPO_BRANCH}`);
return tc.getManifestFromRepo(MANIFEST_REPO_OWNER, MANIFEST_REPO_NAME, AUTH, MANIFEST_REPO_BRANCH);
}
exports.getManifest = getManifest;
exports.getManifestFromRepo = getManifestFromRepo;
function getManifestFromURL() {
return __awaiter(this, void 0, void 0, function* () {
core.debug('Falling back to fetching the manifest using raw URL.');
const http = new httpm.HttpClient('tool-cache');
const response = yield http.getJson(exports.MANIFEST_URL);
if (!response.result) {
throw new Error(`Unable to get manifest from ${exports.MANIFEST_URL}`);
}
return response.result;
});
}
exports.getManifestFromURL = getManifestFromURL;
function installPython(workingDirectory) {
return __awaiter(this, void 0, void 0, function* () {
const options = {
Expand Down
26 changes: 25 additions & 1 deletion src/install-python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import * as core from '@actions/core';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
import * as httpm from '@actions/http-client';
import {ExecOptions} from '@actions/exec/lib/interfaces';
import {IS_WINDOWS, IS_LINUX} from './utils';

Expand Down Expand Up @@ -31,7 +32,19 @@ export async function findReleaseFromManifest(
return foundRelease;
}

export function getManifest(): Promise<tc.IToolRelease[]> {
export async function getManifest(): Promise<tc.IToolRelease[]> {
try {
return await getManifestFromRepo();
} catch (err) {
core.debug('Fetching the manifest via the API failed.');
if (err instanceof Error) {
core.debug(err.message);
}
}
return await getManifestFromURL();
}

export function getManifestFromRepo(): Promise<tc.IToolRelease[]> {
core.debug(
`Getting manifest from ${MANIFEST_REPO_OWNER}/${MANIFEST_REPO_NAME}@${MANIFEST_REPO_BRANCH}`
);
Expand All @@ -43,6 +56,17 @@ export function getManifest(): Promise<tc.IToolRelease[]> {
);
}

export async function getManifestFromURL(): Promise<tc.IToolRelease[]> {
core.debug('Falling back to fetching the manifest using raw URL.');

const http: httpm.HttpClient = new httpm.HttpClient('tool-cache');
const response = await http.getJson<tc.IToolRelease[]>(MANIFEST_URL);
if (!response.result) {
throw new Error(`Unable to get manifest from ${MANIFEST_URL}`);
}
return response.result;
}

async function installPython(workingDirectory: string) {
const options: ExecOptions = {
cwd: workingDirectory,
Expand Down

0 comments on commit 10aa35a

Please sign in to comment.