Add support for node version codename

Refactored for optimization and maintainability
This commit is contained in:
Jimi (Dimitris) Charalampidis 2019-09-13 13:15:45 +03:00
parent 7a3ce83626
commit 62a25ae2c2
No known key found for this signature in database
GPG key ID: 36C7F609B733BD60
10 changed files with 507 additions and 401 deletions

View file

@ -1,30 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`installer tests Appends trailing slash to registry 1`] = `
exports[`auth tests Appends trailing slash to registry 1`] = `
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
registry=https://registry.npmjs.org/
always-auth=false"
`;
exports[`installer tests Automatically configures GPR scope 1`] = `
exports[`auth tests Automatically configures GPR scope 1`] = `
"npm.pkg.github.com/:_authToken=\${NODE_AUTH_TOKEN}
@ownername:registry=npm.pkg.github.com/
always-auth=false"
`;
exports[`installer tests Configures scoped npm registries 1`] = `
exports[`auth tests Configures scoped npm registries 1`] = `
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
@myscope:registry=https://registry.npmjs.org/
always-auth=false"
`;
exports[`installer tests Sets up npmrc for always-auth true 1`] = `
exports[`auth tests Sets up npmrc for always-auth true 1`] = `
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
registry=https://registry.npmjs.org/
always-auth=true"
`;
exports[`installer tests Sets up npmrc for npmjs 1`] = `
exports[`auth tests Sets up npmrc for npmjs 1`] = `
"//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}
registry=https://registry.npmjs.org/
always-auth=false"

View file

@ -1,25 +1,20 @@
import io = require('@actions/io');
import fs = require('fs');
import path = require('path');
const tempDir = path.join(
__dirname,
'runner',
path.join(
Math.random()
.toString(36)
.substring(7)
),
'temp'
);
import * as io from '@actions/io';
import * as fs from 'fs';
import * as path from'path';
const runnerDir = path.join(__dirname, 'runner');
const randomizer = () =>
Math.random()
.toString(36)
.substring(7);
const tempDir = path.join(runnerDir, randomizer(), 'temp');
const rcFile = path.join(tempDir, '.npmrc');
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
process.env['RUNNER_TEMP'] = tempDir;
import * as auth from '../src/authutil';
describe('installer tests', () => {
describe('auth tests', () => {
beforeAll(async () => {
await io.rmRF(tempDir);
await io.mkdirP(tempDir);
@ -32,36 +27,36 @@ describe('installer tests', () => {
process.env['INPUT_SCOPE'] = '';
});
it('Sets up npmrc for npmjs', async () => {
await auth.configAuthentication('https://registry.npmjs.org/', 'false');
it('Sets up npmrc for npmjs', () => {
auth.configAuthentication('https://registry.npmjs.org/', 'false');
expect(fs.existsSync(rcFile)).toBe(true);
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
});
it('Appends trailing slash to registry', async () => {
await auth.configAuthentication('https://registry.npmjs.org', 'false');
it('Appends trailing slash to registry', () => {
auth.configAuthentication('https://registry.npmjs.org', 'false');
expect(fs.existsSync(rcFile)).toBe(true);
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
});
it('Configures scoped npm registries', async () => {
it('Configures scoped npm registries', () => {
process.env['INPUT_SCOPE'] = 'myScope';
await auth.configAuthentication('https://registry.npmjs.org', 'false');
auth.configAuthentication('https://registry.npmjs.org', 'false');
expect(fs.existsSync(rcFile)).toBe(true);
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
});
it('Automatically configures GPR scope', async () => {
await auth.configAuthentication('npm.pkg.github.com', 'false');
it('Automatically configures GPR scope', () => {
auth.configAuthentication('npm.pkg.github.com', 'false');
expect(fs.existsSync(rcFile)).toBe(true);
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
});
it('Sets up npmrc for always-auth true', async () => {
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
it('Sets up npmrc for always-auth true', () => {
auth.configAuthentication('https://registry.npmjs.org/', 'true');
expect(fs.existsSync(rcFile)).toBe(true);
expect(fs.readFileSync(rcFile, {encoding: 'utf8'})).toMatchSnapshot();
});

View file

@ -1,123 +1,255 @@
import io = require('@actions/io');
import fs = require('fs');
import os = require('os');
import path = require('path');
import * as io from '@actions/io';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as semver from 'semver';
import * as restm from 'typed-rest-client/RestClient';
const toolDir = path.join(
__dirname,
'runner',
path.join(
Math.random()
.toString(36)
.substring(7)
),
'tools'
);
const tempDir = path.join(
__dirname,
'runner',
path.join(
Math.random()
.toString(36)
.substring(7)
),
'temp'
);
const IS_WINDOWS = process.platform === 'win32';
const osArch = os.arch();
const runnerDir = path.join(__dirname, 'runner');
const randomizer = () =>
Math.random()
.toString(36)
.substring(7);
const toolDir = path.join(runnerDir, randomizer(), 'tools');
const tempDir = path.join(runnerDir, randomizer(), 'temp');
process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir;
import * as installer from '../src/installer';
const IS_WINDOWS = process.platform === 'win32';
describe('installer tests', () => {
beforeAll(async () => {
await io.rmRF(toolDir);
await io.rmRF(tempDir);
}, 100000);
it('Acquires version of node if no matching version is installed', async () => {
await installer.getNode('10.16.0');
const nodeDir = path.join(toolDir, 'node', '10.16.0', os.arch());
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(nodeDir, 'bin', 'node'))).toBe(true);
}
}, 100000);
if (IS_WINDOWS) {
it('Falls back to backup location if first one doesnt contain correct version', async () => {
it(`Falls back to backup location if first one doesn't contain correct version`, async () => {
await installer.getNode('5.10.1');
const nodeDir = path.join(toolDir, 'node', '5.10.1', os.arch());
const nodeDir = path.join(toolDir, 'node', '5.10.1', osArch);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
}, 100000);
it('Falls back to third location if second one doesnt contain correct version', async () => {
it(`Falls back to third location if second one doesn't contain correct version`, async () => {
await installer.getNode('0.12.18');
const nodeDir = path.join(toolDir, 'node', '0.12.18', os.arch());
const nodeDir = path.join(toolDir, 'node', '0.12.18', osArch);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
}, 100000);
}
it('Throws if no location contains correct node version', async () => {
let thrown = false;
try {
await installer.getNode('1000');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
});
it('Acquires version of node with long paths', async () => {
const toolpath = await installer.getNode('8.8.1');
const nodeDir = path.join(toolDir, 'node', '8.8.1', os.arch());
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(nodeDir, 'bin', 'node'))).toBe(true);
}
}, 100000);
it('Uses version of node installed in cache', async () => {
const nodeDir: string = path.join(toolDir, 'node', '250.0.0', os.arch());
const nodeDir: string = path.join(toolDir, 'node', '250.0.0', osArch);
await io.mkdirP(nodeDir);
fs.writeFileSync(`${nodeDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache (because no such version exists)
await installer.getNode('250.0.0');
return;
});
it('Doesnt use version of node that was only partially installed in cache', async () => {
const nodeDir: string = path.join(toolDir, 'node', '251.0.0', os.arch());
it(`Doesn't use version of node that was only partially installed in cache`, async () => {
const nodeDir: string = path.join(toolDir, 'node', '251.0.0', osArch);
await io.mkdirP(nodeDir);
let thrown = false;
try {
// This will throw if it doesn't find it in the cache (because no such version exists)
await installer.getNode('251.0.0');
} catch {
thrown = true;
} catch (error) {
expect(error).toBeInstanceOf(Error);
}
expect(thrown).toBe(true);
return;
});
it('Resolves semantic versions of node installed in cache', async () => {
const nodeDir: string = path.join(toolDir, 'node', '252.0.0', os.arch());
await io.mkdirP(nodeDir);
fs.writeFileSync(`${nodeDir}.complete`, 'hello');
// These will throw if it doesn't find it in the cache (because no such version exists)
await installer.getNode('252.0.0');
await installer.getNode('252');
await installer.getNode('252.0');
describe('Throws', () => {
it('on unknown node version codename', async () => {
try {
await installer.getNode('potterium');
} catch (error) {
expect(error).toBeInstanceOf(Error);
}
});
it('if no location contains correct node version', async () => {
try {
await installer.getNode('1000');
} catch (error) {
expect(error).toBeInstanceOf(Error);
}
});
});
describe(`Acquires version of node if no matching version is installed of pattern`, () => {
it(`'x'`, async () => {
await installer.getNode('6');
const nodeDir = path.join(toolDir, 'node', '6.17.1', osArch);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(nodeDir, 'bin', 'node'))).toBe(true);
}
}, 100000);
it(`'x.x'`, async () => {
await installer.getNode('6.x');
const nodeDir = path.join(toolDir, 'node', '6.17.1', osArch);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(nodeDir, 'bin', 'node'))).toBe(true);
}
}, 100000);
it(`'x.x.x'`, async () => {
await installer.getNode('6.17.1');
const nodeDir = path.join(toolDir, 'node', '6.17.1', osArch);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(nodeDir, 'node.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(nodeDir, 'bin', 'node'))).toBe(true);
}
}, 100000);
});
describe(`Resolves`, () => {
let getLatestNodeVersionOf: (
predicator: (...args: any[]) => boolean
) => string;
beforeAll(async () => {
const restClient = new restm.RestClient('setup-node');
const request = await restClient.get<installer.INodeVersion[]>(
'https://nodejs.org/dist/index.json'
);
const nodeVersions = request.result || [];
const osPlat = IS_WINDOWS
? 'win'
: process.platform === 'darwin'
? 'osx'
: 'linux';
getLatestNodeVersionOf = (predicator: (...args: any[]) => boolean) => {
const osPlatArchRegExp = new RegExp(
`^${osPlat}-${osArch}-?(?:7z|tar)?`
);
const version = nodeVersions
.filter((version: installer.INodeVersion) =>
version.files.some((file: string) => osPlatArchRegExp.test(file))
)
.filter(predicator)
.sort((a: installer.INodeVersion, b: installer.INodeVersion) =>
semver.gt(b.version, a.version) ? 1 : -1
)[0].version;
return semver.clean(version) || '';
};
});
it('semantic versions of node installed in cache', async () => {
const nodeDir: string = path.join(toolDir, 'node', '252.0.0', osArch);
await io.mkdirP(nodeDir);
fs.writeFileSync(`${nodeDir}.complete`, 'hello');
// These will throw if it doesn't find it in the cache (because no such version exists)
await installer.getNode('252.0.0');
await installer.getNode('252');
await installer.getNode('252.0');
});
it(`'latest' to latest node version`, async () => {
await installer.getNode('latest');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf(
(nv: installer.INodeVersion) => typeof nv.lts !== 'string'
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'current' to current node version`, async () => {
await installer.getNode('current');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf(
(nv: installer.INodeVersion) => typeof nv.lts !== 'string'
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'lts' to latest LTS node version`, async () => {
await installer.getNode('lts');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf(
(nv: installer.INodeVersion) => typeof nv.lts === 'string'
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'argon' to latest node version 4`, async () => {
await installer.getNode('argon');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf((nv: installer.INodeVersion) =>
/v4.\d+.\d+/.test(nv.version)
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'boron' to latest node version 6`, async () => {
await installer.getNode('boron');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf((nv: installer.INodeVersion) =>
/v6.\d+.\d+/.test(nv.version)
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'carbon' to latest node version 8`, async () => {
await installer.getNode('carbon');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf((nv: installer.INodeVersion) =>
/v8.\d+.\d+/.test(nv.version)
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
it(`'dubnium' to latest node version 10`, async () => {
await installer.getNode('dubnium');
const nodeDir = path.join(
toolDir,
'node',
getLatestNodeVersionOf((nv: installer.INodeVersion) =>
/v10.\d+.\d+/.test(nv.version)
),
osArch
);
expect(fs.existsSync(`${nodeDir}.complete`)).toBe(true);
}, 100000);
});
});