mirror of
https://github.com/actions/setup-node.git
synced 2025-04-22 03:28:42 +00:00
add canary releases
This commit is contained in:
parent
fa20ef8ad2
commit
84e2ff1255
3 changed files with 206 additions and 98 deletions
57
dist/cache-save/index.js
vendored
57
dist/cache-save/index.js
vendored
|
@ -3477,6 +3477,7 @@ const file_command_1 = __nccwpck_require__(717);
|
|||
const utils_1 = __nccwpck_require__(5278);
|
||||
const os = __importStar(__nccwpck_require__(2037));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const uuid_1 = __nccwpck_require__(8974);
|
||||
const oidc_utils_1 = __nccwpck_require__(8041);
|
||||
/**
|
||||
* The code to exit an action
|
||||
|
@ -3506,9 +3507,20 @@ function exportVariable(name, val) {
|
|||
process.env[name] = convertedVal;
|
||||
const filePath = process.env['GITHUB_ENV'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
|
||||
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||
// These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.
|
||||
if (name.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
if (convertedVal.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
||||
file_command_1.issueCommand('ENV', commandValue);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
|
@ -3526,7 +3538,7 @@ exports.setSecret = setSecret;
|
|||
function addPath(inputPath) {
|
||||
const filePath = process.env['GITHUB_PATH'] || '';
|
||||
if (filePath) {
|
||||
file_command_1.issueFileCommand('PATH', inputPath);
|
||||
file_command_1.issueCommand('PATH', inputPath);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
|
@ -3566,10 +3578,7 @@ function getMultilineInput(name, options) {
|
|||
const inputs = getInput(name, options)
|
||||
.split('\n')
|
||||
.filter(x => x !== '');
|
||||
if (options && options.trimWhitespace === false) {
|
||||
return inputs;
|
||||
}
|
||||
return inputs.map(input => input.trim());
|
||||
return inputs;
|
||||
}
|
||||
exports.getMultilineInput = getMultilineInput;
|
||||
/**
|
||||
|
@ -3602,12 +3611,8 @@ exports.getBooleanInput = getBooleanInput;
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
const filePath = process.env['GITHUB_OUTPUT'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
|
||||
}
|
||||
process.stdout.write(os.EOL);
|
||||
command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
/**
|
||||
|
@ -3736,11 +3741,7 @@ exports.group = group;
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function saveState(name, value) {
|
||||
const filePath = process.env['GITHUB_STATE'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
|
||||
}
|
||||
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
|
@ -3806,14 +3807,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
|
||||
exports.issueCommand = void 0;
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const os = __importStar(__nccwpck_require__(2037));
|
||||
const uuid_1 = __nccwpck_require__(8974);
|
||||
const utils_1 = __nccwpck_require__(5278);
|
||||
function issueFileCommand(command, message) {
|
||||
function issueCommand(command, message) {
|
||||
const filePath = process.env[`GITHUB_${command}`];
|
||||
if (!filePath) {
|
||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||
|
@ -3825,22 +3825,7 @@ function issueFileCommand(command, message) {
|
|||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
exports.issueFileCommand = issueFileCommand;
|
||||
function prepareKeyValueMessage(key, value) {
|
||||
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||
const convertedValue = utils_1.toCommandValue(value);
|
||||
// These should realistically never happen, but just in case someone finds a
|
||||
// way to exploit uuid generation let's not allow keys or values that contain
|
||||
// the delimiter.
|
||||
if (key.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
if (convertedValue.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
|
||||
}
|
||||
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
||||
exports.issueCommand = issueCommand;
|
||||
//# sourceMappingURL=file-command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
|
147
dist/setup/index.js
vendored
147
dist/setup/index.js
vendored
|
@ -3477,6 +3477,7 @@ const file_command_1 = __nccwpck_require__(717);
|
|||
const utils_1 = __nccwpck_require__(5278);
|
||||
const os = __importStar(__nccwpck_require__(2037));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const uuid_1 = __nccwpck_require__(8974);
|
||||
const oidc_utils_1 = __nccwpck_require__(8041);
|
||||
/**
|
||||
* The code to exit an action
|
||||
|
@ -3506,9 +3507,20 @@ function exportVariable(name, val) {
|
|||
process.env[name] = convertedVal;
|
||||
const filePath = process.env['GITHUB_ENV'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
|
||||
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||
// These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.
|
||||
if (name.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
if (convertedVal.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
||||
file_command_1.issueCommand('ENV', commandValue);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
|
@ -3526,7 +3538,7 @@ exports.setSecret = setSecret;
|
|||
function addPath(inputPath) {
|
||||
const filePath = process.env['GITHUB_PATH'] || '';
|
||||
if (filePath) {
|
||||
file_command_1.issueFileCommand('PATH', inputPath);
|
||||
file_command_1.issueCommand('PATH', inputPath);
|
||||
}
|
||||
else {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
|
@ -3566,10 +3578,7 @@ function getMultilineInput(name, options) {
|
|||
const inputs = getInput(name, options)
|
||||
.split('\n')
|
||||
.filter(x => x !== '');
|
||||
if (options && options.trimWhitespace === false) {
|
||||
return inputs;
|
||||
}
|
||||
return inputs.map(input => input.trim());
|
||||
return inputs;
|
||||
}
|
||||
exports.getMultilineInput = getMultilineInput;
|
||||
/**
|
||||
|
@ -3602,12 +3611,8 @@ exports.getBooleanInput = getBooleanInput;
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function setOutput(name, value) {
|
||||
const filePath = process.env['GITHUB_OUTPUT'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
|
||||
}
|
||||
process.stdout.write(os.EOL);
|
||||
command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
/**
|
||||
|
@ -3736,11 +3741,7 @@ exports.group = group;
|
|||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function saveState(name, value) {
|
||||
const filePath = process.env['GITHUB_STATE'] || '';
|
||||
if (filePath) {
|
||||
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
|
||||
}
|
||||
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
|
@ -3806,14 +3807,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
|
||||
exports.issueCommand = void 0;
|
||||
// We use any as a valid input type
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const os = __importStar(__nccwpck_require__(2037));
|
||||
const uuid_1 = __nccwpck_require__(8974);
|
||||
const utils_1 = __nccwpck_require__(5278);
|
||||
function issueFileCommand(command, message) {
|
||||
function issueCommand(command, message) {
|
||||
const filePath = process.env[`GITHUB_${command}`];
|
||||
if (!filePath) {
|
||||
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||
|
@ -3825,22 +3825,7 @@ function issueFileCommand(command, message) {
|
|||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
exports.issueFileCommand = issueFileCommand;
|
||||
function prepareKeyValueMessage(key, value) {
|
||||
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
|
||||
const convertedValue = utils_1.toCommandValue(value);
|
||||
// These should realistically never happen, but just in case someone finds a
|
||||
// way to exploit uuid generation let's not allow keys or values that contain
|
||||
// the delimiter.
|
||||
if (key.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
if (convertedValue.includes(delimiter)) {
|
||||
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
|
||||
}
|
||||
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
|
||||
}
|
||||
exports.prepareKeyValueMessage = prepareKeyValueMessage;
|
||||
exports.issueCommand = issueCommand;
|
||||
//# sourceMappingURL=file-command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
@ -73181,6 +73166,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const os = __nccwpck_require__(2037);
|
||||
const fs = __nccwpck_require__(7147);
|
||||
const assert = __importStar(__nccwpck_require__(9491));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const hc = __importStar(__nccwpck_require__(9925));
|
||||
|
@ -73188,15 +73174,19 @@ const io = __importStar(__nccwpck_require__(7436));
|
|||
const tc = __importStar(__nccwpck_require__(7784));
|
||||
const path = __importStar(__nccwpck_require__(1017));
|
||||
const semver = __importStar(__nccwpck_require__(5911));
|
||||
const fs = __nccwpck_require__(7147);
|
||||
// TODO: unify with other isNnn?
|
||||
const V8_CANARY = 'v8-canary';
|
||||
const isVersionCanary = (versionSpec) => versionSpec.includes(`-${V8_CANARY}`);
|
||||
function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Store manifest data to avoid multiple calls
|
||||
let manifest;
|
||||
let nodeVersions;
|
||||
let isNightly = versionSpec.includes('nightly');
|
||||
let isCanary = isVersionCanary(versionSpec);
|
||||
let isNightly = versionSpec.includes('nightly') && !isCanary; // avoid both set by preceding isCanary
|
||||
let osPlat = os.platform();
|
||||
let osArch = translateArchToDistUrl(arch);
|
||||
core.debug(`get node isLtsAlias=${isLtsAlias(versionSpec)} isCanary=${isCanary} isNightly=${isNightly}`);
|
||||
if (isLtsAlias(versionSpec)) {
|
||||
core.info('Attempt to resolve LTS alias from manifest...');
|
||||
// No try-catch since it's not possible to resolve LTS alias without manifest
|
||||
|
@ -73204,15 +73194,18 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
|||
versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
|
||||
}
|
||||
if (isLatestSyntax(versionSpec)) {
|
||||
core.debug('will use latest node version from node repository because of latest syntax ...');
|
||||
nodeVersions = yield getVersionsFromDist(versionSpec);
|
||||
versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions);
|
||||
core.info(`getting latest node version...`);
|
||||
core.info(`getting latest node version ${versionSpec}...`);
|
||||
}
|
||||
if (isNightly && checkLatest) {
|
||||
if (isNightly && checkLatest || isCanary && checkLatest) {
|
||||
core.debug(`will check latest node version from node repository because of check latest input with ${isNightly ? 'nightly' : 'canary'} set...`);
|
||||
nodeVersions = yield getVersionsFromDist(versionSpec);
|
||||
versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions);
|
||||
core.info(`getting node version ${versionSpec}...`);
|
||||
}
|
||||
if (checkLatest && !isNightly) {
|
||||
if (checkLatest && !isNightly && !isCanary) {
|
||||
core.info('Attempt to resolve the latest version from manifest...');
|
||||
const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest);
|
||||
if (resolvedVersion) {
|
||||
|
@ -73226,9 +73219,9 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
|||
// check cache
|
||||
core.debug('check toolcache');
|
||||
let toolPath;
|
||||
if (isNightly) {
|
||||
const nightlyVersion = findNightlyVersionInHostedToolcache(versionSpec, osArch);
|
||||
toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch);
|
||||
if (isNightly || isCanary) {
|
||||
const nightlyOrCanaryVersion = findNightlyOrCanaryVersionInHostedToolcache(versionSpec, osArch);
|
||||
toolPath = nightlyOrCanaryVersion && tc.find('node', nightlyOrCanaryVersion, osArch);
|
||||
}
|
||||
else {
|
||||
toolPath = tc.find('node', versionSpec, osArch);
|
||||
|
@ -73245,7 +73238,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
|||
// Try download from internal distribution (popular versions only)
|
||||
//
|
||||
try {
|
||||
info = yield getInfoFromManifest(versionSpec, !isNightly, auth, osArch, manifest);
|
||||
info = yield getInfoFromManifest(versionSpec, !isNightly && !isVersionCanary, auth, osArch, manifest);
|
||||
if (info) {
|
||||
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
|
||||
downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, auth);
|
||||
|
@ -73328,11 +73321,10 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
|||
});
|
||||
}
|
||||
exports.getNode = getNode;
|
||||
function findNightlyVersionInHostedToolcache(versionsSpec, osArch) {
|
||||
function findNightlyOrCanaryVersionInHostedToolcache(versionsSpec, osArch) {
|
||||
const foundAllVersions = tc.findAllVersions('node', osArch);
|
||||
core.debug(foundAllVersions.join('\n'));
|
||||
const version = evaluateVersions(foundAllVersions, versionsSpec);
|
||||
return version;
|
||||
return evaluateVersions(foundAllVersions, versionsSpec);
|
||||
}
|
||||
function isLtsAlias(versionSpec) {
|
||||
return versionSpec.startsWith('lts/');
|
||||
|
@ -73388,7 +73380,14 @@ function getInfoFromDist(versionSpec, arch = os.arch(), nodeVersions) {
|
|||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let osPlat = os.platform();
|
||||
let osArch = translateArchToDistUrl(arch);
|
||||
core.debug(`getting the release version from index.json in node repository`);
|
||||
let version = yield queryDistForMatch(versionSpec, arch, nodeVersions);
|
||||
if (version) {
|
||||
core.debug(`got "${version}" release version from index.json in node repository`);
|
||||
}
|
||||
else {
|
||||
core.debug(`release version from index.json in node repository not found`);
|
||||
}
|
||||
if (!version) {
|
||||
return null;
|
||||
}
|
||||
|
@ -73460,6 +73459,48 @@ function evaluateNightlyVersions(versions, versionSpec) {
|
|||
}
|
||||
return version;
|
||||
}
|
||||
function evaluateCanaryVersions(versions, versionSpec) {
|
||||
var _a;
|
||||
let version = '';
|
||||
let range;
|
||||
const [raw, prerelease] = versionSpec.split(/-(.*)/s);
|
||||
const isValidVersion = semver.valid(raw);
|
||||
const rawVersion = isValidVersion ? raw : (_a = semver.coerce(raw)) === null || _a === void 0 ? void 0 : _a.version;
|
||||
if (rawVersion) {
|
||||
if (prerelease === V8_CANARY) {
|
||||
range = semver.validRange(`^${rawVersion}`);
|
||||
}
|
||||
else {
|
||||
range = `${rawVersion}+${prerelease.replace(V8_CANARY, V8_CANARY + '.')}`;
|
||||
}
|
||||
}
|
||||
core.debug(`evaluate canary versions rawVersion="${rawVersion}" range="${range}"`);
|
||||
if (range) {
|
||||
const versionsReversed = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return -1;
|
||||
}
|
||||
else if (semver.lt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
for (const potential of versionsReversed) {
|
||||
const satisfied = semver.satisfies(potential.replace('-' + V8_CANARY, '+' + V8_CANARY + '.'), range);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version) {
|
||||
core.debug(`matched: ${version}`);
|
||||
}
|
||||
else {
|
||||
core.debug('match not found');
|
||||
}
|
||||
return version;
|
||||
}
|
||||
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
||||
function evaluateVersions(versions, versionSpec) {
|
||||
let version = '';
|
||||
|
@ -73468,6 +73509,9 @@ function evaluateVersions(versions, versionSpec) {
|
|||
if (versionSpec.includes('nightly')) {
|
||||
return evaluateNightlyVersions(versions, versionSpec);
|
||||
}
|
||||
else if (isVersionCanary(versionSpec)) {
|
||||
return evaluateCanaryVersions(versions, versionSpec);
|
||||
}
|
||||
versions = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return 1;
|
||||
|
@ -73493,12 +73537,18 @@ function evaluateVersions(versions, versionSpec) {
|
|||
function getNodejsDistUrl(version) {
|
||||
const prerelease = semver.prerelease(version);
|
||||
if (version.includes('nightly')) {
|
||||
core.debug('requested nightly build');
|
||||
return 'https://nodejs.org/download/nightly';
|
||||
}
|
||||
else if (isVersionCanary(version)) {
|
||||
core.debug('requested v8 canary build');
|
||||
return 'https://nodejs.org/download/v8-canary';
|
||||
}
|
||||
else if (!prerelease) {
|
||||
return 'https://nodejs.org/dist';
|
||||
}
|
||||
else {
|
||||
core.debug('requested RC build');
|
||||
return 'https://nodejs.org/download/rc';
|
||||
}
|
||||
}
|
||||
|
@ -73545,6 +73595,7 @@ function getVersionsFromDist(versionSpec) {
|
|||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const initialUrl = getNodejsDistUrl(versionSpec);
|
||||
const dataUrl = `${initialUrl}/index.json`;
|
||||
core.debug(`download ${dataUrl}`);
|
||||
let httpClient = new hc.HttpClient('setup-node', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
|
|
100
src/installer.ts
100
src/installer.ts
|
@ -1,4 +1,5 @@
|
|||
import os = require('os');
|
||||
import fs = require('fs');
|
||||
import * as assert from 'assert';
|
||||
import * as core from '@actions/core';
|
||||
import * as hc from '@actions/http-client';
|
||||
|
@ -6,13 +7,13 @@ import * as io from '@actions/io';
|
|||
import * as tc from '@actions/tool-cache';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import fs = require('fs');
|
||||
|
||||
//
|
||||
// Node versions interface
|
||||
// see https://nodejs.org/dist/index.json
|
||||
// for nightly https://nodejs.org/download/nightly/index.json
|
||||
//
|
||||
// for canary https://nodejs.org/download/v8-canary/index.json
|
||||
|
||||
export interface INodeVersion {
|
||||
version: string;
|
||||
files: string[];
|
||||
|
@ -29,6 +30,10 @@ interface INodeRelease extends tc.IToolRelease {
|
|||
lts?: string;
|
||||
}
|
||||
|
||||
// TODO: unify with other isNnn?
|
||||
const V8_CANARY = 'v8-canary';
|
||||
const isVersionCanary = (versionSpec: string):boolean => versionSpec.includes(`-${V8_CANARY}`);
|
||||
|
||||
export async function getNode(
|
||||
versionSpec: string,
|
||||
stable: boolean,
|
||||
|
@ -39,10 +44,13 @@ export async function getNode(
|
|||
// Store manifest data to avoid multiple calls
|
||||
let manifest: INodeRelease[] | undefined;
|
||||
let nodeVersions: INodeVersion[] | undefined;
|
||||
let isNightly = versionSpec.includes('nightly');
|
||||
let isCanary = isVersionCanary(versionSpec);
|
||||
let isNightly = versionSpec.includes('nightly') && !isCanary; // avoid both set by preceding isCanary
|
||||
let osPlat: string = os.platform();
|
||||
let osArch: string = translateArchToDistUrl(arch);
|
||||
|
||||
core.debug(`get node isLtsAlias=${isLtsAlias(versionSpec)} isCanary=${isCanary} isNightly=${isNightly}`);
|
||||
|
||||
if (isLtsAlias(versionSpec)) {
|
||||
core.info('Attempt to resolve LTS alias from manifest...');
|
||||
|
||||
|
@ -53,17 +61,22 @@ export async function getNode(
|
|||
}
|
||||
|
||||
if (isLatestSyntax(versionSpec)) {
|
||||
core.debug('will use latest node version from node repository because of latest syntax ...');
|
||||
nodeVersions = await getVersionsFromDist(versionSpec);
|
||||
versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions);
|
||||
core.info(`getting latest node version...`);
|
||||
core.info(`getting latest node version ${versionSpec}...`);
|
||||
}
|
||||
|
||||
if (isNightly && checkLatest) {
|
||||
if (isNightly && checkLatest || isCanary && checkLatest) {
|
||||
core.debug(
|
||||
`will check latest node version from node repository because of check latest input with ${isNightly ? 'nightly' : 'canary'} set...`
|
||||
);
|
||||
nodeVersions = await getVersionsFromDist(versionSpec);
|
||||
versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions);
|
||||
core.info(`getting node version ${versionSpec}...`);
|
||||
}
|
||||
|
||||
if (checkLatest && !isNightly) {
|
||||
if (checkLatest && !isNightly && !isCanary) {
|
||||
core.info('Attempt to resolve the latest version from manifest...');
|
||||
const resolvedVersion = await resolveVersionFromManifest(
|
||||
versionSpec,
|
||||
|
@ -83,12 +96,12 @@ export async function getNode(
|
|||
// check cache
|
||||
core.debug('check toolcache');
|
||||
let toolPath: string;
|
||||
if (isNightly) {
|
||||
const nightlyVersion = findNightlyVersionInHostedToolcache(
|
||||
if (isNightly || isCanary) {
|
||||
const nightlyOrCanaryVersion = findNightlyOrCanaryVersionInHostedToolcache(
|
||||
versionSpec,
|
||||
osArch
|
||||
);
|
||||
toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch);
|
||||
toolPath = nightlyOrCanaryVersion && tc.find('node', nightlyOrCanaryVersion, osArch);
|
||||
} else {
|
||||
toolPath = tc.find('node', versionSpec, osArch);
|
||||
}
|
||||
|
@ -107,7 +120,7 @@ export async function getNode(
|
|||
try {
|
||||
info = await getInfoFromManifest(
|
||||
versionSpec,
|
||||
!isNightly,
|
||||
!isNightly && !isVersionCanary,
|
||||
auth,
|
||||
osArch,
|
||||
manifest
|
||||
|
@ -215,15 +228,13 @@ export async function getNode(
|
|||
core.addPath(toolPath);
|
||||
}
|
||||
|
||||
function findNightlyVersionInHostedToolcache(
|
||||
function findNightlyOrCanaryVersionInHostedToolcache(
|
||||
versionsSpec: string,
|
||||
osArch: string
|
||||
) {
|
||||
const foundAllVersions = tc.findAllVersions('node', osArch);
|
||||
core.debug(foundAllVersions.join('\n'));
|
||||
const version = evaluateVersions(foundAllVersions, versionsSpec);
|
||||
|
||||
return version;
|
||||
return evaluateVersions(foundAllVersions, versionsSpec);
|
||||
}
|
||||
|
||||
function isLtsAlias(versionSpec: string): boolean {
|
||||
|
@ -313,11 +324,17 @@ async function getInfoFromDist(
|
|||
let osPlat: string = os.platform();
|
||||
let osArch: string = translateArchToDistUrl(arch);
|
||||
|
||||
core.debug(`getting the release version from index.json in node repository`);
|
||||
let version: string = await queryDistForMatch(
|
||||
versionSpec,
|
||||
arch,
|
||||
nodeVersions
|
||||
);
|
||||
if (version) {
|
||||
core.debug(`got "${version}" release version from index.json in node repository`);
|
||||
} else {
|
||||
core.debug(`release version from index.json in node repository not found`);
|
||||
}
|
||||
|
||||
if (!version) {
|
||||
return null;
|
||||
|
@ -412,6 +429,53 @@ function evaluateNightlyVersions(
|
|||
return version;
|
||||
}
|
||||
|
||||
function evaluateCanaryVersions(
|
||||
versions: string[],
|
||||
versionSpec: string
|
||||
): string {
|
||||
let version = '';
|
||||
let range: string | null | undefined;
|
||||
const [raw, prerelease] = versionSpec.split(/-(.*)/s);
|
||||
const isValidVersion = semver.valid(raw);
|
||||
const rawVersion = isValidVersion ? raw : semver.coerce(raw)?.version;
|
||||
if (rawVersion) {
|
||||
if (prerelease === V8_CANARY) {
|
||||
range = semver.validRange(`^${rawVersion}`);
|
||||
} else {
|
||||
range = `${rawVersion}+${prerelease.replace(V8_CANARY, V8_CANARY + '.')}`;
|
||||
}
|
||||
}
|
||||
core.debug(`evaluate canary versions rawVersion="${rawVersion}" range="${range}"`)
|
||||
|
||||
if (range) {
|
||||
const versionsReversed = versions.sort((a, b) => {
|
||||
if (semver.gt(a, b)) {
|
||||
return -1;
|
||||
} else if (semver.lt(a, b)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
for (const potential of versionsReversed) {
|
||||
const satisfied: boolean = semver.satisfies(
|
||||
potential.replace('-' + V8_CANARY, '+' + V8_CANARY + '.'),
|
||||
range);
|
||||
if (satisfied) {
|
||||
version = potential;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version) {
|
||||
core.debug(`matched: ${version}`);
|
||||
} else {
|
||||
core.debug('match not found');
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
||||
function evaluateVersions(versions: string[], versionSpec: string): string {
|
||||
let version = '';
|
||||
|
@ -420,6 +484,8 @@ function evaluateVersions(versions: string[], versionSpec: string): string {
|
|||
|
||||
if (versionSpec.includes('nightly')) {
|
||||
return evaluateNightlyVersions(versions, versionSpec);
|
||||
} else if (isVersionCanary(versionSpec)) {
|
||||
return evaluateCanaryVersions(versions, versionSpec);
|
||||
}
|
||||
|
||||
versions = versions.sort((a, b) => {
|
||||
|
@ -449,10 +515,15 @@ function evaluateVersions(versions: string[], versionSpec: string): string {
|
|||
function getNodejsDistUrl(version: string) {
|
||||
const prerelease = semver.prerelease(version);
|
||||
if (version.includes('nightly')) {
|
||||
core.debug('requested nightly build');
|
||||
return 'https://nodejs.org/download/nightly';
|
||||
} else if (isVersionCanary(version)) {
|
||||
core.debug('requested v8 canary build');
|
||||
return 'https://nodejs.org/download/v8-canary';
|
||||
} else if (!prerelease) {
|
||||
return 'https://nodejs.org/dist';
|
||||
} else {
|
||||
core.debug('requested RC build');
|
||||
return 'https://nodejs.org/download/rc';
|
||||
}
|
||||
}
|
||||
|
@ -510,6 +581,7 @@ export async function getVersionsFromDist(
|
|||
): Promise<INodeVersion[]> {
|
||||
const initialUrl = getNodejsDistUrl(versionSpec);
|
||||
const dataUrl = `${initialUrl}/index.json`;
|
||||
core.debug(`download ${dataUrl}`);
|
||||
let httpClient = new hc.HttpClient('setup-node', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
|
|
Loading…
Add table
Reference in a new issue