mirror of
https://github.com/actions/setup-python.git
synced 2025-04-24 15:32:13 +00:00
Utilize pagination when querying GraalPy GitHub releases
This commit is contained in:
parent
62fe528f26
commit
feb18948f5
3 changed files with 64 additions and 10 deletions
|
@ -11,7 +11,8 @@ import {
|
||||||
isCacheFeatureAvailable,
|
isCacheFeatureAvailable,
|
||||||
getVersionInputFromFile,
|
getVersionInputFromFile,
|
||||||
getVersionInputFromPlainFile,
|
getVersionInputFromPlainFile,
|
||||||
getVersionInputFromTomlFile
|
getVersionInputFromTomlFile,
|
||||||
|
getNextPageUrl
|
||||||
} from '../src/utils';
|
} from '../src/utils';
|
||||||
|
|
||||||
jest.mock('@actions/cache');
|
jest.mock('@actions/cache');
|
||||||
|
@ -136,3 +137,25 @@ describe('Version from file test', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getNextPageUrl', () => {
|
||||||
|
it('GitHub API pagination next page is parsed correctly', () => {
|
||||||
|
function generateResponse(link: string) {
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
result: null,
|
||||||
|
headers: {
|
||||||
|
link: link
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const page1Links =
|
||||||
|
'<https://api.github.com/repositories/129883600/releases?page=2>; rel="next", <https://api.github.com/repositories/129883600/releases?page=3>; rel="last"';
|
||||||
|
expect(getNextPageUrl(generateResponse(page1Links))).toStrictEqual(
|
||||||
|
'https://api.github.com/repositories/129883600/releases?page=2'
|
||||||
|
);
|
||||||
|
const page2Links =
|
||||||
|
'<https://api.github.com/repositories/129883600/releases?page=1>; rel="prev", <https://api.github.com/repositories/129883600/releases?page=1>; rel="first"';
|
||||||
|
expect(getNextPageUrl(generateResponse(page2Links))).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -14,7 +14,8 @@ import {
|
||||||
IGraalPyManifestRelease,
|
IGraalPyManifestRelease,
|
||||||
createSymlinkInFolder,
|
createSymlinkInFolder,
|
||||||
isNightlyKeyword,
|
isNightlyKeyword,
|
||||||
getBinaryDirectory
|
getBinaryDirectory,
|
||||||
|
getNextPageUrl
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
const TOKEN = core.getInput('token');
|
const TOKEN = core.getInput('token');
|
||||||
|
@ -106,7 +107,6 @@ export async function installGraalPy(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAvailableGraalPyVersions() {
|
export async function getAvailableGraalPyVersions() {
|
||||||
const url = 'https://api.github.com/repos/oracle/graalpython/releases';
|
|
||||||
const http: httpm.HttpClient = new httpm.HttpClient('tool-cache');
|
const http: httpm.HttpClient = new httpm.HttpClient('tool-cache');
|
||||||
|
|
||||||
let headers: ifm.IHeaders = {};
|
let headers: ifm.IHeaders = {};
|
||||||
|
@ -114,14 +114,22 @@ export async function getAvailableGraalPyVersions() {
|
||||||
headers.authorization = AUTH;
|
headers.authorization = AUTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await http.getJson<IGraalPyManifestRelease[]>(url, headers);
|
let url: string | null =
|
||||||
|
'https://api.github.com/repos/oracle/graalpython/releases';
|
||||||
|
const result: IGraalPyManifestRelease[] = [];
|
||||||
|
do {
|
||||||
|
const response: ifm.ITypedResponse<IGraalPyManifestRelease[]> =
|
||||||
|
await http.getJson(url, headers);
|
||||||
if (!response.result) {
|
if (!response.result) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unable to retrieve the list of available GraalPy versions from '${url}'`
|
`Unable to retrieve the list of available GraalPy versions from '${url}'`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
result.push(...response.result);
|
||||||
|
url = getNextPageUrl(response);
|
||||||
|
} while (url);
|
||||||
|
|
||||||
return response.result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createGraalPySymlink(
|
async function createGraalPySymlink(
|
||||||
|
|
23
src/utils.ts
23
src/utils.ts
|
@ -6,6 +6,7 @@ import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import * as toml from '@iarna/toml';
|
import * as toml from '@iarna/toml';
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
|
import * as ifm from '@actions/http-client/interfaces';
|
||||||
|
|
||||||
export const IS_WINDOWS = process.platform === 'win32';
|
export const IS_WINDOWS = process.platform === 'win32';
|
||||||
export const IS_LINUX = process.platform === 'linux';
|
export const IS_LINUX = process.platform === 'linux';
|
||||||
|
@ -271,3 +272,25 @@ export function getVersionInputFromFile(versionFile: string): string[] {
|
||||||
export function getBinaryDirectory(installDir: string) {
|
export function getBinaryDirectory(installDir: string) {
|
||||||
return IS_WINDOWS ? installDir : path.join(installDir, 'bin');
|
return IS_WINDOWS ? installDir : path.join(installDir, 'bin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract next page URL from a HTTP response "link" header. Such headers are used in GitHub APIs.
|
||||||
|
*/
|
||||||
|
export function getNextPageUrl<T>(response: ifm.ITypedResponse<T>) {
|
||||||
|
const responseHeaders = <ifm.IHeaders>response.headers;
|
||||||
|
const linkHeader = responseHeaders.link;
|
||||||
|
if (typeof linkHeader === 'string') {
|
||||||
|
for (let link of linkHeader.split(/\s*,\s*/)) {
|
||||||
|
const match = link.match(/<([^>]+)>(.*)/);
|
||||||
|
if (match) {
|
||||||
|
const url = match[1];
|
||||||
|
for (let param of match[2].split(/\s*;\s*/)) {
|
||||||
|
if (param.match(/rel="?next"?/)) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue