1
0
mirror of https://github.com/actions/setup-node.git synced 2025-12-17 22:38:59 +08:00

Compare commits

..

8 Commits

Author SHA1 Message Date
Bryan MacFarlane
efab84ad3c dist 2020-05-02 11:12:54 -04:00
Bryan MacFarlane
8a1d983ace format 2020-05-02 11:08:26 -04:00
Bryan MacFarlane
22c0aea623 cya snapshot 2020-05-02 11:06:05 -04:00
Bryan MacFarlane
1c2f59fb67 format 2020-05-02 10:46:48 -04:00
Bryan MacFarlane
ec6092f7d2 dbg 2020-05-02 10:45:32 -04:00
Bryan MacFarlane
889def385d update ts-jest 2020-05-02 10:38:09 -04:00
Bryan MacFarlane
8885b7194e updated tests 2020-05-02 09:51:47 -04:00
Bryan MacFarlane
ecf0ce62f9 wip 2020-04-24 08:58:38 -04:00
73 changed files with 233 additions and 1353 deletions

5
.gitattributes vendored
View File

@@ -1,5 +0,0 @@
# Set default behavior to automatically normalize line endings, and force everything to be LF, except for Windows batch files that require CRLF, so that if a repo is accessed in Unix via a file share from Windows, the scripts will work.
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
.licenses/** -diff linguist-generated=true

View File

@@ -1,32 +0,0 @@
name: build-test
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
jobs:
build:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node 12
uses: actions/setup-node@v1
with:
node-version: 12.x
- run: npm ci
- run: npm run build
- run: npm run format-check
- run: npm test
- name: Verify no unstaged changes
if: runner.os != 'windows'
run: __tests__/verify-no-unstaged-changes.sh

View File

@@ -1,20 +0,0 @@
name: Licensed
on:
push: {branches: main}
pull_request: {branches: main}
jobs:
test:
runs-on: ubuntu-latest
name: Check licenses
steps:
- uses: actions/checkout@v2
- run: npm ci
- name: Install licensed
run: |
cd $RUNNER_TEMP
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
sudo tar -xzf licensed.tar.gz
sudo mv licensed /usr/local/bin/licensed
- run: licensed status

View File

@@ -1,56 +0,0 @@
name: proxy
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- master
- releases/*
paths-ignore:
- '**.md'
jobs:
test-proxy:
runs-on: ubuntu-latest
strategy:
fail-fast: false
container:
image: ubuntu:latest
options: --dns 127.0.0.1
services:
squid-proxy:
image: datadog/squid:latest
ports:
- 3128:3128
env:
https_proxy: http://squid-proxy:3128
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 10
uses: ./
with:
node-version: 10.x
- name: Verify node and npm
run: __tests__/verify-node.sh 10
test-bypass-proxy:
runs-on: ubuntu-latest
strategy:
fail-fast: false
env:
https_proxy: http://no-such-proxy:3128
no_proxy: api.github.com,github.com,nodejs.org,registry.npmjs.org,*.s3.amazonaws.com,s3.amazonaws.com
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 11
uses: ./
with:
node-version: 11
- name: Verify node and npm
run: __tests__/verify-node.sh 11

View File

@@ -1,112 +0,0 @@
name: versions
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
jobs:
local-cache:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash
manifest:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10.15, 12.16.0, 14.2.0]
steps:
- uses: actions/checkout@v2
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash
check-latest:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 11, 12, 14]
steps:
- uses: actions/checkout@v2
- name: Setup Node and check latest
uses: ./
with:
node-version: ${{ matrix.node-version }}
check-latest: true
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash
node-dist:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
node-version: [11, 13]
steps:
- uses: actions/checkout@v2
- name: Setup Node from dist
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Verify node and npm
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash
old-versions:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
# test old versions which didn't have npm and layout different
- name: Setup node 0.12.18 from dist
uses: ./
with:
node-version: 0.12.18
- name: Verify node
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
shell: bash
arch:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Setup node 12 x86 from dist
uses: ./
with:
node-version: '12'
architecture: 'x86'
- name: Verify node
run: __tests__/verify-arch.sh "ia32"
shell: bash

94
.github/workflows/workflow.yml vendored Normal file
View File

@@ -0,0 +1,94 @@
name: Main workflow
on:
pull_request:
push:
branches:
- master
- releases/*
jobs:
build:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
operating-system: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node 12
uses: actions/setup-node@v1
with:
node-version: 12.x
- run: npm ci
- run: npm run build
- run: npm run format-check
- run: npm test
- name: Verify no unstaged changes
if: runner.os != 'windows'
run: __tests__/verify-no-unstaged-changes.sh
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 10
uses: ./
with:
node-version: 10.x
- name: Verify node and npm
run: __tests__/verify-node.sh 10
test-fallback:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
- name: Setup node 0.12.18 # For non LTS versions of Node, the zip is not always available
uses: ./ # and falls back to downloading node.exe and node.lib
with:
node-version: 0.12.18
- name: Verify node
shell: bash
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
test-proxy:
runs-on: ubuntu-latest
container:
image: ubuntu:latest
options: --dns 127.0.0.1
services:
squid-proxy:
image: datadog/squid:latest
ports:
- 3128:3128
env:
https_proxy: http://squid-proxy:3128
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 10
uses: ./
with:
node-version: 10.x
- name: Verify node and npm
run: __tests__/verify-node.sh 10
test-bypass-proxy:
runs-on: ubuntu-latest
env:
https_proxy: http://no-such-proxy:3128
no_proxy: github.com,nodejs.org,registry.npmjs.org
steps:
- uses: actions/checkout@v2
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 10
uses: ./
with:
node-version: 10.x
- name: Verify node and npm
run: __tests__/verify-node.sh 10

View File

@@ -1,14 +0,0 @@
sources:
npm: true
allowed:
- apache-2.0
- bsd-2-clause
- bsd-3-clause
- isc
- mit
- cc0-1.0
- unlicense
reviewed:
npm:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
* @actions/spark

View File

@@ -1,30 +1,13 @@
# setup-node
<p align="left">
<a href="https://github.com/actions/setup-node/actions?query=workflow%3Abuild-test"><img alt="build-test status" src="https://github.com/actions/setup-node/workflows/build-test/badge.svg"></a> <a href="https://github.com/actions/setup-node/actions?query=workflow%3Aversions"><img alt="versions status" src="https://github.com/actions/setup-node/workflows/versions/badge.svg"></a> <a href="https://github.com/actions/setup-node/actions?query=workflow%3Aproxy"><img alt="proxy status" src="https://github.com/actions/setup-node/workflows/proxy/badge.svg"></a>
<a href="https://github.com/actions/setup-node"><img alt="GitHub Actions status" src="https://github.com/actions/setup-node/workflows/Main%20workflow/badge.svg"></a>
</p>
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
- configuring authentication for GPR or npm
# v2-beta
A beta release which adds reliability for pulling node distributions from a cache of node releases is available by referencing the `v2-beta` tag.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
with:
node-version: '12'
```
It will first check the local cache for a semver match. The hosted images have been updated with the latest of each LTS from v8, v10, v12, and v14. `self-hosted` machines will benefit from the cache as well only downloading once. It will pull LTS versions from `main` branch of [node-versions](https://github.com/actions/node-versions/blob/main/versions-manifest.json) repository and on miss or failure, it will fall back to the previous behavior of download directly from [node dist](https://nodejs.org/dist/).
The `node-version` input is optional. If not supplied, node which is in your PATH will be used. However, this action will still register problem matchers and support auth features. So setting up the node environment is still a valid scenario without downloading and caching versions.
- registering problem matchers for error output
# Usage
@@ -36,21 +19,7 @@ steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12'
- run: npm install
- run: npm test
```
Check latest version:
> In basic example, without `check-latest` flag, the action tries to resolve version from local cache firstly and download only if it is not found. Local cache on image is updated with a couple of weeks latency.
`check-latest` flag forces the action to check if the cached version is the latest one. It reduces latency significantly but it is much more likely to incur version downloading.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
with:
node-version: '12'
check-latest: true
node-version: '10.x'
- run: npm install
- run: npm test
```
@@ -62,7 +31,7 @@ jobs:
runs-on: ubuntu-16.04
strategy:
matrix:
node: [ '10', '12' ]
node: [ '10', '8' ]
name: Node ${{ matrix.node }} sample
steps:
- uses: actions/checkout@v2
@@ -74,61 +43,6 @@ jobs:
- run: npm test
```
Architecture:
You can use any of the [supported operating systems](https://docs.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners), and the compatible `architecture` can be selected using `architecture`. Values are `x86`, `x64`, `arm64`, `armv6l`, `armv7l`, `ppc64le`, `s390x` (not all of the architectures are available on all platforms).
When using `architecture`, `node-version` must be provided as well.
```yaml
jobs:
build:
runs-on: windows-latest
name: Node sample
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '12'
architecture: 'x64' # optional, x64 or x86. If not specified, x64 will be used by default
- run: npm install
- run: npm test
```
Multiple Operating Systems and Architectures:
```yaml
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
node_version:
- 10
- 12
- 14
architecture:
- x64
# an extra windows-x86 run:
include:
- os: windows-2016
node_version: 12
architecture: x86
name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}
architecture: ${{ matrix.architecture }}
- run: npm install
- run: npm test
```
Publish to npmjs and GPR with npm:
```yaml
steps:

View File

@@ -20,8 +20,6 @@ describe('authutil tests', () => {
.toString(36)
.substring(7)
);
console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
const tempDir = path.join(_runnerDir, randPath, 'temp');
await io.rmRF(tempDir);
await io.mkdirP(tempDir);
@@ -63,7 +61,6 @@ describe('authutil tests', () => {
if (_runnerDir) {
await io.rmRF(_runnerDir);
}
console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
}, 100000);
function readRcFile(rcFile: string) {

View File

@@ -8,7 +8,6 @@ import path from 'path';
import * as main from '../src/main';
import * as im from '../src/installer';
import * as auth from '../src/authutil';
import {context} from '@actions/github';
let nodeTestManifest = require('./data/versions-manifest.json');
let nodeTestDist = require('./data/node-dist-index.json');
@@ -25,7 +24,6 @@ describe('setup-node', () => {
let findSpy: jest.SpyInstance;
let cnSpy: jest.SpyInstance;
let logSpy: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance;
let getDistSpy: jest.SpyInstance;
let platSpy: jest.SpyInstance;
@@ -42,8 +40,6 @@ describe('setup-node', () => {
beforeEach(() => {
// @actions/core
console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
inputs = {};
inSpy = jest.spyOn(core, 'getInput');
inSpy.mockImplementation(name => inputs[name]);
@@ -81,9 +77,8 @@ describe('setup-node', () => {
// writes
cnSpy = jest.spyOn(process.stdout, 'write');
logSpy = jest.spyOn(core, 'info');
logSpy = jest.spyOn(console, 'log');
dbgSpy = jest.spyOn(core, 'debug');
warningSpy = jest.spyOn(core, 'warning');
cnSpy.mockImplementation(line => {
// uncomment to debug
// process.stderr.write('write:' + line + '\n');
@@ -104,9 +99,7 @@ describe('setup-node', () => {
//jest.restoreAllMocks();
});
afterAll(async () => {
console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
}, 100000);
afterAll(async () => {}, 100000);
//--------------------------------------------------
// Manifest find tests
@@ -252,7 +245,7 @@ describe('setup-node', () => {
expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`Acquiring ${resolvedVersion} - ${os.arch} from ${expectedUrl}`
`Acquiring ${resolvedVersion} from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
@@ -340,194 +333,4 @@ describe('setup-node', () => {
expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
});
it('Acquires specified architecture of node', async () => {
for (const {arch, version, osSpec} of [
{arch: 'x86', version: '12.16.2', osSpec: 'win32'},
{arch: 'x86', version: '14.0.0', osSpec: 'win32'}
]) {
os.platform = osSpec;
os.arch = arch;
const fileExtension = os.platform === 'win32' ? '7z' : 'tar.gz';
const platform = {
linux: 'linux',
darwin: 'darwin',
win32: 'win'
}[os.platform];
inputs['node-version'] = version;
inputs['architecture'] = arch;
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
let expectedUrl =
arch === 'x64'
? `https://github.com/actions/node-versions/releases/download/${version}/node-${version}-${platform}-${arch}.zip`
: `https://nodejs.org/dist/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize(`/cache/node/${version}/${arch}`);
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
expect(dlSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
`Acquiring ${version} - ${arch} from ${expectedUrl}`
);
}
}, 100000);
describe('check-latest flag', () => {
it('use local version and dont check manifest if check-latest is not specified', async () => {
os.platform = 'linux';
os.arch = 'x64';
inputs['node-version'] = '12';
inputs['check-latest'] = 'false';
const toolPath = path.normalize('/cache/node/12.16.1/x64');
findSpy.mockReturnValue(toolPath);
await main.run();
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(logSpy).not.toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
});
it('check latest version and resolve it from local cache', async () => {
os.platform = 'linux';
os.arch = 'x64';
inputs['node-version'] = '12';
inputs['check-latest'] = 'true';
const toolPath = path.normalize('/cache/node/12.16.2/x64');
findSpy.mockReturnValue(toolPath);
dlSpy.mockImplementation(async () => '/some/temp/path');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
});
it('check latest version and install it from manifest', async () => {
os.platform = 'linux';
os.arch = 'x64';
inputs['node-version'] = '12';
inputs['check-latest'] = 'true';
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/node/12.16.2/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
const expectedUrl =
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';
await main.run();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
expect(logSpy).toHaveBeenCalledWith(
`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
});
it('fallback to dist if version if not found in manifest', async () => {
os.platform = 'linux';
os.arch = 'x64';
// a version which is not in the manifest but is in node dist
let versionSpec = '11';
inputs['node-version'] = versionSpec;
inputs['check-latest'] = 'true';
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/node/11.11.0/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
`Failed to resolve version ${versionSpec} from manifest`
);
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
it('fallback to dist if manifest is not available', async () => {
os.platform = 'linux';
os.arch = 'x64';
// a version which is not in the manifest but is in node dist
let versionSpec = '12';
inputs['node-version'] = versionSpec;
inputs['check-latest'] = 'true';
inputs['always-auth'] = false;
inputs['token'] = 'faketoken';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
getManifestSpy.mockImplementation(() => {
throw new Error('Unable to download manifest');
});
dlSpy.mockImplementation(async () => '/some/temp/path');
let toolPath = path.normalize('/cache/node/12.11.0/x64');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(exSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve the latest version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
'Unable to resolve version from manifest...'
);
expect(logSpy).toHaveBeenCalledWith(
`Failed to resolve version ${versionSpec} from manifest`
);
expect(logSpy).toHaveBeenCalledWith(
`Attempting to download ${versionSpec}...`
);
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
});
});

View File

@@ -1,11 +0,0 @@
#!/bin/sh
if [ -n "$1" ]; then
architecture="$(node -e 'console.log(process.arch)')"
if [ -z "$(echo $architecture | grep --fixed-strings $1)" ]; then
echo "Unexpected architecture"
exit 1
fi
else
echo "Skip testing architecture"
fi

View File

@@ -7,11 +7,6 @@ inputs:
default: 'false'
node-version:
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0'
architecture:
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
check-latest:
description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec'
default: false
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:

692
dist/index.js vendored

File diff suppressed because it is too large Load Diff

25
package-lock.json generated
View File

@@ -5,14 +5,14 @@
"requires": true,
"dependencies": {
"@actions/core": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.2.tgz",
"integrity": "sha512-IbCx7oefq+Gi6FWbSs2Fnw8VkEI6Y4gvjrYprY3RV//ksq/KPMlClOerJ4jRosyal6zkUIc8R9fS/cpRMlGClg=="
},
"@actions/exec": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.4.tgz",
"integrity": "sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.3.tgz",
"integrity": "sha512-TogJGnueOmM7ntCi0ASTUj4LapRRtDfj57Ja4IhPmg2fls28uVOPbAn8N+JifaOumN2UG3oEO/Ixek2A4NcYSA==",
"requires": {
"@actions/io": "^1.0.1"
}
@@ -40,11 +40,11 @@
"integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg=="
},
"@actions/tool-cache": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.5.4.tgz",
"integrity": "sha512-72ijIBM0s/dx2D0eYYxaxaeKWeVatOK8OHPNctJ5cyKjZp1j12egX+nW/N+tnQRNMVxTp9WjudZO5wizUBxC/w==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.5.2.tgz",
"integrity": "sha512-40A1St0GEo+QvHV1YRjStEoQcKKMaip+zNXPgGHcjYXCdZ7cl1LGlwOpsVVqwk+6ue/shFTS76KC1A02mVVCQA==",
"requires": {
"@actions/core": "^1.2.3",
"@actions/core": "^1.2.0",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.1",
@@ -52,11 +52,6 @@
"uuid": "^3.3.2"
},
"dependencies": {
"@actions/core": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.4.tgz",
"integrity": "sha512-YJCEq8BE3CdN8+7HPZ/4DxJjk/OkZV2FFIf+DlZTC/4iBlzYCD5yjRR6eiOS5llO11zbRltIRuKAjMKaWTE6cg=="
},
"@actions/http-client": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz",

View File

@@ -23,12 +23,11 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.3",
"@actions/core": "^1.2.2",
"@actions/github": "^1.1.0",
"@actions/http-client": "^1.0.6",
"@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.5.4",
"@actions/tool-cache": "^1.5.2",
"semver": "^6.1.1"
},
"devDependencies": {

View File

@@ -6,7 +6,7 @@ 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');
import {Url} from 'url';
//
// Node versions interface
@@ -19,141 +19,71 @@ export interface INodeVersion {
interface INodeVersionInfo {
downloadUrl: string;
token: string | null;
resolvedVersion: string;
arch: string;
fileName: string;
}
export async function getNode(
versionSpec: string,
stable: boolean,
checkLatest: boolean,
auth: string | undefined,
arch: string = os.arch()
token: string
) {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
if (checkLatest) {
core.info('Attempt to resolve the latest version from manifest...');
const resolvedVersion = await resolveVersionFromManifest(
versionSpec,
stable,
auth,
osArch
);
if (resolvedVersion) {
versionSpec = resolvedVersion;
core.info(`Resolved as '${versionSpec}'`);
} else {
core.info(`Failed to resolve version ${versionSpec} from manifest`);
}
}
let osArch: string = translateArchToDistUrl(os.arch());
// check cache
let info: INodeVersionInfo | null = null;
let toolPath: string;
toolPath = tc.find('node', versionSpec, osArch);
toolPath = tc.find('node', versionSpec);
// If not found in cache, download
if (toolPath) {
core.info(`Found in cache @ ${toolPath}`);
console.log(`Found in cache @ ${toolPath}`);
} else {
core.info(`Attempting to download ${versionSpec}...`);
let downloadPath = '';
let info: INodeVersionInfo | null = null;
//
// Try download from internal distribution (popular versions only)
//
try {
info = await getInfoFromManifest(versionSpec, stable, auth, osArch);
if (info) {
core.info(
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
);
downloadPath = await tc.downloadTool(info.downloadUrl, undefined, auth);
} else {
core.info(
'Not found in manifest. Falling back to download directly from Node'
);
}
} catch (err) {
// Rate limit?
if (
err instanceof tc.HTTPError &&
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
) {
core.info(
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
);
} else {
core.info(err.message);
}
core.debug(err.stack);
core.info('Falling back to download directly from Node');
console.log(`Attempting to download ${versionSpec}...`);
let info = await getInfoFromManifest(versionSpec, stable, token);
if (!info) {
console.log(
'Not found in manifest. Falling back to download directly from Node'
);
info = await getInfoFromDist(versionSpec);
}
//
// Download from nodejs.org
//
if (!downloadPath) {
info = await getInfoFromDist(versionSpec, arch);
if (!info) {
throw new Error(
`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
);
}
core.info(
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
if (!info) {
throw new Error(
`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
);
try {
downloadPath = await tc.downloadTool(info.downloadUrl);
} catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
return await acquireNodeFromFallbackLocation(
info.resolvedVersion,
info.arch
);
}
}
throw err;
console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
let downloadPath = '';
try {
downloadPath = await tc.downloadTool(info.downloadUrl, undefined, token);
} catch (err) {
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
return await acquireNodeFromFallbackLocation(info.resolvedVersion);
}
throw err;
}
//
// Extract
//
core.info('Extracting ...');
let extPath: string;
info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
if (osPlat == 'win32') {
let _7zPath = path.join(__dirname, '..', 'externals', '7zr.exe');
extPath = await tc.extract7z(downloadPath, undefined, _7zPath);
// 7z extracts to folder matching file name
let nestedPath = path.join(extPath, path.basename(info.fileName, '.7z'));
if (fs.existsSync(nestedPath)) {
extPath = nestedPath;
}
} else {
extPath = await tc.extractTar(downloadPath, undefined, [
'xz',
'--strip',
'1'
]);
extPath = await tc.extractTar(downloadPath);
}
//
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
//
core.info('Adding to the cache ...');
toolPath = await tc.cacheDir(
extPath,
'node',
info.resolvedVersion,
info.arch
);
core.info('Done');
toolPath = await tc.cacheDir(extPath, 'node', info.resolvedVersion);
}
//
@@ -173,39 +103,38 @@ export async function getNode(
async function getInfoFromManifest(
versionSpec: string,
stable: boolean,
auth: string | undefined,
osArch: string = translateArchToDistUrl(os.arch())
token: string
): Promise<INodeVersionInfo | null> {
let info: INodeVersionInfo | null = null;
const releases = await tc.getManifestFromRepo(
'actions',
'node-versions',
auth,
'main'
token
);
const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch);
console.log(`matching ${versionSpec}...`);
const rel = await tc.findFromManifest(versionSpec, stable, releases);
if (rel && rel.files.length > 0) {
info = <INodeVersionInfo>{};
info.resolvedVersion = rel.version;
info.arch = rel.files[0].arch;
info.downloadUrl = rel.files[0].download_url;
info.fileName = rel.files[0].filename;
info.token = token;
}
return info;
}
async function getInfoFromDist(
versionSpec: string,
arch: string = os.arch()
versionSpec: string
): Promise<INodeVersionInfo | null> {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
let osArch: string = translateArchToDistUrl(os.arch());
let info: INodeVersionInfo | null = null;
let version: string;
version = await queryDistForMatch(versionSpec, arch);
version = await queryDistForMatch(versionSpec);
if (!version) {
return null;
}
@@ -225,26 +154,10 @@ async function getInfoFromDist(
return <INodeVersionInfo>{
downloadUrl: url,
resolvedVersion: version,
arch: arch,
fileName: fileName
};
}
async function resolveVersionFromManifest(
versionSpec: string,
stable: boolean,
auth: string | undefined,
osArch: string = translateArchToDistUrl(os.arch())
): Promise<string | undefined> {
try {
const info = await getInfoFromManifest(versionSpec, stable, auth, osArch);
return info?.resolvedVersion;
} catch (err) {
core.info('Unable to resolve version from manifest...');
core.debug(err.message);
}
}
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
function evaluateVersions(versions: string[], versionSpec: string): string {
let version = '';
@@ -273,12 +186,9 @@ function evaluateVersions(versions: string[], versionSpec: string): string {
return version;
}
async function queryDistForMatch(
versionSpec: string,
arch: string = os.arch()
): Promise<string> {
async function queryDistForMatch(versionSpec: string): Promise<string> {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
let osArch: string = translateArchToDistUrl(os.arch());
// node offers a json list of versions
let dataFileName: string;
@@ -334,11 +244,10 @@ export async function getVersionsFromDist(): Promise<INodeVersion[]> {
// 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.
async function acquireNodeFromFallbackLocation(
version: string,
arch: string = os.arch()
version: string
): Promise<string> {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
let osArch: string = translateArchToDistUrl(os.arch());
// Create temporary folder to download in to
const tempDownloadFolder: string =
@@ -353,8 +262,6 @@ async function acquireNodeFromFallbackLocation(
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
core.info(`Downloading only node binary from ${exeUrl}`);
const exePath = await tc.downloadTool(exeUrl);
await io.cp(exePath, path.join(tempDir, 'node.exe'));
const libPath = await tc.downloadTool(libUrl);
@@ -372,9 +279,7 @@ async function acquireNodeFromFallbackLocation(
throw err;
}
}
let toolPath = await tc.cacheDir(tempDir, 'node', version, arch);
core.addPath(toolPath);
return toolPath;
return await tc.cacheDir(tempDir, 'node', version);
}
// os.arch does not always match the relative download url, e.g.

View File

@@ -2,8 +2,6 @@ import * as core from '@actions/core';
import * as installer from './installer';
import * as auth from './authutil';
import * as path from 'path';
import {URL} from 'url';
import os = require('os');
export async function run() {
try {
@@ -16,27 +14,11 @@ export async function run() {
version = core.getInput('version');
}
let arch = core.getInput('architecture');
// if architecture supplied but node-version is not
// if we don't throw a warning, the already installed x64 node will be used which is not probably what user meant.
if (arch && !version) {
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();
}
console.log(`version: ${version}`);
if (version) {
let token = core.getInput('token');
let auth = !token || isGhes() ? undefined : `token ${token}`;
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const checkLatest =
(core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
await installer.getNode(version, stable, checkLatest, auth, arch);
await installer.getNode(version, stable, token);
}
const registryUrl: string = core.getInput('registry-url');
@@ -57,10 +39,3 @@ export async function run() {
core.setFailed(error.message);
}
}
function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}

View File

@@ -13,7 +13,7 @@ rm -rf ./node
export RUNNER_TOOL_CACHE=$(pwd)
export RUNNER_TEMP="${RUNNER_TOOL_CACHE}/temp"
export INPUT_STABLE=true
export INPUT_VERSION="12" #"0.12.7" #"12" #"11.15.0"
export INPUT_VERSION="12.x"
# export your PAT with repo scope before running
export INPUT_TOKEN=$GITHUB_TOKEN