feat: fallback to raw endpoint for manifest when rate limit is reached (#766)

This commit is contained in:
Tobias 2024-03-26 14:56:00 +01:00 committed by GitHub
parent 9a7ac94420
commit 10aa35afd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 3 deletions

View File

@ -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
dist/setup/index.js vendored
View File

@ -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}`;
@ -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 = {

View File

@ -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';
@ -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}`
);
@ -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,