Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
initial logic
  • Loading branch information
dmitry-shibanov committed Oct 19, 2022
commit 06981c41e35bc124ffa90eb478be66162f9eca3f
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]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice we test the version range syntax here and exact versions for RC. But, we support both for both cases, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the rc versions it's required to specify the full version. Semver does not support range for rc versions that is why we use the same behaviour as for setup-go https://github.com/actions/setup-go. Besides, nightly syntax is not included to SemVer that is why we use similar approach as for setup-python pypy: https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#specifying-a-pypy-version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Do we want to test an exact version for nightly at least?

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