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

Expose the ability to select different architectures #42

Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
This action sets by node environment for use in actions by:

- optionally downloading and caching a version of node - npm by version spec and add to PATH
- registering problem matchers for error output
- registering problem matchers for error output

# Usage

Expand Down Expand Up @@ -100,6 +100,18 @@ steps:
- run: npm rebuild && npm run prepare --if-present
```

Specifying a different architecture than the system architecture:
```yaml
steps:
- uses: actions/checkout@master
- uses: actions/setup-node@v1
with:
node-version: '10.x'
node-arch: 'x86'
Copy link
Member

Choose a reason for hiding this comment

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

As this is an advanced option, I don't want the readme and straight forward example to have it.

Copy link
Member

Choose a reason for hiding this comment

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

Many folks copy and paste to get started and installing x86 is definately a minor case. It's ok to note further down in the readme that node-arch is an option and list it's possible values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can understand that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the README.md accordingly. Let me know if you have something different in mind.

- run: npm install
- run: npm test
```


# License

Expand Down
Binary file not shown.
Binary file added __tests__/__fixtures__/mock-node-v8.8.0-win-x86.7z
Binary file not shown.
Binary file not shown.
Binary file added __tests__/__fixtures__/mock-node-v8.9.1-win-x64.7z
Binary file not shown.
63 changes: 63 additions & 0 deletions __tests__/installer.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import io = require('@actions/io');
import fs = require('fs');
import nock = require('nock');
import os = require('os');
import path = require('path');

Expand Down Expand Up @@ -36,6 +37,10 @@ describe('installer tests', () => {
await io.rmRF(tempDir);
}, 100000);

beforeEach(() => {
nock.cleanAll();
});

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());
Expand Down Expand Up @@ -120,4 +125,62 @@ describe('installer tests', () => {
await installer.getNode('252');
await installer.getNode('252.0');
});

it('Acquires specified x86 version of node if no matching version is installed', async () => {
implausible marked this conversation as resolved.
Show resolved Hide resolved
const arch = 'x86';
const version = '8.8.0';
const fileExtension = IS_WINDOWS ? '7z' : 'tar.gz';
const platform = {
linux: 'linux',
darwin: 'darwin',
win32: 'win'
}[process.platform];
const fileName = `node-v${version}-${platform}-${arch}.${fileExtension}`;
const pathOnNodeJs = `/dist/v${version}/${fileName}`;
const scope = nock('https://nodejs.org')
.get(pathOnNodeJs)
.replyWithFile(
200,
path.join(__dirname, '__fixtures__', `mock-${fileName}`)
);
await installer.getNode(version, arch);
const nodeDir = path.join(toolDir, 'node', version, arch);

expect(scope.isDone()).toBe(true);
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('Acquires specified x64 version of node if no matching version is installed', async () => {
const arch = 'x64';
const version = '8.9.1';
const fileExtension = IS_WINDOWS ? '7z' : 'tar.gz';
const platform = {
linux: 'linux',
darwin: 'darwin',
win32: 'win'
}[process.platform];
const fileName = `node-v${version}-${platform}-${arch}.${fileExtension}`;
const pathOnNodeJs = `/dist/v${version}/${fileName}`;
const scope = nock('https://nodejs.org')
.get(pathOnNodeJs)
.replyWithFile(
200,
path.join(__dirname, '__fixtures__', `mock-${fileName}`)
);
await installer.getNode(version, arch);
const nodeDir = path.join(toolDir, 'node', version, arch);

expect(scope.isDone()).toBe(true);
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);
});
2 changes: 2 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ inputs:
node-version:
description: 'Version Spec of the version to use. Examples: 10.x, 10.15.1, >=10.15.0'
default: '10.x'
node-arch:
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
registry-url:
description: 'Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN'
scope:
Expand Down
31 changes: 15 additions & 16 deletions lib/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const os = __importStar(require("os"));
const path = __importStar(require("path"));
const semver = __importStar(require("semver"));
let osPlat = os.platform();
let osArch = os.arch();
if (!tempDirectory) {
let baseLocation;
if (process.platform === 'win32') {
Expand All @@ -42,11 +41,11 @@ if (!tempDirectory) {
}
tempDirectory = path.join(baseLocation, 'actions', 'temp');
}
function getNode(versionSpec) {
function getNode(versionSpec, osArch = os.arch()) {
return __awaiter(this, void 0, void 0, function* () {
// check cache
let toolPath;
toolPath = tc.find('node', versionSpec);
toolPath = tc.find('node', versionSpec, osArch);
// If not found in cache, download
if (!toolPath) {
let version;
Expand All @@ -58,16 +57,16 @@ function getNode(versionSpec) {
}
else {
// query nodejs.org for a matching version
version = yield queryLatestMatch(versionSpec);
version = yield queryLatestMatch(versionSpec, osArch);
if (!version) {
throw new Error(`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`);
}
// check cache
toolPath = tc.find('node', version);
toolPath = tc.find('node', version, osArch);
}
if (!toolPath) {
// download, extract, cache
toolPath = yield acquireNode(version);
toolPath = yield acquireNode(version, osArch);
}
}
//
Expand All @@ -84,7 +83,7 @@ function getNode(versionSpec) {
});
}
exports.getNode = getNode;
function queryLatestMatch(versionSpec) {
function queryLatestMatch(versionSpec, osArch) {
return __awaiter(this, void 0, void 0, function* () {
// node offers a json list of versions
let dataFileName;
Expand Down Expand Up @@ -142,15 +141,15 @@ function evaluateVersions(versions, versionSpec) {
}
return version;
}
function acquireNode(version) {
function acquireNode(version, osArch) {
return __awaiter(this, void 0, void 0, function* () {
//
// Download - a tool installer intimately knows how to get the tool (and construct urls)
//
version = semver.clean(version) || '';
let fileName = osPlat == 'win32'
? 'node-v' + version + '-win-' + os.arch()
: 'node-v' + version + '-' + osPlat + '-' + os.arch();
? 'node-v' + version + '-win-' + osArch
: 'node-v' + version + '-' + osPlat + '-' + osArch;
let urlFileName = osPlat == 'win32' ? fileName + '.7z' : fileName + '.tar.gz';
let downloadUrl = 'https://nodejs.org/dist/v' + version + '/' + urlFileName;
let downloadPath;
Expand All @@ -159,7 +158,7 @@ function acquireNode(version) {
}
catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
return yield acquireNodeFromFallbackLocation(version);
return yield acquireNodeFromFallbackLocation(version, osArch);
}
throw err;
}
Expand All @@ -178,7 +177,7 @@ function acquireNode(version) {
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
//
let toolRoot = path.join(extPath, fileName);
return yield tc.cacheDir(toolRoot, 'node', version);
return yield tc.cacheDir(toolRoot, 'node', version, osArch);
});
}
// For non LTS versions of Node, the files we need (for Windows) are sometimes located
Expand All @@ -193,7 +192,7 @@ function acquireNode(version) {
// This method attempts to download and cache the resources from these alternative locations.
// Note also that the files are normally zipped but in this case they are just an exe
// and lib file in a folder, not zipped.
function acquireNodeFromFallbackLocation(version) {
function acquireNodeFromFallbackLocation(version, osArch) {
return __awaiter(this, void 0, void 0, function* () {
// Create temporary folder to download in to
let tempDownloadFolder = 'temp_' + Math.floor(Math.random() * 2000000000);
Expand All @@ -202,8 +201,8 @@ function acquireNodeFromFallbackLocation(version) {
let exeUrl;
let libUrl;
try {
exeUrl = `https://nodejs.org/dist/v${version}/win-${os.arch()}/node.exe`;
libUrl = `https://nodejs.org/dist/v${version}/win-${os.arch()}/node.lib`;
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
const exePath = yield tc.downloadTool(exeUrl);
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = yield tc.downloadTool(libUrl);
Expand All @@ -222,6 +221,6 @@ function acquireNodeFromFallbackLocation(version) {
throw err;
}
}
return yield tc.cacheDir(tempDir, 'node', version);
return yield tc.cacheDir(tempDir, 'node', version, osArch);
});
}
4 changes: 3 additions & 1 deletion lib/setup-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(require("@actions/core"));
const installer = __importStar(require("./installer"));
const auth = __importStar(require("./authutil"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
function run() {
return __awaiter(this, void 0, void 0, function* () {
Expand All @@ -31,8 +32,9 @@ function run() {
version = core.getInput('node-version');
}
if (version) {
const osArch = core.getInput('node-arch') || os.arch();
// TODO: installer doesn't support proxy
yield installer.getNode(version);
yield installer.getNode(version, osArch);
}
const registryUrl = core.getInput('registry-url');
const alwaysAuth = core.getInput('always-auth');
Expand Down