1
0
mirror of https://github.com/actions/setup-node.git synced 2025-12-18 23:08:58 +08:00

Compare commits

...

8 Commits
v2.4.1 ... v2

Author SHA1 Message Date
Dmitry Shibanov
7c12f8017d Update actions/core dependencies for releases/v2 (#713) 2023-03-27 13:36:04 +02:00
Dmitry Shibanov
1f8c6b94b2 Pass to warning uncaught exceptions (#359) 2021-12-28 12:25:43 +03:00
Dmitry Shibanov
9a74eb4e64 Throw error only if exit code is note zero. (#358) 2021-12-27 12:34:06 +03:00
Dmitry Shibanov
04c56d2f95 update cache to 1.0.8 (#367) 2021-11-29 13:35:08 +03:00
Hargun Kaur
d08cf22211 Adding Node.js version file support (#338) 2021-11-29 12:18:31 +03:00
Alexander Forbes-Reed
360ab8b75b Fix typo in the bug_report template (#353) 2021-11-03 13:20:09 +03:00
Dmitry Shibanov
fd4bd829f2 Add issue and pull request templates (#344) 2021-10-18 13:39:58 +03:00
Dmitry Shibanov
a4b8ed2f4e Update dependencies (#346) 2021-10-14 13:18:01 +03:00
44 changed files with 31941 additions and 40183 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a bug report
title: ''
labels: bug, needs triage
assignees: ''
---
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
<!--- Before opening up a new bug report, please make sure to check for similar existing issues -->
**Description:**
A clear and concise description of what the bug is.
**Action version:**
Specify the action version
**Platform:**
- [ ] Ubuntu
- [ ] macOS
- [ ] Windows
**Runner type:**
- [ ] Hosted
- [ ] Self-hosted
**Tools version:**
<!--- Please specify versions of node and package manager (npm, yarn, pnpm and etc)-->
**Repro steps:**
A description with steps to reproduce the issue. If you have a public example or repo to share, please provide the link.
**Expected behavior:**
A description of what you expected to happen.
**Actual behavior:**
A description of what is actually happening.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -0,0 +1,18 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request, needs triage
assignees: ''
---
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
<!--- Before opening up a new feature request, please make sure to check for similar existing issues and pull requests -->
**Description:**
Describe your proposal.
**Justification:**
Justification or a use case for your proposal.
**Are you willing to submit a PR?**
<!--- We accept contributions! -->

9
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,9 @@
**Description:**
Describe your changes.
**Related issue:**
Add link to the related issue.
**Check list:**
- [ ] Mark if documentation changes are required.
- [ ] Mark if tests were added or updated to cover the changes.

View File

@@ -75,7 +75,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12, 14, 16] node-version: [14, 16]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Yarn version - name: Yarn version

View File

@@ -18,7 +18,7 @@ jobs:
- name: Install licensed - name: Install licensed
run: | run: |
cd $RUNNER_TEMP 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 curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.3.1/licensed-3.3.1-linux-x64.tar.gz
sudo tar -xzf licensed.tar.gz sudo tar -xzf licensed.tar.gz
sudo mv licensed /usr/local/bin/licensed sudo mv licensed /usr/local/bin/licensed
- run: licensed status - run: licensed status

View File

@@ -14,14 +14,12 @@ on:
jobs: jobs:
test-proxy: test-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
container: container:
image: ubuntu:latest image: ubuntu:latest
options: --dns 127.0.0.1 options: --dns 127.0.0.1
services: services:
squid-proxy: squid-proxy:
image: datadog/squid:latest image: ubuntu/squid:latest
ports: ports:
- 3128:3128 - 3128:3128
env: env:

View File

@@ -78,6 +78,21 @@ jobs:
run: __tests__/verify-node.sh "${{ matrix.node-version }}" run: __tests__/verify-node.sh "${{ matrix.node-version }}"
shell: bash shell: bash
version-file:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node from node version file
uses: ./
with:
node-version-file: '__tests__/data/.nvmrc'
- name: Verify node
run: __tests__/verify-node.sh 14
node-dist: node-dist:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/@actions/io-1.1.2.dep.yml generated Normal file

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.

BIN
.licenses/npm/form-data-4.0.0.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -93,12 +93,13 @@ jobs:
## Advanced usage ## Advanced usage
1. [Check latest version](docs/advanced-usage.md#check-latest-version) 1. [Check latest version](docs/advanced-usage.md#check-latest-version)
2. [Using different architectures](docs/advanced-usage.md#architecture) 2. [Using a node version file](docs/advanced-usage.md#node-version-file)
3. [Caching packages dependencies](docs/advanced-usage.md#caching-packages-dependencies) 3. [Using different architectures](docs/advanced-usage.md#architecture)
4. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures) 4. [Caching packages dependencies](docs/advanced-usage.md#caching-packages-dependencies)
5. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm) 5. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures)
6. [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn) 6. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm)
7. [Using private packages](docs/advanced-usage.md#use-private-packages) 7. [Publishing to npmjs and GPR with yarn](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-yarn)
8. [Using private packages](docs/advanced-usage.md#use-private-packages)
# License # License

1
__tests__/data/.nvmrc Normal file
View File

@@ -0,0 +1 @@
v14

View File

@@ -1,12 +1,12 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as io from '@actions/io'; import * as io from '@actions/io';
import * as tc from '@actions/tool-cache'; import * as tc from '@actions/tool-cache';
import * as im from '../src/installer';
import fs from 'fs'; import fs from 'fs';
import cp from 'child_process'; import cp from 'child_process';
import osm = require('os'); import osm = require('os');
import path from 'path'; import path from 'path';
import * as main from '../src/main'; import * as main from '../src/main';
import * as im from '../src/installer';
import * as auth from '../src/authutil'; import * as auth from '../src/authutil';
let nodeTestManifest = require('./data/versions-manifest.json'); let nodeTestManifest = require('./data/versions-manifest.json');
@@ -31,9 +31,11 @@ describe('setup-node', () => {
let dbgSpy: jest.SpyInstance; let dbgSpy: jest.SpyInstance;
let whichSpy: jest.SpyInstance; let whichSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance; let existsSpy: jest.SpyInstance;
let readFileSyncSpy: jest.SpyInstance;
let mkdirpSpy: jest.SpyInstance; let mkdirpSpy: jest.SpyInstance;
let execSpy: jest.SpyInstance; let execSpy: jest.SpyInstance;
let authSpy: jest.SpyInstance; let authSpy: jest.SpyInstance;
let parseNodeVersionSpy: jest.SpyInstance;
beforeEach(() => { beforeEach(() => {
// @actions/core // @actions/core
@@ -58,6 +60,7 @@ describe('setup-node', () => {
cacheSpy = jest.spyOn(tc, 'cacheDir'); cacheSpy = jest.spyOn(tc, 'cacheDir');
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo'); getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
getDistSpy = jest.spyOn(im, 'getVersionsFromDist'); getDistSpy = jest.spyOn(im, 'getVersionsFromDist');
parseNodeVersionSpy = jest.spyOn(im, 'parseNodeVersionFile');
// io // io
whichSpy = jest.spyOn(io, 'which'); whichSpy = jest.spyOn(io, 'which');
@@ -91,6 +94,10 @@ describe('setup-node', () => {
// uncomment to see debug output // uncomment to see debug output
// process.stderr.write(msg + '\n'); // process.stderr.write(msg + '\n');
}); });
warningSpy.mockImplementation(msg => {
// uncomment to debug
// process.stderr.write('log:' + line + '\n');
});
}); });
afterEach(() => { afterEach(() => {
@@ -101,6 +108,7 @@ describe('setup-node', () => {
afterAll(async () => { afterAll(async () => {
console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
jest.restoreAllMocks();
}, 100000); }, 100000);
//-------------------------------------------------- //--------------------------------------------------
@@ -343,7 +351,7 @@ describe('setup-node', () => {
expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`); expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
}); });
it('Acquires specified architecture of node', async () => { it('acquires specified architecture of node', async () => {
for (const {arch, version, osSpec} of [ for (const {arch, version, osSpec} of [
{arch: 'x86', version: '12.16.2', osSpec: 'win32'}, {arch: 'x86', version: '12.16.2', osSpec: 'win32'},
{arch: 'x86', version: '14.0.0', osSpec: 'win32'} {arch: 'x86', version: '14.0.0', osSpec: 'win32'}
@@ -360,6 +368,7 @@ describe('setup-node', () => {
inputs['node-version'] = version; inputs['node-version'] = version;
inputs['architecture'] = arch; inputs['architecture'] = arch;
inputs['always-auth'] = false; inputs['always-auth'] = false;
inputs['cache'] = '';
inputs['token'] = 'faketoken'; inputs['token'] = 'faketoken';
let expectedUrl = let expectedUrl =
@@ -549,6 +558,93 @@ describe('setup-node', () => {
}); });
}); });
describe('node-version-file flag', () => {
it('not used if node-version is provided', async () => {
// Arrange
inputs['node-version'] = '12';
// Act
await main.run();
// Assert
expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
});
it('not used if node-version-file not provided', async () => {
// Act
await main.run();
// Assert
expect(parseNodeVersionSpy).toHaveBeenCalledTimes(0);
});
it('reads node-version-file if provided', async () => {
// Arrange
const versionSpec = 'v14';
const versionFile = '.nvmrc';
const expectedVersionSpec = '14';
process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
inputs['node-version-file'] = versionFile;
parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
existsSpy.mockImplementationOnce(
input => input === path.join(__dirname, 'data', versionFile)
);
// Act
await main.run();
// Assert
expect(existsSpy).toHaveBeenCalledTimes(1);
expect(existsSpy).toHaveReturnedWith(true);
expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec);
expect(logSpy).toHaveBeenCalledWith(
`Resolved ${versionFile} as ${expectedVersionSpec}`
);
});
it('both node-version-file and node-version are provided', async () => {
inputs['node-version'] = '12';
const versionSpec = 'v14';
const versionFile = '.nvmrc';
const expectedVersionSpec = '14';
process.env['GITHUB_WORKSPACE'] = path.join(__dirname, '..');
inputs['node-version-file'] = versionFile;
parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec);
// Act
await main.run();
// Assert
expect(existsSpy).toHaveBeenCalledTimes(0);
expect(parseNodeVersionSpy).not.toHaveBeenCalled();
expect(warningSpy).toHaveBeenCalledWith(
'Both node-version and node-version-file inputs are specified, only node-version will be used'
);
});
it('should throw an error if node-version-file is not found', async () => {
const versionFile = '.nvmrc';
const versionFilePath = path.join(__dirname, '..', versionFile);
inputs['node-version-file'] = versionFile;
inSpy.mockImplementation(name => inputs[name]);
existsSpy.mockImplementationOnce(
input => input === path.join(__dirname, 'data', versionFile)
);
// Act
await main.run();
// Assert
expect(existsSpy).toHaveBeenCalled();
expect(existsSpy).toHaveReturnedWith(false);
expect(parseNodeVersionSpy).not.toHaveBeenCalled();
expect(cnSpy).toHaveBeenCalledWith(
`::error::The specified node version file at: ${versionFilePath} does not exist${osm.EOL}`
);
});
});
describe('LTS version', () => { describe('LTS version', () => {
beforeEach(() => { beforeEach(() => {
os.platform = 'linux'; os.platform = 'linux';

View File

@@ -7,6 +7,8 @@ inputs:
default: 'false' default: 'false'
node-version: node-version:
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0' description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0'
node-version-file:
description: 'File containing the version Spec of the version to use. Examples: .nvmrc, .node-version'
architecture: architecture:
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.' description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
check-latest: check-latest:

26365
dist/cache-save/index.js vendored

File diff suppressed because it is too large Load Diff

28170
dist/setup/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,22 @@ steps:
- run: npm test - run: npm test
``` ```
## Node version file
The `node-version-file` input accepts a path to a file containing the version of Node.js to be used by a project, for example `.nvmrc` or `.node-version`. If both the `node-version` and the `node-version-file` inputs are provided then the `node-version` input is used.
See [supported version syntax](https://github.com/actions/setup-node#supported-version-syntax)
> The action will search for the node version file relative to the repository root.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version-file: '.nvmrc'
- run: npm install
- run: npm test
```
## Architecture ## 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). 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).

8349
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,25 +23,25 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^1.0.7", "@actions/cache": "^1.0.8",
"@actions/core": "^1.2.6", "@actions/core": "^1.10.0",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/glob": "^0.2.0", "@actions/glob": "^0.2.0",
"@actions/http-client": "^1.0.6", "@actions/http-client": "^1.0.11",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.5.4", "@actions/tool-cache": "^1.7.2",
"semver": "^6.1.1" "semver": "^6.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^24.0.13", "@types/jest": "^27.0.2",
"@types/node": "^12.0.4", "@types/node": "^12.0.4",
"@types/semver": "^6.0.0", "@types/semver": "^6.0.0",
"@zeit/ncc": "^0.21.0", "@zeit/ncc": "^0.21.0",
"jest": "^24.9.0", "jest": "^27.2.5",
"jest-circus": "^24.7.1", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"ts-jest": "^24.3.0", "ts-jest": "^27.0.5",
"typescript": "^3.8.3" "typescript": "^3.8.3"
} }
} }

View File

@@ -4,6 +4,14 @@ import fs from 'fs';
import {State} from './constants'; import {State} from './constants';
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils'; import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils';
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
// throw an uncaught exception. Instead of failing this action, just warn.
process.on('uncaughtException', e => {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${e.message}`);
});
export async function run() { export async function run() {
try { try {
const cacheLock = core.getInput('cache'); const cacheLock = core.getInput('cache');

View File

@@ -30,9 +30,16 @@ export const supportedPackageManagers: SupportedPackageManagers = {
}; };
export const getCommandOutput = async (toolCommand: string) => { export const getCommandOutput = async (toolCommand: string) => {
const {stdout, stderr, exitCode} = await exec.getExecOutput(toolCommand); let {stdout, stderr, exitCode} = await exec.getExecOutput(
toolCommand,
undefined,
{ignoreReturnCode: true}
);
if (stderr) { if (exitCode) {
stderr = !stderr.trim()
? `The '${toolCommand}' command failed with exit code: ${exitCode}`
: stderr;
throw new Error(stderr); throw new Error(stderr);
} }

View File

@@ -371,7 +371,7 @@ async function queryDistForMatch(
} }
let versions: string[] = []; let versions: string[] = [];
let nodeVersions = await module.exports.getVersionsFromDist(); let nodeVersions = await getVersionsFromDist();
nodeVersions.forEach((nodeVersion: INodeVersion) => { nodeVersions.forEach((nodeVersion: INodeVersion) => {
// ensure this version supports your os and platform // ensure this version supports your os and platform
@@ -464,3 +464,12 @@ function translateArchToDistUrl(arch: string): string {
return arch; return arch;
} }
} }
export function parseNodeVersionFile(contents: string): string {
let nodeVersion = contents.trim();
if (/^v\d/.test(nodeVersion)) {
nodeVersion = nodeVersion.substring(1);
}
return nodeVersion;
}

View File

@@ -1,5 +1,6 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as installer from './installer'; import * as installer from './installer';
import fs from 'fs';
import * as auth from './authutil'; import * as auth from './authutil';
import * as path from 'path'; import * as path from 'path';
import {restoreCache} from './cache-restore'; import {restoreCache} from './cache-restore';
@@ -12,10 +13,7 @@ export async function run() {
// Version is optional. If supplied, install / use from the tool cache // Version is optional. If supplied, install / use from the tool cache
// If not supplied then task is still used to setup proxy, auth, etc... // If not supplied then task is still used to setup proxy, auth, etc...
// //
let version = core.getInput('node-version'); let version = resolveVersionInput();
if (!version) {
version = core.getInput('version');
}
let arch = core.getInput('architecture'); let arch = core.getInput('architecture');
const cache = core.getInput('cache'); const cache = core.getInput('cache');
@@ -63,8 +61,8 @@ export async function run() {
core.info( core.info(
`##[add-matcher]${path.join(matchersPath, 'eslint-compact.json')}` `##[add-matcher]${path.join(matchersPath, 'eslint-compact.json')}`
); );
} catch (error) { } catch (err) {
core.setFailed(error.message); core.setFailed(err.message);
} }
} }
@@ -74,3 +72,36 @@ function isGhes(): boolean {
); );
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
} }
function resolveVersionInput(): string {
let version = core.getInput('node-version') || core.getInput('version');
const versionFileInput = core.getInput('node-version-file');
if (version && versionFileInput) {
core.warning(
'Both node-version and node-version-file inputs are specified, only node-version will be used'
);
}
if (version) {
return version;
}
if (versionFileInput) {
const versionFilePath = path.join(
process.env.GITHUB_WORKSPACE!,
versionFileInput
);
if (!fs.existsSync(versionFilePath)) {
throw new Error(
`The specified node version file at: ${versionFilePath} does not exist`
);
}
version = installer.parseNodeVersionFile(
fs.readFileSync(versionFilePath, 'utf8')
);
core.info(`Resolved ${versionFileInput} as ${version}`);
}
return version;
}