Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for nightly and rc versions #4

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
20 changes: 20 additions & 0 deletions .github/workflows/versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ jobs:
__tests__/verify-node.sh "${BASH_REMATCH[1]}"
shell: bash

nightly-syntax:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [17-nightly, 18-nightly, 19-nightly]
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: |
nightlyVersion="${{ matrix.node-version }}"
majorVersion=$(echo $nightlyVersion | cut -d- -f1)
__tests__/verify-node.sh "$majorVersion"
shell: bash

manifest:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
2 changes: 1 addition & 1 deletion __tests__/authutil.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os = require('os');
import os from 'os';
import * as fs from 'fs';
import * as path from 'path';
import * as core from '@actions/core';
Expand Down
5 changes: 3 additions & 2 deletions __tests__/installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as im from '../src/installer';
import * as cache from '@actions/cache';
import fs from 'fs';
import cp from 'child_process';
import osm = require('os');
import osm from 'os';
import path from 'path';
import each from 'jest-each';
import * as main from '../src/main';
Expand Down Expand Up @@ -138,7 +138,8 @@ describe('setup-node', () => {
});

it('can mock dist versions', async () => {
let versions: im.INodeVersion[] = await im.getVersionsFromDist();
const versionSpec = '1.2.3';
let versions: im.INodeVersion[] = await im.getVersionsFromDist(versionSpec);
expect(versions).toBeDefined();
expect(versions?.length).toBe(23);
});
Expand Down
106 changes: 89 additions & 17 deletions dist/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73194,6 +73194,7 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
// Store manifest data to avoid multiple calls
let manifest;
let nodeVersions;
let isNightly = versionSpec.includes('nightly');
let osPlat = os.platform();
let osArch = translateArchToDistUrl(arch);
if (isLtsAlias(versionSpec)) {
Expand All @@ -73203,11 +73204,15 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
}
if (isLatestSyntax(versionSpec)) {
nodeVersions = yield getVersionsFromDist();
nodeVersions = yield getVersionsFromDist(versionSpec);
versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions);
core.info(`getting latest node version...`);
}
if (checkLatest) {
if (isNightly && checkLatest) {
nodeVersions = yield getVersionsFromDist(versionSpec);
versionSpec = yield queryDistForMatch(versionSpec, arch, nodeVersions);
}
if (checkLatest && !isNightly) {
core.info('Attempt to resolve the latest version from manifest...');
const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch, manifest);
if (resolvedVersion) {
Expand All @@ -73220,7 +73225,13 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
}
// check cache
let toolPath;
toolPath = tc.find('node', versionSpec, osArch);
if (isNightly) {
const nightlyVersion = findNightlyVersionInHostedToolcache(versionSpec, osArch);
toolPath = nightlyVersion && tc.find('node', nightlyVersion, osArch);
}
else {
toolPath = tc.find('node', versionSpec, osArch);
}
// If not found in cache, download
if (toolPath) {
core.info(`Found in cache @ ${toolPath}`);
Expand Down Expand Up @@ -73316,6 +73327,11 @@ function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
});
}
exports.getNode = getNode;
function findNightlyVersionInHostedToolcache(versionsSpec, osArch) {
const foundAllVersions = tc.findAllVersions('node', osArch);
const version = evaluateVersions(foundAllVersions, versionsSpec);
return version;
}
function isLtsAlias(versionSpec) {
return versionSpec.startsWith('lts/');
}
Expand Down Expand Up @@ -73382,7 +73398,8 @@ function getInfoFromDist(versionSpec, arch = os.arch(), nodeVersions) {
? `node-v${version}-win-${osArch}`
: `node-v${version}-${osPlat}-${osArch}`;
let urlFileName = osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`;
let url = `https://nodejs.org/dist/v${version}/${urlFileName}`;
const initialUrl = getNodejsDistUrl(versionSpec);
const url = `${initialUrl}/v${version}/${urlFileName}`;
return {
downloadUrl: url,
resolvedVersion: version,
Expand All @@ -73403,10 +73420,51 @@ function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translat
}
});
}
function evaluateNightlyVersions(versions, versionSpec) {
let version = '';
let range;
const [raw, prerelease] = versionSpec.split('-');
const isValidVersion = semver.valid(raw);
const rawVersion = isValidVersion ? raw : semver.coerce(raw);
if (rawVersion) {
if (prerelease !== 'nightly') {
range = `${rawVersion}+${prerelease.replace('nightly', 'nightly.')}`;
}
else {
range = semver.validRange(`^${rawVersion}`);
}
}
if (range) {
versions = versions.sort((a, b) => {
if (semver.gt(a, b)) {
return 1;
}
return -1;
});
for (let i = versions.length - 1; i >= 0; i--) {
const potential = versions[i];
const satisfied = semver.satisfies(potential.replace('-nightly', '+nightly.'), 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 = '';
core.debug(`evaluating ${versions.length} versions`);
if (versionSpec.includes('nightly')) {
return evaluateNightlyVersions(versions, versionSpec);
}
versions = versions.sort((a, b) => {
if (semver.gt(a, b)) {
return 1;
Expand All @@ -73429,6 +73487,18 @@ function evaluateVersions(versions, versionSpec) {
}
return version;
}
function getNodejsDistUrl(version) {
const prerelease = semver.prerelease(version);
if (version.includes('nightly')) {
return 'https://nodejs.org/download/nightly';
}
else if (!prerelease) {
return 'https://nodejs.org/dist';
}
else {
return 'https://nodejs.org/download/rc';
}
}
function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) {
return __awaiter(this, void 0, void 0, function* () {
let osPlat = os.platform();
Expand All @@ -73450,7 +73520,7 @@ function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) {
}
if (!nodeVersions) {
core.debug('No dist manifest cached');
nodeVersions = yield getVersionsFromDist();
nodeVersions = yield getVersionsFromDist(versionSpec);
}
let versions = [];
if (isLatestSyntax(versionSpec)) {
Expand All @@ -73468,9 +73538,10 @@ function queryDistForMatch(versionSpec, arch = os.arch(), nodeVersions) {
return version;
});
}
function getVersionsFromDist() {
function getVersionsFromDist(versionSpec) {
return __awaiter(this, void 0, void 0, function* () {
let dataUrl = 'https://nodejs.org/dist/index.json';
const initialUrl = getNodejsDistUrl(versionSpec);
const dataUrl = `${initialUrl}/index.json`;
let httpClient = new hc.HttpClient('setup-node', [], {
allowRetries: true,
maxRetries: 3
Expand All @@ -73494,6 +73565,7 @@ exports.getVersionsFromDist = getVersionsFromDist;
// and lib file in a folder, not zipped.
function acquireNodeFromFallbackLocation(version, arch = os.arch()) {
return __awaiter(this, void 0, void 0, function* () {
const initialUrl = getNodejsDistUrl(version);
let osPlat = os.platform();
let osArch = translateArchToDistUrl(arch);
// Create temporary folder to download in to
Expand All @@ -73505,8 +73577,8 @@ function acquireNodeFromFallbackLocation(version, arch = os.arch()) {
let exeUrl;
let libUrl;
try {
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
exeUrl = `${initialUrl}/v${version}/win-${osArch}/node.exe`;
libUrl = `${initialUrl}/v${version}/win-${osArch}/node.lib`;
core.info(`Downloading only node binary from ${exeUrl}`);
const exePath = yield tc.downloadTool(exeUrl);
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
Expand All @@ -73515,8 +73587,8 @@ function acquireNodeFromFallbackLocation(version, arch = os.arch()) {
}
catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
exeUrl = `https://nodejs.org/dist/v${version}/node.exe`;
libUrl = `https://nodejs.org/dist/v${version}/node.lib`;
exeUrl = `${initialUrl}/v${version}/node.exe`;
libUrl = `${initialUrl}/v${version}/node.lib`;
const exePath = yield tc.downloadTool(exeUrl);
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = yield tc.downloadTool(libUrl);
Expand Down Expand Up @@ -73607,15 +73679,15 @@ const auth = __importStar(__nccwpck_require__(7573));
const path = __importStar(__nccwpck_require__(1017));
const cache_restore_1 = __nccwpck_require__(9517);
const cache_utils_1 = __nccwpck_require__(1678);
const os = __nccwpck_require__(2037);
const os_1 = __importDefault(__nccwpck_require__(2037));
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
//
// Version is optional. If supplied, install / use from the tool cache
// If not supplied then task is still used to setup proxy, auth, etc...
//
let version = resolveVersionInput();
const version = resolveVersionInput();
let arch = core.getInput('architecture');
const cache = core.getInput('cache');
// if architecture supplied but node-version is not
Expand All @@ -73624,12 +73696,12 @@ function run() {
core.warning('`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed. To fix this, provide `architecture` in combination with `node-version`');
}
if (!arch) {
arch = os.arch();
arch = os_1.default.arch();
}
if (version) {
let token = core.getInput('token');
let auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`;
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const token = core.getInput('token');
const auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`;
const stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
yield installer.getNode(version, stable, checkLatest, auth, arch);
}
Expand Down
Loading