Merge branch 'actions:main' into main

This commit is contained in:
Huan Pham 2022-08-06 00:36:39 -07:00 committed by GitHub
commit 3764bfa369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 70011 additions and 65929 deletions

View file

@ -18,9 +18,9 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node 16
uses: actions/setup-node@v2
- uses: actions/checkout@v3
- name: Setup Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm

View file

@ -21,10 +21,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set Node.js 16.x
uses: actions/setup-node@v2
- name: Setup Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: npm
@ -45,7 +45,7 @@ jobs:
id: diff
# If index.js was different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist

View file

@ -21,7 +21,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Clean global cache
run: npm cache clean --force
- name: Setup Node
@ -44,7 +44,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
@ -77,7 +77,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Yarn version
run: yarn --version
- name: Generate yarn file
@ -109,7 +109,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Update yarn
run: yarn set version berry
- name: Yarn version

View file

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
name: Check licenses
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- run: npm ci
- name: Install licensed
run: |

View file

@ -25,7 +25,7 @@ jobs:
env:
https_proxy: http://squid-proxy:3128
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 14
@ -41,7 +41,7 @@ jobs:
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
- uses: actions/checkout@v3
- name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/*
- name: Setup node 11

View file

@ -20,7 +20,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Node
uses: ./
with:
@ -35,13 +35,21 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [lts/dubnium, lts/erbium, lts/fermium, lts/*]
node-version: [lts/dubnium, lts/erbium, lts/fermium, lts/*, lts/-1]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
check-latest: true
- if: runner.os != 'Windows'
name: Verify node and npm
run: |
. "$NVM_DIR/nvm.sh"
[[ $(nvm version-remote "${{ matrix.node-version }}") =~ ^v([^.]+) ]]
__tests__/verify-node.sh "${BASH_REMATCH[1]}"
shell: bash
manifest:
runs-on: ${{ matrix.os }}
@ -51,7 +59,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10.15, 12.16.0, 14.2.0, 16.3.0]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Node
uses: ./
with:
@ -68,7 +76,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Node and check latest
uses: ./
with:
@ -84,12 +92,13 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version-file: [.nvmrc, .tool-versions, package.json]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup node from node version file
uses: ./
with:
node-version-file: '__tests__/data/.nvmrc'
node-version-file: '__tests__/data/${{ matrix.node-version-file }}'
- name: Verify node
run: __tests__/verify-node.sh 14
@ -101,7 +110,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [11, 13]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Node from dist
uses: ./
with:
@ -117,7 +126,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
# test old versions which didn't have npm and layout different
- name: Setup node 0.12.18 from dist
uses: ./
@ -130,7 +139,7 @@ jobs:
arch:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup node 14 x86 from dist
uses: ./
with:
@ -139,3 +148,34 @@ jobs:
- name: Verify node
run: __tests__/verify-arch.sh "ia32"
shell: bash
node-latest-aliases:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [current, latest, node]
steps:
- name: Get node version
run: |
latestNodeVersion=$(curl https://nodejs.org/dist/index.json | jq -r '. [0].version')
echo "::set-output name=LATEST_NODE_VERSION::$latestNodeVersion"
id: version
shell: bash
- uses: actions/checkout@v3
- name: Setup Node
uses: ./
with:
node-version: ${{ matrix.node-version }}
- name: Retrieve version after install
run: |
updatedVersion=$(echo $(node --version))
echo "::set-output name=NODE_VERSION_UPDATED::$updatedVersion"
id: updatedVersion
shell: bash
- name: Compare versions
if: ${{ steps.version.outputs.LATEST_NODE_VERSION != steps.updatedVersion.outputs.NODE_VERSION_UPDATED}}
run: |
echo "Latest node version failed to download."
exit 1

View file

@ -1,6 +1,6 @@
---
name: "@actions/cache"
version: 1.0.8
version: 3.0.0
type: npm
summary: Actions cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/cache

View file

@ -0,0 +1,32 @@
---
name: "@actions/http-client"
version: 2.0.1
type: npm
summary: Actions Http Client
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
license: mit
licenses:
- sources: LICENSE
text: |
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View file

@ -1,16 +1,16 @@
---
name: "@azure/core-asynciterator-polyfill"
version: 1.0.0
version: 1.0.2
type: npm
summary: Polyfill for IE/Node 8 for Symbol.asyncIterator
homepage: https://github.com/Azure/azure-sdk-for-js/tree/master/sdk/core/core-asynciterator-polyfill
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-asynciterator-polyfill/README.md
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
text: |
The MIT License (MIT)
Copyright (c) Microsoft Corporation. All rights reserved.
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -28,5 +28,5 @@ licenses:
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
SOFTWARE.
notices: []

View file

@ -1,6 +1,6 @@
---
name: "@azure/core-http"
version: 2.2.2
version: 2.2.4
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest

View file

@ -1,6 +1,6 @@
---
name: "@azure/core-lro"
version: 2.2.1
version: 2.2.4
type: npm
summary: Isomorphic client library for supporting long-running operations in node.js
and browser.

View file

@ -1,6 +1,6 @@
---
name: "@azure/core-paging"
version: 1.2.0
version: 1.2.1
type: npm
summary: Core types for paging async iterable iterators
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-paging/README.md

View file

@ -1,6 +1,6 @@
---
name: "@azure/ms-rest-js"
version: 2.6.0
version: 2.6.1
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest

View file

@ -1,6 +1,6 @@
---
name: "@azure/storage-blob"
version: 12.8.0
version: 12.9.0
type: npm
summary: Microsoft Azure Storage SDK for JavaScript - Blob
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/

View file

@ -1,6 +1,6 @@
---
name: "@opentelemetry/api"
version: 1.0.3
version: 1.0.4
type: npm
summary: Public API for OpenTelemetry
homepage: https://github.com/open-telemetry/opentelemetry-js-api#readme
@ -218,10 +218,6 @@ licenses:
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/LICENSE
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
[dependencies-image]: https://status.david-dm.org/gh/open-telemetry/opentelemetry-js-api.svg
[dependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js-api
[devDependencies-image]: https://status.david-dm.org/gh/open-telemetry/opentelemetry-js-api.svg?type=dev
[devDependencies-url]: https://david-dm.org/open-telemetry/opentelemetry-js-api?type=dev
[npm-url]: https://www.npmjs.com/package/@opentelemetry/api
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fapi.svg
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js-api/blob/main/docs/tracing.md

View file

@ -1,6 +1,6 @@
---
name: "@types/node-fetch"
version: 2.5.12
version: 2.6.1
type: npm
summary: TypeScript definitions for node-fetch
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node-fetch

View file

@ -1,8 +1,8 @@
# 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>
</p>
[![build-test](https://github.com/actions/setup-node/actions/workflows/build-test.yml/badge.svg)](https://github.com/actions/setup-node/actions/workflows/build-test.yml)
[![versions](https://github.com/actions/setup-node/actions/workflows/versions.yml/badge.svg)](https://github.com/actions/setup-node/actions/workflows/versions.yml)
[![proxy](https://github.com/actions/setup-node/actions/workflows/proxy.yml/badge.svg)](https://github.com/actions/setup-node/actions/workflows/proxy.yml)
This action provides the following functionality for GitHub Actions users:
@ -11,18 +11,19 @@ This action provides the following functionality for GitHub Actions users:
- Registering problem matchers for error output
- Configuring authentication for GPR or npm
# Usage
## Usage
See [action.yml](action.yml)
**Basic:**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
- run: npm install
node-version: 16
- run: npm ci
- run: npm test
```
@ -32,83 +33,103 @@ The action will first check the local cache for a semver match. If unable to fin
For information regarding locally cached versions of Node.js on GitHub hosted runners, check out [GitHub Actions Virtual Environments](https://github.com/actions/virtual-environments).
#### Supported version syntax
The `node-version` input supports the following syntax:
### Supported version syntax
major versions: `12`, `14`, `16`
more specific versions: `10.15`, `14.2.0`, `16.3.0`
nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*`
The `node-version` input supports the Semantic Versioning Specification, for more detailed examples please refer to the [documentation](https://github.com/npm/node-semver).
## Caching packages dependencies
Examples:
The action has a built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `npm`, `yarn`, `pnpm` (v6.10+). The `cache` input is optional, and caching is turned off by default.
- Major versions: `14`, `16`, `18`
- More specific versions: `10.15`, `16.15.1` , `18.4.0`
- NVM LTS syntax: `lts/erbium`, `lts/fermium`, `lts/*`, `lts/-n`
- Latest release: `*` or `latest`/`current`/`node`
The action defaults to search for the dependency file (`package-lock.json` or `yarn.lock`) in the repository root, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
**Note:** Like the other values, `*` will get the latest [locally-cached Node.js version](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md#nodejs), or the latest version from [actions/node-versions](https://github.com/actions/node-versions/blob/main/versions-manifest.json), depending on the [`check-latest`](docs/advanced-usage.md#check-latest-version) input.
See the examples of using cache for `yarn` / `pnpm` and `cache-dependency-path` input in the [Advanced usage](docs/advanced-usage.md#caching-packages-dependencies) guide.
`current`/`latest`/`node` always resolve to the latest [dist version](https://nodejs.org/dist/index.json).
That version is then downloaded from actions/node-versions if possible, or directly from Node.js if not.
Since it will not be cached always, there is possibility of hitting rate limit when downloading from dist
### Checking in lockfiles
It's **always** recommended to commit the lockfile of your package manager for security and performance reasons. For more information consult the "Working with lockfiles" section of the [Advanced usage](docs/advanced-usage.md#working-with-lockfiles) guide.
## Caching global packages data
The action has a built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/cache) under the hood for caching global packages data but requires less configuration settings. Supported package managers are `npm`, `yarn`, `pnpm` (v6.10+). The `cache` input is optional, and caching is turned off by default.
The action defaults to search for the dependency file (`package-lock.json`, `npm-shrinkwrap.json` or `yarn.lock`) in the repository root, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
**Note:** The action does not cache `node_modules`
See the examples of using cache for `yarn`/`pnpm` and `cache-dependency-path` input in the [Advanced usage](docs/advanced-usage.md#caching-packages-data) guide.
**Caching npm dependencies:**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
node-version: 16
cache: 'npm'
- run: npm install
- run: npm ci
- run: npm test
```
**Caching npm dependencies in monorepos:**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
node-version: 16
cache: 'npm'
cache-dependency-path: subdir/package-lock.json
- run: npm install
- run: npm ci
- run: npm test
```
## Matrix Testing:
## Matrix Testing
```yaml
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node: [ '12', '14', '16' ]
node: [ 14, 16, 18 ]
name: Node ${{ matrix.node }} sample
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- run: npm install
- run: npm ci
- run: npm test
```
## Advanced usage
1. [Check latest version](docs/advanced-usage.md#check-latest-version)
2. [Using a node version file](docs/advanced-usage.md#node-version-file)
3. [Using different architectures](docs/advanced-usage.md#architecture)
4. [Caching packages dependencies](docs/advanced-usage.md#caching-packages-dependencies)
4. [Caching packages data](docs/advanced-usage.md#caching-packages-data)
5. [Using multiple operating systems and architectures](docs/advanced-usage.md#multiple-operating-systems-and-architectures)
6. [Publishing to npmjs and GPR with npm](docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm)
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
The scripts and documentation in this project are released under the [MIT License](LICENSE)
# Contributions
## Contributions
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
## Code of Conduct
:wave: Be nice. See [our code of conduct](CONDUCT)
:wave: Be nice. See [our code of conduct](CODE_OF_CONDUCT.md)

View file

@ -294,6 +294,63 @@ describe('run', () => {
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('save with -1 cacheId , should not fail workflow', async () => {
inputs['cache'] = 'npm';
getStateSpy.mockImplementation((name: string) => {
if (name === State.CacheMatchedKey) {
return npmFileHash;
} else {
return yarnFileHash;
}
});
getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`);
saveCacheSpy.mockImplementation(() => {
return -1;
});
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(getStateSpy).toHaveBeenCalledTimes(2);
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
expect(infoSpy).not.toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
);
expect(saveCacheSpy).toHaveBeenCalled();
expect(infoSpy).not.toHaveBeenLastCalledWith(
`Cache saved with the key: ${yarnFileHash}`
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('saves with error from toolkit, should fail workflow', async () => {
inputs['cache'] = 'npm';
getStateSpy.mockImplementation((name: string) => {
if (name === State.CacheMatchedKey) {
return npmFileHash;
} else {
return yarnFileHash;
}
});
getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`);
saveCacheSpy.mockImplementation(() => {
throw new cache.ValidationError('Validation failed');
});
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(getStateSpy).toHaveBeenCalledTimes(2);
expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
expect(debugSpy).toHaveBeenCalledWith(`npm path is ${commonPath}/npm`);
expect(infoSpy).not.toHaveBeenCalledWith(
`Cache hit occurred on the primary key ${npmFileHash}, not saving cache.`
);
expect(saveCacheSpy).toHaveBeenCalled();
expect(setFailedSpy).toHaveBeenCalled();
});
});
afterEach(() => {

View file

@ -1,37 +1,28 @@
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import path from 'path';
import * as utils from '../src/cache-utils';
import {PackageManagerInfo} from '../src/cache-utils';
import {PackageManagerInfo, isCacheFeatureAvailable} from '../src/cache-utils';
describe('cache-utils', () => {
const commonPath = '/some/random/path';
const versionYarn1 = '1.2.3';
const versionYarn2 = '2.3.4';
let debugSpy: jest.SpyInstance;
let getCommandOutputSpy: jest.SpyInstance;
function getPackagePath(name: string) {
if (name === utils.supportedPackageManagers.npm.getCacheFolderCommand) {
return `${commonPath}/npm`;
} else if (
name === utils.supportedPackageManagers.pnpm.getCacheFolderCommand
) {
return `${commonPath}/pnpm`;
} else {
if (name === utils.supportedPackageManagers.yarn1.getCacheFolderCommand) {
return `${commonPath}/yarn1`;
} else {
return `${commonPath}/yarn2`;
}
}
}
let isFeatureAvailable: jest.SpyInstance;
let info: jest.SpyInstance;
let warningSpy: jest.SpyInstance;
beforeEach(() => {
process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(msg => {});
info = jest.spyOn(core, 'info');
warningSpy = jest.spyOn(core, 'warning');
isFeatureAvailable = jest.spyOn(cache, 'isFeatureAvailable');
getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
});
@ -51,7 +42,32 @@ describe('cache-utils', () => {
});
});
it('isCacheFeatureAvailable for GHES is false', () => {
isFeatureAvailable.mockImplementation(() => false);
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
expect(() => isCacheFeatureAvailable()).toThrowError(
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.'
);
});
it('isCacheFeatureAvailable for GHES has an interhal error', () => {
isFeatureAvailable.mockImplementation(() => false);
process.env['GITHUB_SERVER_URL'] = '';
isCacheFeatureAvailable();
expect(warningSpy).toHaveBeenCalledWith(
'The runner was not able to contact the cache service. Caching will be skipped'
);
});
it('isCacheFeatureAvailable for GHES is available', () => {
isFeatureAvailable.mockImplementation(() => true);
expect(isCacheFeatureAvailable()).toStrictEqual(true);
});
afterEach(() => {
process.env['GITHUB_SERVER_URL'] = '';
jest.resetAllMocks();
jest.clearAllMocks();
});

View file

@ -0,0 +1 @@
nodejs 14.0.0

View file

@ -0,0 +1,5 @@
{
"engines": {
"node": "^14.0.0"
}
}

View file

@ -3,50 +3,50 @@
"version": "14.0.0",
"stable": true,
"lts": "Fermium",
"release_url": "https://github.com/actions/node-versions/releases/tag/14.0.0-20200423.30",
"release_url": "https://github.com/actions/node-versions/releases/tag/14.0.0-20200507.99",
"files": [
{
"filename": "node-14.0.0-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200423.30/node-14.0.0-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200507.99/node-14.0.0-darwin-x64.tar.gz"
},
{
"filename": "node-14.0.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200423.30/node-14.0.0-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200507.99/node-14.0.0-linux-x64.tar.gz"
},
{
"filename": "node-14.0.0-win32-x64.zip",
"filename": "node-14.0.0-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200423.30/node-14.0.0-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/14.0.0-20200507.99/node-14.0.0-win32-x64.7z"
}
]
},
{
"version": "13.13.0",
"stable": true,
"release_url": "https://github.com/actions/node-versions/releases/tag/13.13.0-20200423.29",
"release_url": "https://github.com/actions/node-versions/releases/tag/13.13.0-20200507.97",
"files": [
{
"filename": "node-13.13.0-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200423.29/node-13.13.0-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200507.97/node-13.13.0-darwin-x64.tar.gz"
},
{
"filename": "node-13.13.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200423.29/node-13.13.0-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200507.97/node-13.13.0-linux-x64.tar.gz"
},
{
"filename": "node-13.13.0-win32-x64.zip",
"filename": "node-13.13.0-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200423.29/node-13.13.0-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/13.13.0-20200507.97/node-13.13.0-win32-x64.7z"
}
]
},
@ -54,25 +54,51 @@
"version": "12.16.2",
"stable": true,
"lts": "Erbium",
"release_url": "https://github.com/actions/node-versions/releases/tag/12.16.2-20200423.28",
"release_url": "https://github.com/actions/node-versions/releases/tag/12.16.2-20200507.95",
"files": [
{
"filename": "node-12.16.2-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-darwin-x64.tar.gz"
},
{
"filename": "node-12.16.2-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz"
},
{
"filename": "node-12.16.2-win32-x64.zip",
"filename": "node-12.16.2-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-win32-x64.7z"
}
]
},
{
"version": "12.0.0",
"stable": true,
"lts": "Erbium",
"release_url": "https://github.com/actions/node-versions/releases/tag/12.0.0-20200507.71",
"files": [
{
"filename": "node-12.0.0-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/12.0.0-20200507.71/node-12.0.0-darwin-x64.tar.gz"
},
{
"filename": "node-12.0.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/12.0.0-20200507.71/node-12.0.0-linux-x64.tar.gz"
},
{
"filename": "node-12.0.0-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/12.0.0-20200507.71/node-12.0.0-win32-x64.7z"
}
]
},
@ -80,25 +106,25 @@
"version": "10.20.1",
"stable": true,
"lts": "Dubnium",
"release_url": "https://github.com/actions/node-versions/releases/tag/10.20.1-20200423.27",
"release_url": "https://github.com/actions/node-versions/releases/tag/10.20.1-20200507.70",
"files": [
{
"filename": "node-10.20.1-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200423.27/node-10.20.1-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200507.70/node-10.20.1-darwin-x64.tar.gz"
},
{
"filename": "node-10.20.1-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200423.27/node-10.20.1-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200507.70/node-10.20.1-linux-x64.tar.gz"
},
{
"filename": "node-10.20.1-win32-x64.zip",
"filename": "node-10.20.1-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200423.27/node-10.20.1-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/10.20.1-20200507.70/node-10.20.1-win32-x64.7z"
}
]
},
@ -106,25 +132,25 @@
"version": "8.17.0",
"stable": true,
"lts": "Carbon",
"release_url": "https://github.com/actions/node-versions/releases/tag/8.17.0-20200423.26",
"release_url": "https://github.com/actions/node-versions/releases/tag/8.17.0-20200507.37",
"files": [
{
"filename": "node-8.17.0-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200423.26/node-8.17.0-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200507.37/node-8.17.0-darwin-x64.tar.gz"
},
{
"filename": "node-8.17.0-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200423.26/node-8.17.0-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200507.37/node-8.17.0-linux-x64.tar.gz"
},
{
"filename": "node-8.17.0-win32-x64.zip",
"filename": "node-8.17.0-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200423.26/node-8.17.0-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/8.17.0-20200507.37/node-8.17.0-win32-x64.7z"
}
]
},
@ -132,25 +158,25 @@
"version": "6.17.1",
"stable": true,
"lts": "Boron",
"release_url": "https://github.com/actions/node-versions/releases/tag/6.17.1-20200423.25",
"release_url": "https://github.com/actions/node-versions/releases/tag/6.17.1-20200529.2",
"files": [
{
"filename": "node-6.17.1-darwin-x64.tar.gz",
"arch": "x64",
"platform": "darwin",
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200423.25/node-6.17.1-darwin-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200529.2/node-6.17.1-darwin-x64.tar.gz"
},
{
"filename": "node-6.17.1-linux-x64.tar.gz",
"arch": "x64",
"platform": "linux",
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200423.25/node-6.17.1-linux-x64.tar.gz"
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200529.2/node-6.17.1-linux-x64.tar.gz"
},
{
"filename": "node-6.17.1-win32-x64.zip",
"filename": "node-6.17.1-win32-x64.7z",
"arch": "x64",
"platform": "win32",
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200423.25/node-6.17.1-win32-x64.zip"
"download_url": "https://github.com/actions/node-versions/releases/download/6.17.1-20200529.2/node-6.17.1-win32-x64.7z"
}
]
}

View file

@ -1,11 +1,14 @@
import * as core from '@actions/core';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import * as exec from '@actions/exec';
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 path from 'path';
import each from 'jest-each';
import * as main from '../src/main';
import * as auth from '../src/authutil';
@ -36,6 +39,8 @@ describe('setup-node', () => {
let execSpy: jest.SpyInstance;
let authSpy: jest.SpyInstance;
let parseNodeVersionSpy: jest.SpyInstance;
let isCacheActionAvailable: jest.SpyInstance;
let getExecOutputSpy: jest.SpyInstance;
beforeEach(() => {
// @actions/core
@ -67,6 +72,9 @@ describe('setup-node', () => {
existsSpy = jest.spyOn(fs, 'existsSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP');
// @actions/tool-cache
isCacheActionAvailable = jest.spyOn(cache, 'isFeatureAvailable');
// disable authentication portion for installer tests
authSpy = jest.spyOn(auth, 'configAuthentication');
authSpy.mockImplementation(() => {});
@ -98,6 +106,10 @@ describe('setup-node', () => {
// uncomment to debug
// process.stderr.write('log:' + line + '\n');
});
// @actions/exec
getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
getExecOutputSpy.mockImplementation(() => 'v16.15.0');
});
afterEach(() => {
@ -121,7 +133,7 @@ describe('setup-node', () => {
'mocktoken'
);
expect(versions).toBeDefined();
expect(versions?.length).toBe(6);
expect(versions?.length).toBe(7);
});
it('can mock dist versions', async () => {
@ -130,8 +142,15 @@ describe('setup-node', () => {
expect(versions?.length).toBe(23);
});
it('can find 12.16.2 from manifest on osx', async () => {
os.platform = 'darwin';
it.each([
['12.16.2', 'darwin', '12.16.2', 'Erbium'],
['12', 'linux', '12.16.2', 'Erbium'],
['10', 'win32', '10.20.1', 'Dubnium'],
['*', 'linux', '14.0.0', 'Fermium']
])(
'can find %s from manifest on %s',
async (versionSpec, platform, expectedVersion, expectedLts) => {
os.platform = platform;
os.arch = 'x64';
let versions: tc.IToolRelease[] | null = await tc.getManifestFromRepo(
'actions',
@ -139,41 +158,12 @@ describe('setup-node', () => {
'mocktoken'
);
expect(versions).toBeDefined();
let match = await tc.findFromManifest('12.16.2', true, versions);
let match = await tc.findFromManifest(versionSpec, true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('12.16.2');
expect((match as any).lts).toBe('Erbium');
});
it('can find 12 from manifest on linux', async () => {
os.platform = 'linux';
os.arch = 'x64';
let versions: tc.IToolRelease[] | null = await tc.getManifestFromRepo(
'actions',
'node-versions',
'mocktoken'
expect(match?.version).toBe(expectedVersion);
expect((match as any).lts).toBe(expectedLts);
}
);
expect(versions).toBeDefined();
let match = await tc.findFromManifest('12.16.2', true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('12.16.2');
expect((match as any).lts).toBe('Erbium');
});
it('can find 10 from manifest on windows', async () => {
os.platform = 'win32';
os.arch = 'x64';
let versions: tc.IToolRelease[] | null = await tc.getManifestFromRepo(
'actions',
'node-versions',
'mocktoken'
);
expect(versions).toBeDefined();
let match = await tc.findFromManifest('10', true, versions);
expect(match).toBeDefined();
expect(match?.version).toBe('10.20.1');
expect((match as any).lts).toBe('Dubnium');
});
//--------------------------------------------------
// Found in cache tests
@ -245,7 +235,7 @@ describe('setup-node', () => {
inputs['token'] = 'faketoken';
let expectedUrl =
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
@ -283,7 +273,7 @@ describe('setup-node', () => {
inputs['token'] = 'faketoken';
let expectedUrl =
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
@ -452,7 +442,7 @@ describe('setup-node', () => {
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';
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz';
await main.run();
@ -601,6 +591,33 @@ describe('setup-node', () => {
);
});
it('reads package.json as node-version-file if provided', async () => {
// Arrange
const versionSpec = fs.readFileSync(
path.join(__dirname, 'data/package.json'),
'utf-8'
);
const versionFile = 'package.json';
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';
@ -644,6 +661,49 @@ describe('setup-node', () => {
);
});
});
describe('cache on GHES', () => {
it('Should throw an error, because cache is not supported', async () => {
inputs['node-version'] = '12';
inputs['cache'] = 'npm';
inSpy.mockImplementation(name => inputs[name]);
let toolPath = path.normalize('/cache/node/12.16.1/x64');
findSpy.mockImplementation(() => toolPath);
// expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
isCacheActionAvailable.mockImplementation(() => false);
await main.run();
expect(cnSpy).toHaveBeenCalledWith(
`::error::Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.${osm.EOL}`
);
});
it('Should throw an internal error', async () => {
inputs['node-version'] = '12';
inputs['cache'] = 'npm';
inSpy.mockImplementation(name => inputs[name]);
let toolPath = path.normalize('/cache/node/12.16.1/x64');
findSpy.mockImplementation(() => toolPath);
// expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
process.env['GITHUB_SERVER_URL'] = '';
isCacheActionAvailable.mockImplementation(() => false);
await main.run();
expect(warningSpy).toHaveBeenCalledWith(
'The runner was not able to contact the cache service. Caching will be skipped'
);
});
});
describe('LTS version', () => {
beforeEach(() => {
os.platform = 'linux';
@ -651,11 +711,17 @@ describe('setup-node', () => {
inputs.stable = 'true';
});
it('find latest LTS version and resolve it from local cache (lts/erbium)', async () => {
it.each([
['erbium', '12.16.2'],
['*', '14.0.0'],
['-1', '12.16.2']
])(
'find latest LTS version and resolve it from local cache (lts/%s)',
async (lts, expectedVersion) => {
// arrange
inputs['node-version'] = 'lts/erbium';
inputs['node-version'] = `lts/${lts}`;
const toolPath = path.normalize('/cache/node/12.16.2/x64');
const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
findSpy.mockReturnValue(toolPath);
// act
@ -670,28 +736,46 @@ describe('setup-node', () => {
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias 'erbium' for Node version 'lts/erbium'`
`LTS alias '${lts}' for Node version 'lts/${lts}'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '12.16.2' for Node version 'lts/erbium'`
`Found LTS release '${expectedVersion}' for Node version 'lts/${lts}'`
);
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});
}
);
it('find latest LTS version and install it from manifest (lts/erbium)', async () => {
it.each([
[
'erbium',
'12.16.2',
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz'
],
[
'*',
'14.0.0',
'https://github.com/actions/node-versions/releases/download/14.0.0-20200507.99/node-14.0.0-linux-x64.tar.gz'
],
[
'-1',
'12.16.2',
'https://github.com/actions/node-versions/releases/download/12.16.2-20200507.95/node-12.16.2-linux-x64.tar.gz'
]
])(
'find latest LTS version and install it from manifest (lts/%s)',
async (lts, expectedVersion, expectedUrl) => {
// arrange
inputs['node-version'] = 'lts/erbium';
inputs['node-version'] = `lts/${lts}`;
const toolPath = path.normalize('/cache/node/12.16.2/x64');
const toolPath = path.normalize(`/cache/node/${expectedVersion}/x64`);
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
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';
const expectedMajor = expectedVersion.split('.')[0];
// act
await main.run();
@ -705,91 +789,24 @@ describe('setup-node', () => {
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias 'erbium' for Node version 'lts/erbium'`
`LTS alias '${lts}' for Node version 'lts/${lts}'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '12.16.2' for Node version 'lts/erbium'`
`Found LTS release '${expectedVersion}' for Node version 'lts/${lts}'`
);
expect(logSpy).toHaveBeenCalledWith('Attempting to download 12...');
expect(logSpy).toHaveBeenCalledWith(
`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`
`Attempting to download ${expectedMajor}...`
);
expect(logSpy).toHaveBeenCalledWith(
`Acquiring ${expectedVersion} - ${os.arch} from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});
it('find latest LTS version and resolve it from local cache (lts/*)', async () => {
// arrange
inputs['node-version'] = 'lts/*';
const toolPath = path.normalize('/cache/node/14.0.0/x64');
findSpy.mockReturnValue(toolPath);
// act
await main.run();
// assert
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve LTS alias from manifest...'
}
);
expect(dbgSpy).toHaveBeenCalledWith(
'Getting manifest from actions/node-versions@main'
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias '*' for Node version 'lts/*'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '14.0.0' for Node version 'lts/*'`
);
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});
it('find latest LTS version and install it from manifest (lts/*)', async () => {
// arrange
inputs['node-version'] = 'lts/*';
const toolPath = path.normalize('/cache/node/14.0.0/x64');
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
exSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
const expectedUrl =
'https://github.com/actions/node-versions/releases/download/14.0.0-20200423.30/node-14.0.0-linux-x64.tar.gz';
// act
await main.run();
// assert
expect(logSpy).toHaveBeenCalledWith(
'Attempt to resolve LTS alias from manifest...'
);
expect(dbgSpy).toHaveBeenCalledWith(
'Getting manifest from actions/node-versions@main'
);
expect(dbgSpy).not.toHaveBeenCalledWith('No manifest cached');
expect(dbgSpy).toHaveBeenCalledWith(
`LTS alias '*' for Node version 'lts/*'`
);
expect(dbgSpy).toHaveBeenCalledWith(
`Found LTS release '14.0.0' for Node version 'lts/*'`
);
expect(logSpy).toHaveBeenCalledWith('Attempting to download 14...');
expect(logSpy).toHaveBeenCalledWith(
`Acquiring 14.0.0 - ${os.arch} from ${expectedUrl}`
);
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
expect(logSpy).toHaveBeenCalledWith('Adding to the cache ...');
expect(cnSpy).toHaveBeenCalledWith(
`::add-path::${path.join(toolPath, 'bin')}${osm.EOL}`
);
});
it('fail with unable to parse LTS alias (lts/)', async () => {
// arrange
@ -861,4 +878,77 @@ describe('setup-node', () => {
);
});
});
describe('latest alias syntax', () => {
it.each(['latest', 'current', 'node'])(
'download the %s version if alias is provided',
async inputVersion => {
// Arrange
inputs['node-version'] = inputVersion;
os.platform = 'darwin';
os.arch = 'x64';
findSpy.mockImplementation(() => '');
getManifestSpy.mockImplementation(() => {
throw new Error('Unable to download manifest');
});
// Act
await main.run();
// assert
expect(logSpy).toHaveBeenCalledWith('Unable to download manifest');
expect(logSpy).toHaveBeenCalledWith('getting latest node version...');
}
);
});
describe('latest alias syntax from cache', () => {
it.each(['latest', 'current', 'node'])(
'download the %s version if alias is provided',
async inputVersion => {
// Arrange
inputs['node-version'] = inputVersion;
const expectedVersion = nodeTestDist[0];
os.platform = 'darwin';
os.arch = 'x64';
const toolPath = path.normalize(
`/cache/node/${expectedVersion.version}/x64`
);
findSpy.mockReturnValue(toolPath);
// Act
await main.run();
// assert
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
expect(logSpy).toHaveBeenCalledWith('getting latest node version...');
}
);
});
});
describe('helper methods', () => {
describe('parseNodeVersionFile', () => {
each`
contents | expected
${'12'} | ${'12'}
${'12.3'} | ${'12.3'}
${'12.3.4'} | ${'12.3.4'}
${'v12.3.4'} | ${'12.3.4'}
${'lts/erbium'} | ${'lts/erbium'}
${'lts/*'} | ${'lts/*'}
${'nodejs 12.3.4'} | ${'12.3.4'}
${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
${''} | ${''}
${'unknown format'} | ${'unknown format'}
`.it('parses "$contents"', ({contents, expected}) => {
expect(im.parseNodeVersionFile(contents)).toBe(expected);
});
});
});

View file

@ -1,35 +1,37 @@
name: 'Setup Node.js environment'
description: 'Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH'
description: 'Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH.'
author: 'GitHub'
inputs:
always-auth:
description: 'Set always-auth in npmrc'
description: 'Set always-auth in npmrc.'
default: 'false'
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'
description: 'File containing the version Spec of the version to use. Examples: .nvmrc, .node-version, .tool-versions.'
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'
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'
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:
description: 'Optional scope for authenticating against scoped registries'
description: 'Optional scope for authenticating against scoped registries. Will fall back to the repository owner when using the GitHub Packages registry (https://npm.pkg.github.com/).'
token:
description: Used to pull node distributions from node-versions. Since there's a default, this is typically not supplied by the user.
default: ${{ github.token }}
cache:
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm'
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
cache-dependency-path:
description: 'Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc. Supports wildcards or a list of file names for caching multiple dependencies.'
# TODO: add input to control forcing to pull from cloud or dist.
# escape valve for someone having issues or needing the absolute latest which isn't cached yet
outputs:
cache-hit:
description: 'A boolean value to indicate if a cache was hit'
description: 'A boolean value to indicate if a cache was hit.'
node-version:
description: 'The installed node version.'
runs:
using: 'node16'
main: 'dist/setup/index.js'

55972
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

78201
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,39 @@
# Advanced usage
## Working with lockfiles
All supported package managers recommend that you **always** commit the lockfile, although implementations vary doing so generally provides the following benefits:
- Enables faster installation for CI and production environments, due to being able to skip package resolution.
- Describes a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
- Provides a facility for users to "time-travel" to previous states of `node_modules` without having to commit the directory itself.
- Facilitates greater visibility of tree changes through readable source control diffs.
In order to get the most out of using your lockfile on continuous integration follow the conventions outlined below for your respective package manager.
### NPM
Ensure that `package-lock.json` is always committed, use `npm ci` instead of `npm install` when installing packages.
**See also:**
- [Documentation of `package-lock.json`](https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json)
- [Documentation of `npm ci`](https://docs.npmjs.com/cli/v8/commands/npm-ci)
### Yarn
To ensure that `yarn.lock` is always committed, use `yarn install --immutable` when installing packages.
**See also:**
- [Documentation of `yarn.lock`](https://classic.yarnpkg.com/en/docs/yarn-lock)
- [Documentation of `--frozen-lockfile` option](https://classic.yarnpkg.com/en/docs/cli/install#toc-yarn-install-frozen-lockfile)
- [QA - Should lockfiles be committed to the repoistory?](https://yarnpkg.com/getting-started/qa/#should-lockfiles-be-committed-to-the-repository)
- [Documentation of `yarn install`](https://yarnpkg.com/cli/install)
### PNPM
Ensure that `pnpm-lock.yaml` is always committed, when on CI pass `--frozen-lockfile` to `pnpm install` when installing packages.
**See also:**
- [Working with Git - Lockfiles](https://pnpm.io/git#lockfiles)
- [Documentation of `--frozen-lockfile` option](https://pnpm.io/cli/install#--frozen-lockfile)
## Check latest version
@ -10,28 +45,28 @@ If `check-latest` is set to `true`, the action first checks if the cached versio
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
check-latest: true
- run: npm install
- run: npm ci
- 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.
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`, `.node-version` or `.tool-versions`. 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
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- run: npm install
- run: npm ci
- run: npm test
```
@ -46,28 +81,28 @@ jobs:
runs-on: windows-latest
name: Node sample
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
architecture: 'x64' # optional, x64 or x86. If not specified, x64 will be used by default
- run: npm install
- run: npm ci
- run: npm test
```
## Caching packages dependencies
## Caching packages data
The action follows [actions/cache](https://github.com/actions/cache/blob/main/examples.md#node---npm) guidelines, and caches global cache on the machine instead of `node_modules`, so cache can be reused between different Node.js versions.
**Caching yarn dependencies:**
Yarn caching handles both yarn versions: 1 or 2.
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
cache: 'yarn'
- run: yarn install
- run: yarn install --frozen-lockfile # optional, --immutable
- run: yarn test
```
@ -81,43 +116,43 @@ steps:
# NOTE: pnpm caching support requires pnpm version >= 6.10.0
steps:
- uses: actions/checkout@v2
- uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 6.10.0
- uses: actions/setup-node@v2
version: 6.32.9
- uses: actions/setup-node@v3
with:
node-version: '14'
cache: 'pnpm'
- run: pnpm install
- run: pnpm install --frozen-lockfile
- run: pnpm test
```
**Using wildcard patterns to cache dependencies**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- run: npm install
- run: npm ci
- run: npm test
```
**Using a list of file paths to cache dependencies**
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14'
cache: 'npm'
cache-dependency-path: |
server/app/package-lock.json
frontend/app/package-lock.json
- run: npm install
- run: npm ci
- run: npm test
```
@ -146,29 +181,29 @@ jobs:
architecture: x86
name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node_version }}
architecture: ${{ matrix.architecture }}
- run: npm install
- run: npm ci
- run: npm test
```
## Publish to npmjs and GPR with npm
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
registry-url: 'https://npm.pkg.github.com'
- run: npm publish
@ -179,16 +214,16 @@ steps:
## Publish to npmjs and GPR with yarn
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14.x'
registry-url: <registry url>
- run: yarn install
- run: yarn install --frozen-lockfile
- run: yarn publish
env:
NODE_AUTH_TOKEN: ${{ secrets.YARN_TOKEN }}
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
registry-url: 'https://npm.pkg.github.com'
- run: yarn publish
@ -199,16 +234,18 @@ steps:
## Use private packages
```yaml
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '14.x'
registry-url: 'https://registry.npmjs.org'
# Skip post-install scripts here, as a malicious
# script could steal NODE_AUTH_TOKEN.
- run: npm install --ignore-scripts
- run: npm ci --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# `npm rebuild` will run all those post-install scripts for us.
- run: npm rebuild && npm run prepare --if-present
```
NOTE: As per https://github.com/actions/setup-node/issues/49 you cannot use `secrets.GITHUB_TOKEN` to access private GitHub Packages within the same organisation but in a different repository.

172
package-lock.json generated
View file

@ -1,15 +1,15 @@
{
"name": "setup-node",
"version": "2.0.0",
"version": "3.1.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "setup-node",
"version": "2.0.0",
"version": "3.1.1",
"license": "MIT",
"dependencies": {
"@actions/cache": "^1.0.8",
"@actions/cache": "^3.0.0",
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^1.1.0",
@ -23,7 +23,7 @@
"@types/jest": "^27.0.2",
"@types/node": "^16.11.25",
"@types/semver": "^6.0.0",
"@zeit/ncc": "^0.21.0",
"@vercel/ncc": "^0.33.4",
"jest": "^27.2.5",
"jest-circus": "^27.2.5",
"prettier": "^1.19.1",
@ -32,17 +32,17 @@
}
},
"node_modules/@actions/cache": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-1.0.8.tgz",
"integrity": "sha512-GWNNB67w93HGJRQXlsV56YqrdAuDoP3esK/mo5mzU8WoDCVjtQgJGsTdkYUX7brswtT7xnI30bWNo1WLKQ8FZQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.0.7",
"@azure/storage-blob": "^12.1.2",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
}
@ -56,6 +56,14 @@
"minimatch": "^3.0.4"
}
},
"node_modules/@actions/cache/node_modules/@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@actions/cache/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@ -142,9 +150,12 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/core-asynciterator-polyfill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz",
"integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg=="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz",
"integrity": "sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/@azure/core-auth": {
"version": "1.3.2",
@ -164,9 +175,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/core-http": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.2.tgz",
"integrity": "sha512-V1DdoO9V/sFimKpdWoNBgsE+QUjQgpXYnxrTdUp5RyhsTJjvEVn/HKmTQXIHuLUUo6IyIWj+B+Dg4VaXse9dIA==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.4.tgz",
"integrity": "sha512-QmmJmexXKtPyc3/rsZR/YTLDvMatzbzAypJmLzvlfxgz/SkgnqV/D4f6F2LsK6tBj1qhyp8BoXiOebiej0zz3A==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
@ -176,7 +187,7 @@
"@types/node-fetch": "^2.5.0",
"@types/tunnel": "^0.0.3",
"form-data": "^4.0.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"process": "^0.11.10",
"tough-cookie": "^4.0.0",
"tslib": "^2.2.0",
@ -215,9 +226,9 @@
}
},
"node_modules/@azure/core-lro": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.1.tgz",
"integrity": "sha512-HE6PBl+mlKa0eBsLwusHqAqjLc5n9ByxeDo3Hz4kF3B1hqHvRkBr4oMgoT6tX7Hc3q97KfDctDUon7EhvoeHPA==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz",
"integrity": "sha512-e1I2v2CZM0mQo8+RSix0x091Av493e4bnT22ds2fcQGslTHzM2oTbswkB65nP4iEpCxBrFxOSDPKExmTmjCVtQ==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.13",
@ -234,9 +245,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/core-paging": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.0.tgz",
"integrity": "sha512-ZX1bCjm/MjKPCN6kQD/9GJErYSoKA8YWp6YWoo5EIzcTWlSBLXu3gNaBTUl8usGl+UShiKo7b4Gdy1NSTIlpZg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.1.tgz",
"integrity": "sha512-UtH5iMlYsvg+nQYIl4UHlvvSrsBjOlRF4fs0j7mxd3rWdAStrKYrh2durOpHs5C9yZbVhsVDaisoyaf/lL1EVA==",
"dependencies": {
"@azure/core-asynciterator-polyfill": "^1.0.0",
"tslib": "^2.2.0"
@ -284,14 +295,14 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@azure/ms-rest-js": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
"integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.1.tgz",
"integrity": "sha512-LLi4jRe/qy5IM8U2CkoDgSZp2OH+MgDe2wePmhz8uY84Svc53EhHaamVyoU6BjjHBxvCRh1vcD1urJDccrxqIw==",
"dependencies": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
@ -334,9 +345,9 @@
}
},
"node_modules/@azure/storage-blob": {
"version": "12.8.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.8.0.tgz",
"integrity": "sha512-c8+Wz19xauW0bGkTCoqZH4dYfbtBniPiGiRQOn1ca6G5jsjr4azwaTk9gwjVY8r3vY2Taf95eivLzipfIfiS4A==",
"version": "12.9.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.9.0.tgz",
"integrity": "sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg==",
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^2.0.0",
@ -1359,9 +1370,9 @@
}
},
"node_modules/@opentelemetry/api": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz",
"integrity": "sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz",
"integrity": "sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog==",
"engines": {
"node": ">=8.0.0"
}
@ -1483,9 +1494,9 @@
"integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ=="
},
"node_modules/@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
"dependencies": {
"@types/node": "*",
"form-data": "^3.0.0"
@ -1532,11 +1543,10 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
"dev": true
},
"node_modules/@zeit/ncc": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.21.0.tgz",
"integrity": "sha512-RUMdvVK/w78oo+yBjruZltt0kJXYar2un/1bYQ2LuHG7GmFVm+QjxzEmySwREctaJdEnBvlMdUNWd9hXHxEI3g==",
"deprecated": "@zeit/ncc is no longer maintained. Please use @vercel/ncc instead.",
"node_modules/@vercel/ncc": {
"version": "0.33.4",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.4.tgz",
"integrity": "sha512-ln18hs7dMffelP47tpkaR+V5Tj6coykNyxJrlcmCormPqRQjB/Gv4cu2FfBG+PMzIfdZp2CLDsrrB1NPU22Qhg==",
"dev": true,
"bin": {
"ncc": "dist/ncc/cli.js"
@ -5077,17 +5087,17 @@
},
"dependencies": {
"@actions/cache": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-1.0.8.tgz",
"integrity": "sha512-GWNNB67w93HGJRQXlsV56YqrdAuDoP3esK/mo5mzU8WoDCVjtQgJGsTdkYUX7brswtT7xnI30bWNo1WLKQ8FZQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"requires": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.0.7",
"@azure/storage-blob": "^12.1.2",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
},
@ -5101,6 +5111,14 @@
"minimatch": "^3.0.4"
}
},
"@actions/http-client": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@ -5184,9 +5202,9 @@
}
},
"@azure/core-asynciterator-polyfill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz",
"integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg=="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz",
"integrity": "sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw=="
},
"@azure/core-auth": {
"version": "1.3.2",
@ -5205,9 +5223,9 @@
}
},
"@azure/core-http": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.2.tgz",
"integrity": "sha512-V1DdoO9V/sFimKpdWoNBgsE+QUjQgpXYnxrTdUp5RyhsTJjvEVn/HKmTQXIHuLUUo6IyIWj+B+Dg4VaXse9dIA==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.4.tgz",
"integrity": "sha512-QmmJmexXKtPyc3/rsZR/YTLDvMatzbzAypJmLzvlfxgz/SkgnqV/D4f6F2LsK6tBj1qhyp8BoXiOebiej0zz3A==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
@ -5217,7 +5235,7 @@
"@types/node-fetch": "^2.5.0",
"@types/tunnel": "^0.0.3",
"form-data": "^4.0.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"process": "^0.11.10",
"tough-cookie": "^4.0.0",
"tslib": "^2.2.0",
@ -5249,9 +5267,9 @@
}
},
"@azure/core-lro": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.1.tgz",
"integrity": "sha512-HE6PBl+mlKa0eBsLwusHqAqjLc5n9ByxeDo3Hz4kF3B1hqHvRkBr4oMgoT6tX7Hc3q97KfDctDUon7EhvoeHPA==",
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.2.4.tgz",
"integrity": "sha512-e1I2v2CZM0mQo8+RSix0x091Av493e4bnT22ds2fcQGslTHzM2oTbswkB65nP4iEpCxBrFxOSDPKExmTmjCVtQ==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.13",
@ -5267,9 +5285,9 @@
}
},
"@azure/core-paging": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.0.tgz",
"integrity": "sha512-ZX1bCjm/MjKPCN6kQD/9GJErYSoKA8YWp6YWoo5EIzcTWlSBLXu3gNaBTUl8usGl+UShiKo7b4Gdy1NSTIlpZg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.2.1.tgz",
"integrity": "sha512-UtH5iMlYsvg+nQYIl4UHlvvSrsBjOlRF4fs0j7mxd3rWdAStrKYrh2durOpHs5C9yZbVhsVDaisoyaf/lL1EVA==",
"requires": {
"@azure/core-asynciterator-polyfill": "^1.0.0",
"tslib": "^2.2.0"
@ -5314,14 +5332,14 @@
}
},
"@azure/ms-rest-js": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.0.tgz",
"integrity": "sha512-4C5FCtvEzWudblB+h92/TYYPiq7tuElX8icVYToxOdggnYqeec4Se14mjse5miInKtZahiFHdl8lZA/jziEc5g==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/@azure/ms-rest-js/-/ms-rest-js-2.6.1.tgz",
"integrity": "sha512-LLi4jRe/qy5IM8U2CkoDgSZp2OH+MgDe2wePmhz8uY84Svc53EhHaamVyoU6BjjHBxvCRh1vcD1urJDccrxqIw==",
"requires": {
"@azure/core-auth": "^1.1.4",
"abort-controller": "^3.0.0",
"form-data": "^2.5.0",
"node-fetch": "^2.6.0",
"node-fetch": "^2.6.7",
"tough-cookie": "^3.0.1",
"tslib": "^1.10.0",
"tunnel": "0.0.6",
@ -5357,9 +5375,9 @@
}
},
"@azure/storage-blob": {
"version": "12.8.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.8.0.tgz",
"integrity": "sha512-c8+Wz19xauW0bGkTCoqZH4dYfbtBniPiGiRQOn1ca6G5jsjr4azwaTk9gwjVY8r3vY2Taf95eivLzipfIfiS4A==",
"version": "12.9.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.9.0.tgz",
"integrity": "sha512-ank38FdCLfJ+EoeMzCz3hkYJuZAd63ARvDKkxZYRDb+beBYf+/+gx8jNTqkq/hfyUl4dJQ/a7tECU0Y0F98CHg==",
"requires": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-http": "^2.0.0",
@ -6177,9 +6195,9 @@
}
},
"@opentelemetry/api": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz",
"integrity": "sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ=="
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz",
"integrity": "sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog=="
},
"@sinonjs/commons": {
"version": "1.8.3",
@ -6295,9 +6313,9 @@
"integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ=="
},
"@types/node-fetch": {
"version": "2.5.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
"integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
"requires": {
"@types/node": "*",
"form-data": "^3.0.0"
@ -6344,10 +6362,10 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
"dev": true
},
"@zeit/ncc": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.21.0.tgz",
"integrity": "sha512-RUMdvVK/w78oo+yBjruZltt0kJXYar2un/1bYQ2LuHG7GmFVm+QjxzEmySwREctaJdEnBvlMdUNWd9hXHxEI3g==",
"@vercel/ncc": {
"version": "0.33.4",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.4.tgz",
"integrity": "sha512-ln18hs7dMffelP47tpkaR+V5Tj6coykNyxJrlcmCormPqRQjB/Gv4cu2FfBG+PMzIfdZp2CLDsrrB1NPU22Qhg==",
"dev": true
},
"abab": {

View file

@ -1,6 +1,6 @@
{
"name": "setup-node",
"version": "2.0.0",
"version": "3.1.1",
"private": true,
"description": "setup node action",
"main": "lib/setup-node.js",
@ -8,7 +8,7 @@
"build": "ncc build -o dist/setup src/setup-node.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"test": "jest",
"test": "jest --coverage",
"pre-checkin": "npm run format && npm run build && npm test"
},
"repository": {
@ -23,7 +23,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^1.0.8",
"@actions/cache": "^3.0.0",
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^1.1.0",
@ -37,7 +37,7 @@
"@types/jest": "^27.0.2",
"@types/node": "^16.11.25",
"@types/semver": "^6.0.0",
"@zeit/ncc": "^0.21.0",
"@vercel/ncc": "^0.33.4",
"jest": "^27.2.5",
"jest-circus": "^27.2.5",
"prettier": "^1.19.1",

View file

@ -49,18 +49,12 @@ const cachePackages = async (packageManager: string) => {
return;
}
try {
await cache.saveCache([cachePath], primaryKey);
const cacheId = await cache.saveCache([cachePath], primaryKey);
if (cacheId == -1) {
return;
}
core.info(`Cache saved with the key: ${primaryKey}`);
} catch (error) {
if (error.name === cache.ValidationError.name) {
throw error;
} else if (error.name === cache.ReserveCacheError.name) {
core.info(error.message);
} else {
core.warning(`${error.message}`);
}
}
};
run();

View file

@ -1,5 +1,6 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as cache from '@actions/cache';
type SupportedPackageManagers = {
[prop: string]: PackageManagerInfo;
@ -12,12 +13,12 @@ export interface PackageManagerInfo {
export const supportedPackageManagers: SupportedPackageManagers = {
npm: {
lockFilePatterns: ['package-lock.json', 'yarn.lock'],
lockFilePatterns: ['package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock'],
getCacheFolderCommand: 'npm config get cache'
},
pnpm: {
lockFilePatterns: ['pnpm-lock.yaml'],
getCacheFolderCommand: 'pnpm store path'
getCacheFolderCommand: 'pnpm store path --silent'
},
yarn1: {
lockFilePatterns: ['yarn.lock'],
@ -93,5 +94,30 @@ export const getCacheDirectoryPath = async (
core.debug(`${packageManager} path is ${stdOut}`);
return stdOut;
return stdOut.trim();
};
export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
export function isCacheFeatureAvailable(): boolean {
if (!cache.isFeatureAvailable()) {
if (isGhes()) {
throw new Error(
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.'
);
} else {
core.warning(
'The runner was not able to contact the cache service. Caching will be skipped'
);
}
return false;
}
return true;
}

View file

@ -37,6 +37,7 @@ export async function getNode(
) {
// Store manifest data to avoid multiple calls
let manifest: INodeRelease[] | undefined;
let nodeVersions: INodeVersion[] | undefined;
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
@ -49,6 +50,12 @@ export async function getNode(
versionSpec = resolveLtsAliasFromManifest(versionSpec, stable, manifest);
}
if (isLatestSyntax(versionSpec)) {
nodeVersions = await getVersionsFromDist();
versionSpec = await queryDistForMatch(versionSpec, arch, nodeVersions);
core.info(`getting latest node version...`);
}
if (checkLatest) {
core.info('Attempt to resolve the latest version from manifest...');
const resolvedVersion = await resolveVersionFromManifest(
@ -119,7 +126,7 @@ export async function getNode(
// Download from nodejs.org
//
if (!downloadPath) {
info = await getInfoFromDist(versionSpec, arch);
info = await getInfoFromDist(versionSpec, arch, nodeVersions);
if (!info) {
throw new Error(
`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
@ -216,13 +223,21 @@ function resolveLtsAliasFromManifest(
core.debug(`LTS alias '${alias}' for Node version '${versionSpec}'`);
// Supported formats are `lts/<alias>` and `lts/*`. Where asterisk means highest possible LTS.
// Supported formats are `lts/<alias>`, `lts/*`, and `lts/-n`. Where asterisk means highest possible LTS and -n means the nth-highest.
const n = Number(alias);
const aliases = Object.fromEntries(
manifest
.filter(x => x.lts && x.stable === stable)
.map(x => [x.lts!.toLowerCase(), x])
.reverse()
);
const numbered = Object.values(aliases);
const release =
alias === '*'
? manifest.find(x => !!x.lts && x.stable === stable)
: manifest.find(
x => x.lts?.toLowerCase() === alias && x.stable === stable
);
? numbered[numbered.length - 1]
: n < 0
? numbered[numbered.length - 1 + n]
: aliases[alias];
if (!release) {
throw new Error(
@ -265,14 +280,18 @@ async function getInfoFromManifest(
async function getInfoFromDist(
versionSpec: string,
arch: string = os.arch()
arch: string = os.arch(),
nodeVersions?: INodeVersion[]
): Promise<INodeVersionInfo | null> {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
let version: string;
let version: string = await queryDistForMatch(
versionSpec,
arch,
nodeVersions
);
version = await queryDistForMatch(versionSpec, arch);
if (!version) {
return null;
}
@ -349,7 +368,8 @@ function evaluateVersions(versions: string[], versionSpec: string): string {
async function queryDistForMatch(
versionSpec: string,
arch: string = os.arch()
arch: string = os.arch(),
nodeVersions?: INodeVersion[]
): Promise<string> {
let osPlat: string = os.platform();
let osArch: string = translateArchToDistUrl(arch);
@ -370,8 +390,17 @@ async function queryDistForMatch(
throw new Error(`Unexpected OS '${osPlat}'`);
}
if (!nodeVersions) {
core.debug('No dist manifest cached');
nodeVersions = await getVersionsFromDist();
}
let versions: string[] = [];
let nodeVersions = await getVersionsFromDist();
if (isLatestSyntax(versionSpec)) {
core.info(`getting latest node version...`);
return nodeVersions[0].version;
}
nodeVersions.forEach((nodeVersion: INodeVersion) => {
// ensure this version supports your os and platform
@ -466,10 +495,32 @@ function translateArchToDistUrl(arch: string): string {
}
export function parseNodeVersionFile(contents: string): string {
let nodeVersion = contents.trim();
let nodeVersion: string | undefined;
if (/^v\d/.test(nodeVersion)) {
nodeVersion = nodeVersion.substring(1);
// Try parsing the file as an NPM `package.json`
// file.
try {
nodeVersion = JSON.parse(contents).engines?.node;
} catch {
core.warning('Node version file is not JSON file');
}
return nodeVersion;
if (!nodeVersion) {
try {
const found = contents.match(/^(?:nodejs\s+)?v?(?<version>[^\s]+)$/m);
nodeVersion = found?.groups?.version;
if (!nodeVersion) throw new Error();
} catch (err) {
// In the case of an unknown format,
// return as is and evaluate the version separately.
nodeVersion = contents.trim();
}
}
return nodeVersion as string;
}
function isLatestSyntax(versionSpec): boolean {
return ['current', 'latest', 'node'].includes(versionSpec);
}

View file

@ -1,10 +1,11 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as installer from './installer';
import fs from 'fs';
import * as auth from './authutil';
import * as path from 'path';
import {restoreCache} from './cache-restore';
import {URL} from 'url';
import {isGhes, isCacheFeatureAvailable} from './cache-utils';
import os = require('os');
export async function run() {
@ -39,16 +40,25 @@ export async function run() {
await installer.getNode(version, stable, checkLatest, auth, arch);
}
// Output version of node is being used
try {
const {stdout: installedVersion} = await exec.getExecOutput(
'node',
['--version'],
{ignoreReturnCode: true, silent: true}
);
core.setOutput('node-version', installedVersion.trim());
} catch (err) {
core.setOutput('node-version', '');
}
const registryUrl: string = core.getInput('registry-url');
const alwaysAuth: string = core.getInput('always-auth');
if (registryUrl) {
auth.configAuthentication(registryUrl, alwaysAuth);
}
if (cache) {
if (isGhes()) {
throw new Error('Caching is not supported on GHES');
}
if (cache && isCacheFeatureAvailable()) {
const cacheDependencyPath = core.getInput('cache-dependency-path');
await restoreCache(cache, cacheDependencyPath);
}
@ -66,13 +76,6 @@ export async function run() {
}
}
function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
function resolveVersionInput(): string {
let version = core.getInput('node-version');
const versionFileInput = core.getInput('node-version-file');