mirror of
https://github.com/actions/setup-node.git
synced 2025-12-18 14:58:57 +08:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27082cecf3 | ||
|
|
05e7d6cc23 | ||
|
|
d6fea3c137 | ||
|
|
4667755142 | ||
|
|
2bbfc7698a | ||
|
|
5984462aaa | ||
|
|
aabe026707 | ||
|
|
b7cfa22539 | ||
|
|
70b9252472 | ||
|
|
c6fd00ceb9 | ||
|
|
2f532cef8f | ||
|
|
c211e95e60 | ||
|
|
99d584aa06 | ||
|
|
2a5c060ce2 | ||
|
|
2801f51f90 | ||
|
|
0a161fe2f9 | ||
|
|
63fffe4411 | ||
|
|
a83bf51129 | ||
|
|
922f2f9468 | ||
|
|
7a3669aa8a | ||
|
|
66f3e9f7ce | ||
|
|
82271389a6 | ||
|
|
2e40994c28 | ||
|
|
c7e4d38541 | ||
|
|
3eb4bc9d68 | ||
|
|
bf47decdc2 | ||
|
|
6afbfca452 | ||
|
|
3e84c3523b | ||
|
|
6668516d2a | ||
|
|
f27ebaf08b | ||
|
|
42d59fbc36 | ||
|
|
2d8887128d | ||
|
|
0635b31a61 | ||
|
|
59e61b8951 | ||
|
|
321b6ccb03 | ||
|
|
1ae8f4b1fd | ||
|
|
0e2f9cde8b |
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Set default behavior to automatically normalize line endings, and force everything to be LF, except for Windows batch files that require CRLF, so that if a repo is accessed in Unix via a file share from Windows, the scripts will work.
|
||||||
|
* text=auto eol=lf
|
||||||
|
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||||
|
*.{bat,[bB][aA][tT]} text eol=crlf
|
||||||
|
.licenses/** -diff linguist-generated=true
|
||||||
4
.github/workflows/build-test.yml
vendored
4
.github/workflows/build-test.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest]
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Setup node 12
|
- name: Setup node 12
|
||||||
|
|||||||
20
.github/workflows/licensed.yml
vendored
Normal file
20
.github/workflows/licensed.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Licensed
|
||||||
|
|
||||||
|
on:
|
||||||
|
push: {branches: main}
|
||||||
|
pull_request: {branches: main}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Check licenses
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- run: npm ci
|
||||||
|
- name: Install licensed
|
||||||
|
run: |
|
||||||
|
cd $RUNNER_TEMP
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
||||||
|
sudo tar -xzf licensed.tar.gz
|
||||||
|
sudo mv licensed /usr/local/bin/licensed
|
||||||
|
- run: licensed status
|
||||||
97
.github/workflows/versions.yml
vendored
97
.github/workflows/versions.yml
vendored
@@ -6,42 +6,107 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
versions:
|
local-cache:
|
||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest]
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
defaults:
|
node-version: [10, 12, 14]
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
# test version that falls through to node dist
|
- name: Setup Node
|
||||||
- name: Setup node 11 from dist
|
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
node-version: 11
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Verify node and npm
|
- name: Verify node and npm
|
||||||
run: __tests__/verify-node.sh 11
|
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
manifest:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
node-version: [10.15, 12.16.0, 14.2.0]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup Node
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- name: Verify node and npm
|
||||||
|
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
check-latest:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
node-version: [10, 11, 12, 14]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup Node and check latest
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
check-latest: true
|
||||||
|
- name: Verify node and npm
|
||||||
|
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
node-dist:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
node-version: [11, 13]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup Node from dist
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- name: Verify node and npm
|
||||||
|
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
old-versions:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
# test old versions which didn't have npm and layout different
|
# test old versions which didn't have npm and layout different
|
||||||
- name: Setup node 0.12.18 from dist
|
- name: Setup node 0.12.18 from dist
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
node-version: 0.12.18
|
node-version: 0.12.18
|
||||||
- name: Verify node
|
- name: Verify node
|
||||||
shell: bash
|
|
||||||
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
|
run: __tests__/verify-node.sh 0.12.18 SKIP_NPM
|
||||||
# test version from node manifest
|
shell: bash
|
||||||
- name: Setup node 12.16.2 from manifest
|
|
||||||
|
arch:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup node 12 x86 from dist
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
node-version: 12.16.2
|
node-version: '12'
|
||||||
- name: Verify node and npm
|
architecture: 'x86'
|
||||||
run: __tests__/verify-node.sh 12
|
- name: Verify node
|
||||||
|
run: __tests__/verify-arch.sh "ia32"
|
||||||
|
shell: bash
|
||||||
14
.licensed.yml
Normal file
14
.licensed.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
sources:
|
||||||
|
npm: true
|
||||||
|
|
||||||
|
allowed:
|
||||||
|
- apache-2.0
|
||||||
|
- bsd-2-clause
|
||||||
|
- bsd-3-clause
|
||||||
|
- isc
|
||||||
|
- mit
|
||||||
|
- cc0-1.0
|
||||||
|
- unlicense
|
||||||
|
|
||||||
|
reviewed:
|
||||||
|
npm:
|
||||||
BIN
.licenses/npm/@actions/core-1.2.4.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/core-1.2.4.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/core-1.2.6.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/core-1.2.6.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.6.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.6.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/auth-token.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/auth-token.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/types.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/types.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@types/node.dep.yml
generated
Normal file
BIN
.licenses/npm/@types/node.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/once.dep.yml
generated
Normal file
BIN
.licenses/npm/once.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-6.1.2.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-6.1.2.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/uuid.dep.yml
generated
Normal file
BIN
.licenses/npm/uuid.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/which.dep.yml
generated
Normal file
BIN
.licenses/npm/which.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
Binary file not shown.
1
CODEOWNERS
Normal file
1
CODEOWNERS
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @actions/spark
|
||||||
87
README.md
87
README.md
@@ -1,7 +1,7 @@
|
|||||||
# setup-node
|
# setup-node
|
||||||
|
|
||||||
<p align="left">
|
<p align="left">
|
||||||
<a href="https://github.com/actions/setup-node"><img alt="GitHub Actions status" src="https://github.com/actions/setup-node/workflows/Main%20workflow/badge.svg"></a>
|
<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>
|
</p>
|
||||||
|
|
||||||
This action sets by node environment for use in actions by:
|
This action sets by node environment for use in actions by:
|
||||||
@@ -10,6 +10,22 @@ This action sets by node environment for use in actions by:
|
|||||||
- registering problem matchers for error output
|
- registering problem matchers for error output
|
||||||
- configuring authentication for GPR or npm
|
- configuring authentication for GPR or npm
|
||||||
|
|
||||||
|
# v2-beta
|
||||||
|
|
||||||
|
A beta release which adds reliability for pulling node distributions from a cache of node releases is available by referencing the `v2-beta` tag.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2-beta
|
||||||
|
with:
|
||||||
|
node-version: '12'
|
||||||
|
```
|
||||||
|
|
||||||
|
It will first check the local cache for a semver match. The hosted images have been updated with the latest of each LTS from v8, v10, v12, and v14. `self-hosted` machines will benefit from the cache as well only downloading once. It will pull LTS versions from `main` branch of [node-versions](https://github.com/actions/node-versions/blob/main/versions-manifest.json) repository and on miss or failure, it will fall back to the previous behavior of download directly from [node dist](https://nodejs.org/dist/).
|
||||||
|
|
||||||
|
The `node-version` input is optional. If not supplied, node which is in your PATH will be used. However, this action will still register problem matchers and support auth features. So setting up the node environment is still a valid scenario without downloading and caching versions.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
See [action.yml](action.yml)
|
See [action.yml](action.yml)
|
||||||
@@ -25,6 +41,20 @@ steps:
|
|||||||
- run: npm test
|
- run: npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Check latest version:
|
||||||
|
> In basic example, without `check-latest` flag, the action tries to resolve version from local cache firstly and download only if it is not found. Local cache on image is updated with a couple of weeks latency.
|
||||||
|
`check-latest` flag forces the action to check if the cached version is the latest one. It reduces latency significantly but it is much more likely to incur version downloading.
|
||||||
|
```yaml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2-beta
|
||||||
|
with:
|
||||||
|
node-version: '12'
|
||||||
|
check-latest: true
|
||||||
|
- run: npm install
|
||||||
|
- run: npm test
|
||||||
|
```
|
||||||
|
|
||||||
Matrix Testing:
|
Matrix Testing:
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
jobs:
|
||||||
@@ -44,6 +74,61 @@ jobs:
|
|||||||
- run: npm test
|
- run: npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Architecture:
|
||||||
|
|
||||||
|
You can use any of the [supported operating systems](https://docs.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners), and the compatible `architecture` can be selected using `architecture`. Values are `x86`, `x64`, `arm64`, `armv6l`, `armv7l`, `ppc64le`, `s390x` (not all of the architectures are available on all platforms).
|
||||||
|
|
||||||
|
When using `architecture`, `node-version` must be provided as well.
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
name: Node sample
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: '12'
|
||||||
|
architecture: 'x64' # optional, x64 or x86. If not specified, x64 will be used by default
|
||||||
|
- run: npm install
|
||||||
|
- run: npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple Operating Systems and Architectures:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
- macos-latest
|
||||||
|
- windows-latest
|
||||||
|
node_version:
|
||||||
|
- 10
|
||||||
|
- 12
|
||||||
|
- 14
|
||||||
|
architecture:
|
||||||
|
- x64
|
||||||
|
# an extra windows-x86 run:
|
||||||
|
include:
|
||||||
|
- os: windows-2016
|
||||||
|
node_version: 12
|
||||||
|
architecture: x86
|
||||||
|
name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node_version }}
|
||||||
|
architecture: ${{ matrix.architecture }}
|
||||||
|
- run: npm install
|
||||||
|
- run: npm test
|
||||||
|
```
|
||||||
|
|
||||||
Publish to npmjs and GPR with npm:
|
Publish to npmjs and GPR with npm:
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ describe('authutil tests', () => {
|
|||||||
.toString(36)
|
.toString(36)
|
||||||
.substring(7)
|
.substring(7)
|
||||||
);
|
);
|
||||||
|
console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
|
||||||
|
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
|
||||||
const tempDir = path.join(_runnerDir, randPath, 'temp');
|
const tempDir = path.join(_runnerDir, randPath, 'temp');
|
||||||
await io.rmRF(tempDir);
|
await io.rmRF(tempDir);
|
||||||
await io.mkdirP(tempDir);
|
await io.mkdirP(tempDir);
|
||||||
@@ -61,6 +63,7 @@ describe('authutil tests', () => {
|
|||||||
if (_runnerDir) {
|
if (_runnerDir) {
|
||||||
await io.rmRF(_runnerDir);
|
await io.rmRF(_runnerDir);
|
||||||
}
|
}
|
||||||
|
console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
|
||||||
}, 100000);
|
}, 100000);
|
||||||
|
|
||||||
function readRcFile(rcFile: string) {
|
function readRcFile(rcFile: string) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import path from 'path';
|
|||||||
import * as main from '../src/main';
|
import * as main from '../src/main';
|
||||||
import * as im from '../src/installer';
|
import * as im from '../src/installer';
|
||||||
import * as auth from '../src/authutil';
|
import * as auth from '../src/authutil';
|
||||||
|
import {context} from '@actions/github';
|
||||||
|
|
||||||
let nodeTestManifest = require('./data/versions-manifest.json');
|
let nodeTestManifest = require('./data/versions-manifest.json');
|
||||||
let nodeTestDist = require('./data/node-dist-index.json');
|
let nodeTestDist = require('./data/node-dist-index.json');
|
||||||
@@ -24,6 +25,7 @@ describe('setup-node', () => {
|
|||||||
let findSpy: jest.SpyInstance;
|
let findSpy: jest.SpyInstance;
|
||||||
let cnSpy: jest.SpyInstance;
|
let cnSpy: jest.SpyInstance;
|
||||||
let logSpy: jest.SpyInstance;
|
let logSpy: jest.SpyInstance;
|
||||||
|
let warningSpy: jest.SpyInstance;
|
||||||
let getManifestSpy: jest.SpyInstance;
|
let getManifestSpy: jest.SpyInstance;
|
||||||
let getDistSpy: jest.SpyInstance;
|
let getDistSpy: jest.SpyInstance;
|
||||||
let platSpy: jest.SpyInstance;
|
let platSpy: jest.SpyInstance;
|
||||||
@@ -40,6 +42,8 @@ describe('setup-node', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// @actions/core
|
// @actions/core
|
||||||
|
console.log('::stop-commands::stoptoken'); // Disable executing of runner commands when running tests in actions
|
||||||
|
process.env['GITHUB_PATH'] = ''; // Stub out ENV file functionality so we can verify it writes to standard out
|
||||||
inputs = {};
|
inputs = {};
|
||||||
inSpy = jest.spyOn(core, 'getInput');
|
inSpy = jest.spyOn(core, 'getInput');
|
||||||
inSpy.mockImplementation(name => inputs[name]);
|
inSpy.mockImplementation(name => inputs[name]);
|
||||||
@@ -77,8 +81,9 @@ describe('setup-node', () => {
|
|||||||
|
|
||||||
// writes
|
// writes
|
||||||
cnSpy = jest.spyOn(process.stdout, 'write');
|
cnSpy = jest.spyOn(process.stdout, 'write');
|
||||||
logSpy = jest.spyOn(console, 'log');
|
logSpy = jest.spyOn(core, 'info');
|
||||||
dbgSpy = jest.spyOn(core, 'debug');
|
dbgSpy = jest.spyOn(core, 'debug');
|
||||||
|
warningSpy = jest.spyOn(core, 'warning');
|
||||||
cnSpy.mockImplementation(line => {
|
cnSpy.mockImplementation(line => {
|
||||||
// uncomment to debug
|
// uncomment to debug
|
||||||
// process.stderr.write('write:' + line + '\n');
|
// process.stderr.write('write:' + line + '\n');
|
||||||
@@ -99,7 +104,9 @@ describe('setup-node', () => {
|
|||||||
//jest.restoreAllMocks();
|
//jest.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {}, 100000);
|
afterAll(async () => {
|
||||||
|
console.log('::stoptoken::'); // Re-enable executing of runner commands when running tests in actions
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Manifest find tests
|
// Manifest find tests
|
||||||
@@ -245,7 +252,7 @@ describe('setup-node', () => {
|
|||||||
expect(dlSpy).toHaveBeenCalled();
|
expect(dlSpy).toHaveBeenCalled();
|
||||||
expect(exSpy).toHaveBeenCalled();
|
expect(exSpy).toHaveBeenCalled();
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
`Acquiring ${resolvedVersion} from ${expectedUrl}`
|
`Acquiring ${resolvedVersion} - ${os.arch} from ${expectedUrl}`
|
||||||
);
|
);
|
||||||
expect(logSpy).toHaveBeenCalledWith(
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
`Attempting to download ${versionSpec}...`
|
`Attempting to download ${versionSpec}...`
|
||||||
@@ -333,4 +340,194 @@ describe('setup-node', () => {
|
|||||||
|
|
||||||
expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
|
expect(cnSpy).toHaveBeenCalledWith(`::error::${errMsg}${osm.EOL}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Acquires specified architecture of node', async () => {
|
||||||
|
for (const {arch, version, osSpec} of [
|
||||||
|
{arch: 'x86', version: '12.16.2', osSpec: 'win32'},
|
||||||
|
{arch: 'x86', version: '14.0.0', osSpec: 'win32'}
|
||||||
|
]) {
|
||||||
|
os.platform = osSpec;
|
||||||
|
os.arch = arch;
|
||||||
|
const fileExtension = os.platform === 'win32' ? '7z' : 'tar.gz';
|
||||||
|
const platform = {
|
||||||
|
linux: 'linux',
|
||||||
|
darwin: 'darwin',
|
||||||
|
win32: 'win'
|
||||||
|
}[os.platform];
|
||||||
|
|
||||||
|
inputs['node-version'] = version;
|
||||||
|
inputs['architecture'] = arch;
|
||||||
|
inputs['always-auth'] = false;
|
||||||
|
inputs['token'] = 'faketoken';
|
||||||
|
|
||||||
|
let expectedUrl =
|
||||||
|
arch === 'x64'
|
||||||
|
? `https://github.com/actions/node-versions/releases/download/${version}/node-${version}-${platform}-${arch}.zip`
|
||||||
|
: `https://nodejs.org/dist/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
|
||||||
|
|
||||||
|
// ... but not in the local cache
|
||||||
|
findSpy.mockImplementation(() => '');
|
||||||
|
|
||||||
|
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||||
|
let toolPath = path.normalize(`/cache/node/${version}/${arch}`);
|
||||||
|
exSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||||
|
cacheSpy.mockImplementation(async () => toolPath);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
expect(dlSpy).toHaveBeenCalled();
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Acquiring ${version} - ${arch} from ${expectedUrl}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
describe('check-latest flag', () => {
|
||||||
|
it('use local version and dont check manifest if check-latest is not specified', async () => {
|
||||||
|
os.platform = 'linux';
|
||||||
|
os.arch = 'x64';
|
||||||
|
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['check-latest'] = 'false';
|
||||||
|
|
||||||
|
const toolPath = path.normalize('/cache/node/12.16.1/x64');
|
||||||
|
findSpy.mockReturnValue(toolPath);
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
|
||||||
|
expect(logSpy).not.toHaveBeenCalledWith(
|
||||||
|
'Attempt to resolve the latest version from manifest...'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('check latest version and resolve it from local cache', async () => {
|
||||||
|
os.platform = 'linux';
|
||||||
|
os.arch = 'x64';
|
||||||
|
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['check-latest'] = 'true';
|
||||||
|
|
||||||
|
const toolPath = path.normalize('/cache/node/12.16.2/x64');
|
||||||
|
findSpy.mockReturnValue(toolPath);
|
||||||
|
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||||
|
exSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||||
|
cacheSpy.mockImplementation(async () => toolPath);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
'Attempt to resolve the latest version from manifest...'
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(`Found in cache @ ${toolPath}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('check latest version and install it from manifest', async () => {
|
||||||
|
os.platform = 'linux';
|
||||||
|
os.arch = 'x64';
|
||||||
|
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['check-latest'] = 'true';
|
||||||
|
|
||||||
|
findSpy.mockImplementation(() => '');
|
||||||
|
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||||
|
const toolPath = path.normalize('/cache/node/12.16.2/x64');
|
||||||
|
exSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||||
|
cacheSpy.mockImplementation(async () => toolPath);
|
||||||
|
const expectedUrl =
|
||||||
|
'https://github.com/actions/node-versions/releases/download/12.16.2-20200423.28/node-12.16.2-linux-x64.tar.gz';
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
'Attempt to resolve the latest version from manifest...'
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith("Resolved as '12.16.2'");
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Acquiring 12.16.2 - ${os.arch} from ${expectedUrl}`
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith('Extracting ...');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fallback to dist if version if not found in manifest', async () => {
|
||||||
|
os.platform = 'linux';
|
||||||
|
os.arch = 'x64';
|
||||||
|
|
||||||
|
// a version which is not in the manifest but is in node dist
|
||||||
|
let versionSpec = '11';
|
||||||
|
|
||||||
|
inputs['node-version'] = versionSpec;
|
||||||
|
inputs['check-latest'] = 'true';
|
||||||
|
inputs['always-auth'] = false;
|
||||||
|
inputs['token'] = 'faketoken';
|
||||||
|
|
||||||
|
// ... but not in the local cache
|
||||||
|
findSpy.mockImplementation(() => '');
|
||||||
|
|
||||||
|
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||||
|
let toolPath = path.normalize('/cache/node/11.11.0/x64');
|
||||||
|
exSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||||
|
cacheSpy.mockImplementation(async () => toolPath);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
let expPath = path.join(toolPath, 'bin');
|
||||||
|
|
||||||
|
expect(dlSpy).toHaveBeenCalled();
|
||||||
|
expect(exSpy).toHaveBeenCalled();
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
'Attempt to resolve the latest version from manifest...'
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Failed to resolve version ${versionSpec} from manifest`
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Attempting to download ${versionSpec}...`
|
||||||
|
);
|
||||||
|
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fallback to dist if manifest is not available', async () => {
|
||||||
|
os.platform = 'linux';
|
||||||
|
os.arch = 'x64';
|
||||||
|
|
||||||
|
// a version which is not in the manifest but is in node dist
|
||||||
|
let versionSpec = '12';
|
||||||
|
|
||||||
|
inputs['node-version'] = versionSpec;
|
||||||
|
inputs['check-latest'] = 'true';
|
||||||
|
inputs['always-auth'] = false;
|
||||||
|
inputs['token'] = 'faketoken';
|
||||||
|
|
||||||
|
// ... but not in the local cache
|
||||||
|
findSpy.mockImplementation(() => '');
|
||||||
|
getManifestSpy.mockImplementation(() => {
|
||||||
|
throw new Error('Unable to download manifest');
|
||||||
|
});
|
||||||
|
|
||||||
|
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||||
|
let toolPath = path.normalize('/cache/node/12.11.0/x64');
|
||||||
|
exSpy.mockImplementation(async () => '/some/other/temp/path');
|
||||||
|
cacheSpy.mockImplementation(async () => toolPath);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
let expPath = path.join(toolPath, 'bin');
|
||||||
|
|
||||||
|
expect(dlSpy).toHaveBeenCalled();
|
||||||
|
expect(exSpy).toHaveBeenCalled();
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
'Attempt to resolve the latest version from manifest...'
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
'Unable to resolve version from manifest...'
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Failed to resolve version ${versionSpec} from manifest`
|
||||||
|
);
|
||||||
|
expect(logSpy).toHaveBeenCalledWith(
|
||||||
|
`Attempting to download ${versionSpec}...`
|
||||||
|
);
|
||||||
|
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
11
__tests__/verify-arch.sh
Normal file
11
__tests__/verify-arch.sh
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
architecture="$(node -e 'console.log(process.arch)')"
|
||||||
|
if [ -z "$(echo $architecture | grep --fixed-strings $1)" ]; then
|
||||||
|
echo "Unexpected architecture"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Skip testing architecture"
|
||||||
|
fi
|
||||||
@@ -7,6 +7,11 @@ 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'
|
||||||
|
architecture:
|
||||||
|
description: 'Target architecture for Node to use. Examples: x86, x64. Will use system architecture by default.'
|
||||||
|
check-latest:
|
||||||
|
description: 'Set this option if you want the action to check for the latest available version that satisfies the version spec'
|
||||||
|
default: false
|
||||||
registry-url:
|
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:
|
scope:
|
||||||
|
|||||||
223
dist/index.js
vendored
223
dist/index.js
vendored
@@ -3028,6 +3028,32 @@ const windowsRelease = release => {
|
|||||||
module.exports = windowsRelease;
|
module.exports = windowsRelease;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 82:
|
||||||
|
/***/ (function(__unusedmodule, exports) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// We use any as a valid input type
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
/**
|
||||||
|
* Sanitizes an input into a string so it can be passed into issueCommand safely
|
||||||
|
* @param input input to sanitize into a string
|
||||||
|
*/
|
||||||
|
function toCommandValue(input) {
|
||||||
|
if (input === null || input === undefined) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
else if (typeof input === 'string' || input instanceof String) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
return JSON.stringify(input);
|
||||||
|
}
|
||||||
|
exports.toCommandValue = toCommandValue;
|
||||||
|
//# sourceMappingURL=utils.js.map
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 87:
|
/***/ 87:
|
||||||
@@ -3037,6 +3063,42 @@ module.exports = require("os");
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 102:
|
||||||
|
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// For internal use, subject to change.
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||||
|
result["default"] = mod;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
// We use any as a valid input type
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
const fs = __importStar(__webpack_require__(747));
|
||||||
|
const os = __importStar(__webpack_require__(87));
|
||||||
|
const utils_1 = __webpack_require__(82);
|
||||||
|
function issueCommand(command, message) {
|
||||||
|
const filePath = process.env[`GITHUB_${command}`];
|
||||||
|
if (!filePath) {
|
||||||
|
throw new Error(`Unable to find environment variable for file command ${command}`);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
throw new Error(`Missing file at path: ${filePath}`);
|
||||||
|
}
|
||||||
|
fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {
|
||||||
|
encoding: 'utf8'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.issueCommand = issueCommand;
|
||||||
|
//# sourceMappingURL=file-command.js.map
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
/***/ 108:
|
/***/ 108:
|
||||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||||
|
|
||||||
@@ -4632,6 +4694,7 @@ const installer = __importStar(__webpack_require__(749));
|
|||||||
const auth = __importStar(__webpack_require__(202));
|
const auth = __importStar(__webpack_require__(202));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
const url_1 = __webpack_require__(835);
|
const url_1 = __webpack_require__(835);
|
||||||
|
const os = __webpack_require__(87);
|
||||||
function run() {
|
function run() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
@@ -4643,12 +4706,21 @@ function run() {
|
|||||||
if (!version) {
|
if (!version) {
|
||||||
version = core.getInput('version');
|
version = core.getInput('version');
|
||||||
}
|
}
|
||||||
console.log(`version: ${version}`);
|
let arch = core.getInput('architecture');
|
||||||
|
// if architecture supplied but node-version is not
|
||||||
|
// if we don't throw a warning, the already installed x64 node will be used which is not probably what user meant.
|
||||||
|
if (arch && !version) {
|
||||||
|
core.warning('`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed. To fix this, provide `architecture` in combination with `node-version`');
|
||||||
|
}
|
||||||
|
if (!arch) {
|
||||||
|
arch = os.arch();
|
||||||
|
}
|
||||||
if (version) {
|
if (version) {
|
||||||
let token = core.getInput('token');
|
let token = core.getInput('token');
|
||||||
let auth = !token || isGhes() ? undefined : `token ${token}`;
|
let auth = !token || isGhes() ? undefined : `token ${token}`;
|
||||||
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
||||||
yield installer.getNode(version, stable, auth);
|
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
|
||||||
|
yield installer.getNode(version, stable, checkLatest, auth, arch);
|
||||||
}
|
}
|
||||||
const registryUrl = core.getInput('registry-url');
|
const registryUrl = core.getInput('registry-url');
|
||||||
const alwaysAuth = core.getInput('always-auth');
|
const alwaysAuth = core.getInput('always-auth');
|
||||||
@@ -8396,6 +8468,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const os = __importStar(__webpack_require__(87));
|
const os = __importStar(__webpack_require__(87));
|
||||||
|
const utils_1 = __webpack_require__(82);
|
||||||
/**
|
/**
|
||||||
* Commands
|
* Commands
|
||||||
*
|
*
|
||||||
@@ -8450,13 +8523,13 @@ class Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function escapeData(s) {
|
function escapeData(s) {
|
||||||
return (s || '')
|
return utils_1.toCommandValue(s)
|
||||||
.replace(/%/g, '%25')
|
.replace(/%/g, '%25')
|
||||||
.replace(/\r/g, '%0D')
|
.replace(/\r/g, '%0D')
|
||||||
.replace(/\n/g, '%0A');
|
.replace(/\n/g, '%0A');
|
||||||
}
|
}
|
||||||
function escapeProperty(s) {
|
function escapeProperty(s) {
|
||||||
return (s || '')
|
return utils_1.toCommandValue(s)
|
||||||
.replace(/%/g, '%25')
|
.replace(/%/g, '%25')
|
||||||
.replace(/\r/g, '%0D')
|
.replace(/\r/g, '%0D')
|
||||||
.replace(/\n/g, '%0A')
|
.replace(/\n/g, '%0A')
|
||||||
@@ -10381,6 +10454,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const command_1 = __webpack_require__(431);
|
const command_1 = __webpack_require__(431);
|
||||||
|
const file_command_1 = __webpack_require__(102);
|
||||||
|
const utils_1 = __webpack_require__(82);
|
||||||
const os = __importStar(__webpack_require__(87));
|
const os = __importStar(__webpack_require__(87));
|
||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
/**
|
/**
|
||||||
@@ -10403,11 +10478,21 @@ var ExitCode;
|
|||||||
/**
|
/**
|
||||||
* Sets env variable for this action and future actions in the job
|
* Sets env variable for this action and future actions in the job
|
||||||
* @param name the name of the variable to set
|
* @param name the name of the variable to set
|
||||||
* @param val the value of the variable
|
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function exportVariable(name, val) {
|
function exportVariable(name, val) {
|
||||||
process.env[name] = val;
|
const convertedVal = utils_1.toCommandValue(val);
|
||||||
command_1.issueCommand('set-env', { name }, val);
|
process.env[name] = convertedVal;
|
||||||
|
const filePath = process.env['GITHUB_ENV'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
const delimiter = '_GitHubActionsFileCommandDelimeter_';
|
||||||
|
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
|
||||||
|
file_command_1.issueCommand('ENV', commandValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command_1.issueCommand('set-env', { name }, convertedVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.exportVariable = exportVariable;
|
exports.exportVariable = exportVariable;
|
||||||
/**
|
/**
|
||||||
@@ -10423,7 +10508,13 @@ exports.setSecret = setSecret;
|
|||||||
* @param inputPath
|
* @param inputPath
|
||||||
*/
|
*/
|
||||||
function addPath(inputPath) {
|
function addPath(inputPath) {
|
||||||
command_1.issueCommand('add-path', {}, inputPath);
|
const filePath = process.env['GITHUB_PATH'] || '';
|
||||||
|
if (filePath) {
|
||||||
|
file_command_1.issueCommand('PATH', inputPath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
command_1.issueCommand('add-path', {}, inputPath);
|
||||||
|
}
|
||||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||||
}
|
}
|
||||||
exports.addPath = addPath;
|
exports.addPath = addPath;
|
||||||
@@ -10446,12 +10537,22 @@ exports.getInput = getInput;
|
|||||||
* Sets the value of an output.
|
* Sets the value of an output.
|
||||||
*
|
*
|
||||||
* @param name name of the output to set
|
* @param name name of the output to set
|
||||||
* @param value value to store
|
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function setOutput(name, value) {
|
function setOutput(name, value) {
|
||||||
command_1.issueCommand('set-output', { name }, value);
|
command_1.issueCommand('set-output', { name }, value);
|
||||||
}
|
}
|
||||||
exports.setOutput = setOutput;
|
exports.setOutput = setOutput;
|
||||||
|
/**
|
||||||
|
* Enables or disables the echoing of commands into stdout for the rest of the step.
|
||||||
|
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function setCommandEcho(enabled) {
|
||||||
|
command_1.issue('echo', enabled ? 'on' : 'off');
|
||||||
|
}
|
||||||
|
exports.setCommandEcho = setCommandEcho;
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Results
|
// Results
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
@@ -10468,6 +10569,13 @@ exports.setFailed = setFailed;
|
|||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Logging Commands
|
// Logging Commands
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Gets whether Actions Step Debug is on or not
|
||||||
|
*/
|
||||||
|
function isDebug() {
|
||||||
|
return process.env['RUNNER_DEBUG'] === '1';
|
||||||
|
}
|
||||||
|
exports.isDebug = isDebug;
|
||||||
/**
|
/**
|
||||||
* Writes debug message to user log
|
* Writes debug message to user log
|
||||||
* @param message debug message
|
* @param message debug message
|
||||||
@@ -10478,18 +10586,18 @@ function debug(message) {
|
|||||||
exports.debug = debug;
|
exports.debug = debug;
|
||||||
/**
|
/**
|
||||||
* Adds an error issue
|
* Adds an error issue
|
||||||
* @param message error issue message
|
* @param message error issue message. Errors will be converted to string via toString()
|
||||||
*/
|
*/
|
||||||
function error(message) {
|
function error(message) {
|
||||||
command_1.issue('error', message);
|
command_1.issue('error', message instanceof Error ? message.toString() : message);
|
||||||
}
|
}
|
||||||
exports.error = error;
|
exports.error = error;
|
||||||
/**
|
/**
|
||||||
* Adds an warning issue
|
* Adds an warning issue
|
||||||
* @param message warning issue message
|
* @param message warning issue message. Errors will be converted to string via toString()
|
||||||
*/
|
*/
|
||||||
function warning(message) {
|
function warning(message) {
|
||||||
command_1.issue('warning', message);
|
command_1.issue('warning', message instanceof Error ? message.toString() : message);
|
||||||
}
|
}
|
||||||
exports.warning = warning;
|
exports.warning = warning;
|
||||||
/**
|
/**
|
||||||
@@ -10547,8 +10655,9 @@ exports.group = group;
|
|||||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||||
*
|
*
|
||||||
* @param name name of the state to store
|
* @param name name of the state to store
|
||||||
* @param value value to store
|
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function saveState(name, value) {
|
function saveState(name, value) {
|
||||||
command_1.issueCommand('save-state', { name }, value);
|
command_1.issueCommand('save-state', { name }, value);
|
||||||
}
|
}
|
||||||
@@ -12994,61 +13103,72 @@ const tc = __importStar(__webpack_require__(533));
|
|||||||
const path = __importStar(__webpack_require__(622));
|
const path = __importStar(__webpack_require__(622));
|
||||||
const semver = __importStar(__webpack_require__(280));
|
const semver = __importStar(__webpack_require__(280));
|
||||||
const fs = __webpack_require__(747);
|
const fs = __webpack_require__(747);
|
||||||
function getNode(versionSpec, stable, auth) {
|
function getNode(versionSpec, stable, checkLatest, auth, arch = os.arch()) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let osPlat = os.platform();
|
let osPlat = os.platform();
|
||||||
let osArch = translateArchToDistUrl(os.arch());
|
let osArch = translateArchToDistUrl(arch);
|
||||||
|
if (checkLatest) {
|
||||||
|
core.info('Attempt to resolve the latest version from manifest...');
|
||||||
|
const resolvedVersion = yield resolveVersionFromManifest(versionSpec, stable, auth, osArch);
|
||||||
|
if (resolvedVersion) {
|
||||||
|
versionSpec = resolvedVersion;
|
||||||
|
core.info(`Resolved as '${versionSpec}'`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||||
|
}
|
||||||
|
}
|
||||||
// check cache
|
// check cache
|
||||||
let toolPath;
|
let toolPath;
|
||||||
toolPath = tc.find('node', versionSpec);
|
toolPath = tc.find('node', versionSpec, osArch);
|
||||||
// If not found in cache, download
|
// If not found in cache, download
|
||||||
if (toolPath) {
|
if (toolPath) {
|
||||||
console.log(`Found in cache @ ${toolPath}`);
|
core.info(`Found in cache @ ${toolPath}`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(`Attempting to download ${versionSpec}...`);
|
core.info(`Attempting to download ${versionSpec}...`);
|
||||||
let downloadPath = '';
|
let downloadPath = '';
|
||||||
let info = null;
|
let info = null;
|
||||||
//
|
//
|
||||||
// Try download from internal distribution (popular versions only)
|
// Try download from internal distribution (popular versions only)
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
info = yield getInfoFromManifest(versionSpec, stable, auth);
|
info = yield getInfoFromManifest(versionSpec, stable, auth, osArch);
|
||||||
if (info) {
|
if (info) {
|
||||||
console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
|
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
|
||||||
downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, auth);
|
downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, auth);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log('Not found in manifest. Falling back to download directly from Node');
|
core.info('Not found in manifest. Falling back to download directly from Node');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
// Rate limit?
|
// Rate limit?
|
||||||
if (err instanceof tc.HTTPError &&
|
if (err instanceof tc.HTTPError &&
|
||||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)) {
|
(err.httpStatusCode === 403 || err.httpStatusCode === 429)) {
|
||||||
console.log(`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`);
|
core.info(`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(err.message);
|
core.info(err.message);
|
||||||
}
|
}
|
||||||
core.debug(err.stack);
|
core.debug(err.stack);
|
||||||
console.log('Falling back to download directly from Node');
|
core.info('Falling back to download directly from Node');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Download from nodejs.org
|
// Download from nodejs.org
|
||||||
//
|
//
|
||||||
if (!downloadPath) {
|
if (!downloadPath) {
|
||||||
info = yield getInfoFromDist(versionSpec);
|
info = yield getInfoFromDist(versionSpec, arch);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error(`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`);
|
throw new Error(`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`);
|
||||||
}
|
}
|
||||||
console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
|
core.info(`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`);
|
||||||
try {
|
try {
|
||||||
downloadPath = yield tc.downloadTool(info.downloadUrl);
|
downloadPath = yield tc.downloadTool(info.downloadUrl);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
||||||
return yield acquireNodeFromFallbackLocation(info.resolvedVersion);
|
return yield acquireNodeFromFallbackLocation(info.resolvedVersion, info.arch);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -13056,7 +13176,7 @@ function getNode(versionSpec, stable, auth) {
|
|||||||
//
|
//
|
||||||
// Extract
|
// Extract
|
||||||
//
|
//
|
||||||
console.log('Extracting ...');
|
core.info('Extracting ...');
|
||||||
let extPath;
|
let extPath;
|
||||||
info = info || {}; // satisfy compiler, never null when reaches here
|
info = info || {}; // satisfy compiler, never null when reaches here
|
||||||
if (osPlat == 'win32') {
|
if (osPlat == 'win32') {
|
||||||
@@ -13078,9 +13198,9 @@ function getNode(versionSpec, stable, auth) {
|
|||||||
//
|
//
|
||||||
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
|
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
|
||||||
//
|
//
|
||||||
console.log('Adding to the cache ...');
|
core.info('Adding to the cache ...');
|
||||||
toolPath = yield tc.cacheDir(extPath, 'node', info.resolvedVersion);
|
toolPath = yield tc.cacheDir(extPath, 'node', info.resolvedVersion, info.arch);
|
||||||
console.log('Done');
|
core.info('Done');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// a tool installer initimately knows details about the layout of that tool
|
// a tool installer initimately knows details about the layout of that tool
|
||||||
@@ -13096,27 +13216,27 @@ function getNode(versionSpec, stable, auth) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
exports.getNode = getNode;
|
exports.getNode = getNode;
|
||||||
function getInfoFromManifest(versionSpec, stable, auth) {
|
function getInfoFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch())) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let info = null;
|
let info = null;
|
||||||
const releases = yield tc.getManifestFromRepo('actions', 'node-versions', auth);
|
const releases = yield tc.getManifestFromRepo('actions', 'node-versions', auth, 'main');
|
||||||
console.log(`matching ${versionSpec}...`);
|
const rel = yield tc.findFromManifest(versionSpec, stable, releases, osArch);
|
||||||
const rel = yield tc.findFromManifest(versionSpec, stable, releases);
|
|
||||||
if (rel && rel.files.length > 0) {
|
if (rel && rel.files.length > 0) {
|
||||||
info = {};
|
info = {};
|
||||||
info.resolvedVersion = rel.version;
|
info.resolvedVersion = rel.version;
|
||||||
|
info.arch = rel.files[0].arch;
|
||||||
info.downloadUrl = rel.files[0].download_url;
|
info.downloadUrl = rel.files[0].download_url;
|
||||||
info.fileName = rel.files[0].filename;
|
info.fileName = rel.files[0].filename;
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getInfoFromDist(versionSpec) {
|
function getInfoFromDist(versionSpec, arch = os.arch()) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let osPlat = os.platform();
|
let osPlat = os.platform();
|
||||||
let osArch = translateArchToDistUrl(os.arch());
|
let osArch = translateArchToDistUrl(arch);
|
||||||
let version;
|
let version;
|
||||||
version = yield queryDistForMatch(versionSpec);
|
version = yield queryDistForMatch(versionSpec, arch);
|
||||||
if (!version) {
|
if (!version) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -13132,10 +13252,23 @@ function getInfoFromDist(versionSpec) {
|
|||||||
return {
|
return {
|
||||||
downloadUrl: url,
|
downloadUrl: url,
|
||||||
resolvedVersion: version,
|
resolvedVersion: version,
|
||||||
|
arch: arch,
|
||||||
fileName: fileName
|
fileName: fileName
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function resolveVersionFromManifest(versionSpec, stable, auth, osArch = translateArchToDistUrl(os.arch())) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
try {
|
||||||
|
const info = yield getInfoFromManifest(versionSpec, stable, auth, osArch);
|
||||||
|
return info === null || info === void 0 ? void 0 : info.resolvedVersion;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
core.info('Unable to resolve version from manifest...');
|
||||||
|
core.debug(err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
||||||
function evaluateVersions(versions, versionSpec) {
|
function evaluateVersions(versions, versionSpec) {
|
||||||
let version = '';
|
let version = '';
|
||||||
@@ -13162,10 +13295,10 @@ function evaluateVersions(versions, versionSpec) {
|
|||||||
}
|
}
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
function queryDistForMatch(versionSpec) {
|
function queryDistForMatch(versionSpec, arch = os.arch()) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let osPlat = os.platform();
|
let osPlat = os.platform();
|
||||||
let osArch = translateArchToDistUrl(os.arch());
|
let osArch = translateArchToDistUrl(arch);
|
||||||
// node offers a json list of versions
|
// node offers a json list of versions
|
||||||
let dataFileName;
|
let dataFileName;
|
||||||
switch (osPlat) {
|
switch (osPlat) {
|
||||||
@@ -13218,10 +13351,10 @@ exports.getVersionsFromDist = getVersionsFromDist;
|
|||||||
// This method attempts to download and cache the resources from these alternative locations.
|
// This method attempts to download and cache the resources from these alternative locations.
|
||||||
// Note also that the files are normally zipped but in this case they are just an exe
|
// Note also that the files are normally zipped but in this case they are just an exe
|
||||||
// and lib file in a folder, not zipped.
|
// and lib file in a folder, not zipped.
|
||||||
function acquireNodeFromFallbackLocation(version) {
|
function acquireNodeFromFallbackLocation(version, arch = os.arch()) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let osPlat = os.platform();
|
let osPlat = os.platform();
|
||||||
let osArch = translateArchToDistUrl(os.arch());
|
let osArch = translateArchToDistUrl(arch);
|
||||||
// Create temporary folder to download in to
|
// Create temporary folder to download in to
|
||||||
const tempDownloadFolder = 'temp_' + Math.floor(Math.random() * 2000000000);
|
const tempDownloadFolder = 'temp_' + Math.floor(Math.random() * 2000000000);
|
||||||
const tempDirectory = process.env['RUNNER_TEMP'] || '';
|
const tempDirectory = process.env['RUNNER_TEMP'] || '';
|
||||||
@@ -13233,7 +13366,7 @@ function acquireNodeFromFallbackLocation(version) {
|
|||||||
try {
|
try {
|
||||||
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
|
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
|
||||||
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
|
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
|
||||||
console.log(`Downloading only node binary from ${exeUrl}`);
|
core.info(`Downloading only node binary from ${exeUrl}`);
|
||||||
const exePath = yield tc.downloadTool(exeUrl);
|
const exePath = yield tc.downloadTool(exeUrl);
|
||||||
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
|
yield io.cp(exePath, path.join(tempDir, 'node.exe'));
|
||||||
const libPath = yield tc.downloadTool(libUrl);
|
const libPath = yield tc.downloadTool(libUrl);
|
||||||
@@ -13252,7 +13385,7 @@ function acquireNodeFromFallbackLocation(version) {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let toolPath = yield tc.cacheDir(tempDir, 'node', version);
|
let toolPath = yield tc.cacheDir(tempDir, 'node', version, arch);
|
||||||
core.addPath(toolPath);
|
core.addPath(toolPath);
|
||||||
return toolPath;
|
return toolPath;
|
||||||
});
|
});
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -5,9 +5,9 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": {
|
"@actions/core": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
|
||||||
"integrity": "sha512-IbCx7oefq+Gi6FWbSs2Fnw8VkEI6Y4gvjrYprY3RV//ksq/KPMlClOerJ4jRosyal6zkUIc8R9fS/cpRMlGClg=="
|
"integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA=="
|
||||||
},
|
},
|
||||||
"@actions/exec": {
|
"@actions/exec": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.2.2",
|
"@actions/core": "^1.2.6",
|
||||||
"@actions/exec": "^1.0.3",
|
"@actions/exec": "^1.0.3",
|
||||||
"@actions/github": "^1.1.0",
|
"@actions/github": "^1.1.0",
|
||||||
"@actions/http-client": "^1.0.6",
|
"@actions/http-client": "^1.0.6",
|
||||||
|
|||||||
116
src/installer.ts
116
src/installer.ts
@@ -20,26 +20,45 @@ export interface INodeVersion {
|
|||||||
interface INodeVersionInfo {
|
interface INodeVersionInfo {
|
||||||
downloadUrl: string;
|
downloadUrl: string;
|
||||||
resolvedVersion: string;
|
resolvedVersion: string;
|
||||||
|
arch: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNode(
|
export async function getNode(
|
||||||
versionSpec: string,
|
versionSpec: string,
|
||||||
stable: boolean,
|
stable: boolean,
|
||||||
auth: string | undefined
|
checkLatest: boolean,
|
||||||
|
auth: string | undefined,
|
||||||
|
arch: string = os.arch()
|
||||||
) {
|
) {
|
||||||
let osPlat: string = os.platform();
|
let osPlat: string = os.platform();
|
||||||
let osArch: string = translateArchToDistUrl(os.arch());
|
let osArch: string = translateArchToDistUrl(arch);
|
||||||
|
|
||||||
|
if (checkLatest) {
|
||||||
|
core.info('Attempt to resolve the latest version from manifest...');
|
||||||
|
const resolvedVersion = await resolveVersionFromManifest(
|
||||||
|
versionSpec,
|
||||||
|
stable,
|
||||||
|
auth,
|
||||||
|
osArch
|
||||||
|
);
|
||||||
|
if (resolvedVersion) {
|
||||||
|
versionSpec = resolvedVersion;
|
||||||
|
core.info(`Resolved as '${versionSpec}'`);
|
||||||
|
} else {
|
||||||
|
core.info(`Failed to resolve version ${versionSpec} from manifest`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check cache
|
// check cache
|
||||||
let toolPath: string;
|
let toolPath: string;
|
||||||
toolPath = tc.find('node', versionSpec);
|
toolPath = tc.find('node', versionSpec, osArch);
|
||||||
|
|
||||||
// If not found in cache, download
|
// If not found in cache, download
|
||||||
if (toolPath) {
|
if (toolPath) {
|
||||||
console.log(`Found in cache @ ${toolPath}`);
|
core.info(`Found in cache @ ${toolPath}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`Attempting to download ${versionSpec}...`);
|
core.info(`Attempting to download ${versionSpec}...`);
|
||||||
let downloadPath = '';
|
let downloadPath = '';
|
||||||
let info: INodeVersionInfo | null = null;
|
let info: INodeVersionInfo | null = null;
|
||||||
|
|
||||||
@@ -47,14 +66,14 @@ export async function getNode(
|
|||||||
// Try download from internal distribution (popular versions only)
|
// Try download from internal distribution (popular versions only)
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
info = await getInfoFromManifest(versionSpec, stable, auth);
|
info = await getInfoFromManifest(versionSpec, stable, auth, osArch);
|
||||||
if (info) {
|
if (info) {
|
||||||
console.log(
|
core.info(
|
||||||
`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`
|
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
|
||||||
);
|
);
|
||||||
downloadPath = await tc.downloadTool(info.downloadUrl, undefined, auth);
|
downloadPath = await tc.downloadTool(info.downloadUrl, undefined, auth);
|
||||||
} else {
|
} else {
|
||||||
console.log(
|
core.info(
|
||||||
'Not found in manifest. Falling back to download directly from Node'
|
'Not found in manifest. Falling back to download directly from Node'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -64,33 +83,38 @@ export async function getNode(
|
|||||||
err instanceof tc.HTTPError &&
|
err instanceof tc.HTTPError &&
|
||||||
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
|
(err.httpStatusCode === 403 || err.httpStatusCode === 429)
|
||||||
) {
|
) {
|
||||||
console.log(
|
core.info(
|
||||||
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
|
`Received HTTP status code ${err.httpStatusCode}. This usually indicates the rate limit has been exceeded`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log(err.message);
|
core.info(err.message);
|
||||||
}
|
}
|
||||||
core.debug(err.stack);
|
core.debug(err.stack);
|
||||||
console.log('Falling back to download directly from Node');
|
core.info('Falling back to download directly from Node');
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Download from nodejs.org
|
// Download from nodejs.org
|
||||||
//
|
//
|
||||||
if (!downloadPath) {
|
if (!downloadPath) {
|
||||||
info = await getInfoFromDist(versionSpec);
|
info = await getInfoFromDist(versionSpec, arch);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
|
`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`);
|
core.info(
|
||||||
|
`Acquiring ${info.resolvedVersion} - ${info.arch} from ${info.downloadUrl}`
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
downloadPath = await tc.downloadTool(info.downloadUrl);
|
downloadPath = await tc.downloadTool(info.downloadUrl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
if (err instanceof tc.HTTPError && err.httpStatusCode == 404) {
|
||||||
return await acquireNodeFromFallbackLocation(info.resolvedVersion);
|
return await acquireNodeFromFallbackLocation(
|
||||||
|
info.resolvedVersion,
|
||||||
|
info.arch
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
@@ -100,7 +124,7 @@ export async function getNode(
|
|||||||
//
|
//
|
||||||
// Extract
|
// Extract
|
||||||
//
|
//
|
||||||
console.log('Extracting ...');
|
core.info('Extracting ...');
|
||||||
let extPath: string;
|
let extPath: string;
|
||||||
info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
|
info = info || ({} as INodeVersionInfo); // satisfy compiler, never null when reaches here
|
||||||
if (osPlat == 'win32') {
|
if (osPlat == 'win32') {
|
||||||
@@ -122,9 +146,14 @@ export async function getNode(
|
|||||||
//
|
//
|
||||||
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
|
// Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
|
||||||
//
|
//
|
||||||
console.log('Adding to the cache ...');
|
core.info('Adding to the cache ...');
|
||||||
toolPath = await tc.cacheDir(extPath, 'node', info.resolvedVersion);
|
toolPath = await tc.cacheDir(
|
||||||
console.log('Done');
|
extPath,
|
||||||
|
'node',
|
||||||
|
info.resolvedVersion,
|
||||||
|
info.arch
|
||||||
|
);
|
||||||
|
core.info('Done');
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -144,20 +173,22 @@ export async function getNode(
|
|||||||
async function getInfoFromManifest(
|
async function getInfoFromManifest(
|
||||||
versionSpec: string,
|
versionSpec: string,
|
||||||
stable: boolean,
|
stable: boolean,
|
||||||
auth: string | undefined
|
auth: string | undefined,
|
||||||
|
osArch: string = translateArchToDistUrl(os.arch())
|
||||||
): Promise<INodeVersionInfo | null> {
|
): Promise<INodeVersionInfo | null> {
|
||||||
let info: INodeVersionInfo | null = null;
|
let info: INodeVersionInfo | null = null;
|
||||||
const releases = await tc.getManifestFromRepo(
|
const releases = await tc.getManifestFromRepo(
|
||||||
'actions',
|
'actions',
|
||||||
'node-versions',
|
'node-versions',
|
||||||
auth
|
auth,
|
||||||
|
'main'
|
||||||
);
|
);
|
||||||
console.log(`matching ${versionSpec}...`);
|
const rel = await tc.findFromManifest(versionSpec, stable, releases, osArch);
|
||||||
const rel = await tc.findFromManifest(versionSpec, stable, releases);
|
|
||||||
|
|
||||||
if (rel && rel.files.length > 0) {
|
if (rel && rel.files.length > 0) {
|
||||||
info = <INodeVersionInfo>{};
|
info = <INodeVersionInfo>{};
|
||||||
info.resolvedVersion = rel.version;
|
info.resolvedVersion = rel.version;
|
||||||
|
info.arch = rel.files[0].arch;
|
||||||
info.downloadUrl = rel.files[0].download_url;
|
info.downloadUrl = rel.files[0].download_url;
|
||||||
info.fileName = rel.files[0].filename;
|
info.fileName = rel.files[0].filename;
|
||||||
}
|
}
|
||||||
@@ -166,14 +197,15 @@ async function getInfoFromManifest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getInfoFromDist(
|
async function getInfoFromDist(
|
||||||
versionSpec: string
|
versionSpec: string,
|
||||||
|
arch: string = os.arch()
|
||||||
): Promise<INodeVersionInfo | null> {
|
): Promise<INodeVersionInfo | null> {
|
||||||
let osPlat: string = os.platform();
|
let osPlat: string = os.platform();
|
||||||
let osArch: string = translateArchToDistUrl(os.arch());
|
let osArch: string = translateArchToDistUrl(arch);
|
||||||
|
|
||||||
let version: string;
|
let version: string;
|
||||||
|
|
||||||
version = await queryDistForMatch(versionSpec);
|
version = await queryDistForMatch(versionSpec, arch);
|
||||||
if (!version) {
|
if (!version) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -193,10 +225,26 @@ async function getInfoFromDist(
|
|||||||
return <INodeVersionInfo>{
|
return <INodeVersionInfo>{
|
||||||
downloadUrl: url,
|
downloadUrl: url,
|
||||||
resolvedVersion: version,
|
resolvedVersion: version,
|
||||||
|
arch: arch,
|
||||||
fileName: fileName
|
fileName: fileName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resolveVersionFromManifest(
|
||||||
|
versionSpec: string,
|
||||||
|
stable: boolean,
|
||||||
|
auth: string | undefined,
|
||||||
|
osArch: string = translateArchToDistUrl(os.arch())
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
try {
|
||||||
|
const info = await getInfoFromManifest(versionSpec, stable, auth, osArch);
|
||||||
|
return info?.resolvedVersion;
|
||||||
|
} catch (err) {
|
||||||
|
core.info('Unable to resolve version from manifest...');
|
||||||
|
core.debug(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
// TODO - should we just export this from @actions/tool-cache? Lifted directly from there
|
||||||
function evaluateVersions(versions: string[], versionSpec: string): string {
|
function evaluateVersions(versions: string[], versionSpec: string): string {
|
||||||
let version = '';
|
let version = '';
|
||||||
@@ -225,9 +273,12 @@ function evaluateVersions(versions: string[], versionSpec: string): string {
|
|||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function queryDistForMatch(versionSpec: string): Promise<string> {
|
async function queryDistForMatch(
|
||||||
|
versionSpec: string,
|
||||||
|
arch: string = os.arch()
|
||||||
|
): Promise<string> {
|
||||||
let osPlat: string = os.platform();
|
let osPlat: string = os.platform();
|
||||||
let osArch: string = translateArchToDistUrl(os.arch());
|
let osArch: string = translateArchToDistUrl(arch);
|
||||||
|
|
||||||
// node offers a json list of versions
|
// node offers a json list of versions
|
||||||
let dataFileName: string;
|
let dataFileName: string;
|
||||||
@@ -283,10 +334,11 @@ export async function getVersionsFromDist(): Promise<INodeVersion[]> {
|
|||||||
// Note also that the files are normally zipped but in this case they are just an exe
|
// Note also that the files are normally zipped but in this case they are just an exe
|
||||||
// and lib file in a folder, not zipped.
|
// and lib file in a folder, not zipped.
|
||||||
async function acquireNodeFromFallbackLocation(
|
async function acquireNodeFromFallbackLocation(
|
||||||
version: string
|
version: string,
|
||||||
|
arch: string = os.arch()
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
let osPlat: string = os.platform();
|
let osPlat: string = os.platform();
|
||||||
let osArch: string = translateArchToDistUrl(os.arch());
|
let osArch: string = translateArchToDistUrl(arch);
|
||||||
|
|
||||||
// Create temporary folder to download in to
|
// Create temporary folder to download in to
|
||||||
const tempDownloadFolder: string =
|
const tempDownloadFolder: string =
|
||||||
@@ -301,7 +353,7 @@ async function acquireNodeFromFallbackLocation(
|
|||||||
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
|
exeUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.exe`;
|
||||||
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
|
libUrl = `https://nodejs.org/dist/v${version}/win-${osArch}/node.lib`;
|
||||||
|
|
||||||
console.log(`Downloading only node binary from ${exeUrl}`);
|
core.info(`Downloading only node binary from ${exeUrl}`);
|
||||||
|
|
||||||
const exePath = await tc.downloadTool(exeUrl);
|
const exePath = await tc.downloadTool(exeUrl);
|
||||||
await io.cp(exePath, path.join(tempDir, 'node.exe'));
|
await io.cp(exePath, path.join(tempDir, 'node.exe'));
|
||||||
@@ -320,7 +372,7 @@ async function acquireNodeFromFallbackLocation(
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let toolPath = await tc.cacheDir(tempDir, 'node', version);
|
let toolPath = await tc.cacheDir(tempDir, 'node', version, arch);
|
||||||
core.addPath(toolPath);
|
core.addPath(toolPath);
|
||||||
return toolPath;
|
return toolPath;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/main.ts
20
src/main.ts
@@ -3,6 +3,7 @@ import * as installer from './installer';
|
|||||||
import * as auth from './authutil';
|
import * as auth from './authutil';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import {URL} from 'url';
|
import {URL} from 'url';
|
||||||
|
import os = require('os');
|
||||||
|
|
||||||
export async function run() {
|
export async function run() {
|
||||||
try {
|
try {
|
||||||
@@ -15,12 +16,27 @@ export async function run() {
|
|||||||
version = core.getInput('version');
|
version = core.getInput('version');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`version: ${version}`);
|
let arch = core.getInput('architecture');
|
||||||
|
|
||||||
|
// if architecture supplied but node-version is not
|
||||||
|
// if we don't throw a warning, the already installed x64 node will be used which is not probably what user meant.
|
||||||
|
if (arch && !version) {
|
||||||
|
core.warning(
|
||||||
|
'`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed. To fix this, provide `architecture` in combination with `node-version`'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arch) {
|
||||||
|
arch = os.arch();
|
||||||
|
}
|
||||||
|
|
||||||
if (version) {
|
if (version) {
|
||||||
let token = core.getInput('token');
|
let token = core.getInput('token');
|
||||||
let auth = !token || isGhes() ? undefined : `token ${token}`;
|
let auth = !token || isGhes() ? undefined : `token ${token}`;
|
||||||
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
|
||||||
await installer.getNode(version, stable, auth);
|
const checkLatest =
|
||||||
|
(core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
|
||||||
|
await installer.getNode(version, stable, checkLatest, auth, arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
const registryUrl: string = core.getInput('registry-url');
|
const registryUrl: string = core.getInput('registry-url');
|
||||||
|
|||||||
Reference in New Issue
Block a user