mirror of
https://github.com/actions/setup-node.git
synced 2025-12-17 01:03:45 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
395ad32622 | ||
|
|
a4d2e2bbca | ||
|
|
b9b25d45f7 | ||
|
|
633bb92bc0 | ||
|
|
dda4788290 | ||
|
|
2028fbc5c2 | ||
|
|
13427813f7 | ||
|
|
89d709d423 | ||
|
|
cd2651c462 | ||
|
|
a0853c2454 | ||
|
|
b7234cc9fe | ||
|
|
d7a11313b5 | ||
|
|
5e2628c959 | ||
|
|
65beceff8e | ||
|
|
7e24a656e1 | ||
|
|
08f58d1471 |
2
.github/workflows/basic-validation.yml
vendored
2
.github/workflows/basic-validation.yml
vendored
@ -16,4 +16,4 @@ jobs:
|
||||
name: Basic validation
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: '24.x'
|
||||
|
||||
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@ -16,4 +16,4 @@ jobs:
|
||||
name: Check dist/
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
with:
|
||||
node-version: '20.x'
|
||||
node-version: '24.x'
|
||||
|
||||
101
.github/workflows/e2e-cache.yml
vendored
101
.github/workflows/e2e-cache.yml
vendored
@ -18,10 +18,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Clean global cache
|
||||
run: npm cache clean --force
|
||||
- name: Setup Node
|
||||
@ -41,10 +41,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
@ -74,14 +74,14 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Yarn version
|
||||
run: yarn --version
|
||||
- name: Generate yarn file
|
||||
run: yarn install
|
||||
run: yarn install --ignore-engines
|
||||
- name: Remove dependencies
|
||||
shell: pwsh
|
||||
run: Remove-Item node_modules -Force -Recurse
|
||||
@ -106,10 +106,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Update yarn
|
||||
run: yarn set version 3.6.4
|
||||
- name: Yarn version
|
||||
@ -139,11 +139,11 @@ jobs:
|
||||
name: Test yarn subprojects
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18, 20, 22]
|
||||
node-version: [20, 22, 24]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: prepare sub-projects
|
||||
run: __tests__/prepare-yarn-subprojects.sh yarn1
|
||||
@ -166,11 +166,11 @@ jobs:
|
||||
name: Test yarn subprojects all locally managed
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18, 20, 22]
|
||||
node-version: [20, 22, 24]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: prepare sub-projects
|
||||
run: __tests__/prepare-yarn-subprojects.sh keepcache keepcache
|
||||
@ -193,11 +193,11 @@ jobs:
|
||||
name: Test yarn subprojects some locally managed
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18, 20, 22]
|
||||
node-version: [20, 22, 24]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: prepare sub-projects
|
||||
run: __tests__/prepare-yarn-subprojects.sh global
|
||||
@ -220,11 +220,11 @@ jobs:
|
||||
name: Test yarn subprojects managed by git
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18, 20, 22]
|
||||
node-version: [20, 22, 24]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: prepare sub-projects
|
||||
run: /bin/bash __tests__/prepare-yarn-subprojects.sh keepcache
|
||||
@ -243,3 +243,62 @@ jobs:
|
||||
cache-dependency-path: |
|
||||
sub2/*.lock
|
||||
sub3/*.lock
|
||||
|
||||
node-npm-packageManager-auto-cache:
|
||||
name: Test auto cache with top-level packageManager
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Create package.json with packageManager field
|
||||
run: |
|
||||
echo '{ "name": "test-project", "version": "1.0.0", "packageManager": "npm@8.0.0" }' > package.json
|
||||
- name: Clean global cache
|
||||
run: npm cache clean --force
|
||||
- name: Setup Node with caching enabled
|
||||
uses: ./
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Verify node and npm
|
||||
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||
shell: bash
|
||||
|
||||
node-npm-devEngines-auto-cache:
|
||||
name: Test auto cache with devEngines.packageManager
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Create package.json with devEngines field
|
||||
run: |
|
||||
echo '{
|
||||
"name": "test-project",
|
||||
"version": "1.0.0",
|
||||
"devEngines": {
|
||||
"packageManager": {
|
||||
"name": "npm",
|
||||
"onFail": "error"
|
||||
}
|
||||
}
|
||||
}' > package.json
|
||||
- name: Clean global cache
|
||||
run: npm cache clean --force
|
||||
- name: Setup Node with caching enabled
|
||||
uses: ./
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Verify node and npm
|
||||
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||
shell: bash
|
||||
|
||||
16
.github/workflows/proxy.yml
vendored
16
.github/workflows/proxy.yml
vendored
@ -25,15 +25,15 @@ jobs:
|
||||
env:
|
||||
https_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Clear tool cache
|
||||
run: rm -rf $RUNNER_TOOL_CACHE/*
|
||||
- name: Setup node 14
|
||||
- name: Setup node 24
|
||||
uses: ./
|
||||
with:
|
||||
node-version: 14.x
|
||||
node-version: 24.x
|
||||
- name: Verify node and npm
|
||||
run: __tests__/verify-node.sh 14
|
||||
run: __tests__/verify-node.sh 24
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
@ -41,12 +41,12 @@ 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@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Clear tool cache
|
||||
run: rm -rf $RUNNER_TOOL_CACHE/*
|
||||
- name: Setup node 11
|
||||
- name: Setup node 24
|
||||
uses: ./
|
||||
with:
|
||||
node-version: 11
|
||||
node-version: 24
|
||||
- name: Verify node and npm
|
||||
run: __tests__/verify-node.sh 11
|
||||
run: __tests__/verify-node.sh 24
|
||||
|
||||
@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checking out
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Publish
|
||||
id: publish
|
||||
uses: actions/publish-immutable-action@v0.0.4
|
||||
|
||||
@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
uses: actions/publish-action@v0.3.0
|
||||
uses: actions/publish-action@v0.4.0
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
|
||||
70
.github/workflows/versions.yml
vendored
70
.github/workflows/versions.yml
vendored
@ -17,10 +17,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -34,10 +34,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest-large]
|
||||
node-version: [lts/dubnium, lts/erbium, lts/fermium, lts/*, lts/-1]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -56,7 +56,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version:
|
||||
[
|
||||
'20-v8-canary',
|
||||
@ -64,7 +64,7 @@ jobs:
|
||||
'20.0.0-v8-canary20221101e50e45c9f8'
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -81,10 +81,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [20-nightly, 21-nightly, 18.0.0-nightly]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20-nightly, 25-nightly, 24.0.0-nightly]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -101,10 +101,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [20.0.0-rc.1, 18.0.0-rc.2, 19.0.0-rc.0]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20.0.0-rc.1, 22.14.0-rc.1, 24.0.0-rc.4]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -121,10 +121,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18.20.0, 20.10.0, 22.0.0]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20.10.0, 22.0.0, 24.9.0]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
@ -138,10 +138,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
node-version: [18, 20, 22]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [20, 22, 24]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node and check latest
|
||||
uses: ./
|
||||
with:
|
||||
@ -156,57 +156,57 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version-file:
|
||||
[.nvmrc, .tool-versions, .tool-versions-node, package.json]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup node from node version file
|
||||
uses: ./
|
||||
with:
|
||||
node-version-file: '__tests__/data/${{ matrix.node-version-file }}'
|
||||
- name: Verify node
|
||||
run: __tests__/verify-node.sh 20
|
||||
run: __tests__/verify-node.sh 24
|
||||
|
||||
version-file-volta:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup node from node version file
|
||||
uses: ./
|
||||
with:
|
||||
node-version-file: '__tests__/data/package-volta.json'
|
||||
- name: Verify node
|
||||
run: __tests__/verify-node.sh 20
|
||||
run: __tests__/verify-node.sh 24
|
||||
|
||||
version-file-volta-extends:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup node from node version file
|
||||
uses: ./
|
||||
with:
|
||||
node-version-file: '__tests__/data/package-volta-extends.json'
|
||||
- name: Verify node
|
||||
run: __tests__/verify-node.sh 20
|
||||
run: __tests__/verify-node.sh 24
|
||||
|
||||
node-dist:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [17, 19]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node from dist
|
||||
uses: ./
|
||||
with:
|
||||
@ -220,9 +220,9 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest-large]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
# test old versions which didn't have npm and layout different
|
||||
- name: Setup node 0.12.18 from dist
|
||||
uses: ./
|
||||
@ -235,7 +235,7 @@ jobs:
|
||||
arch:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup node 20 x86 from dist
|
||||
uses: ./
|
||||
with:
|
||||
@ -250,7 +250,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||
os: [ubuntu-latest, windows-latest, macos-latest, macos-latest-large]
|
||||
node-version: [current, latest, node]
|
||||
steps:
|
||||
- name: Get node version
|
||||
@ -259,7 +259,7 @@ jobs:
|
||||
echo "LATEST_NODE_VERSION=$latestNodeVersion" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
shell: bash
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Setup Node
|
||||
uses: ./
|
||||
with:
|
||||
|
||||
BIN
.licenses/npm/@actions/cache.dep.yml
generated
BIN
.licenses/npm/@actions/cache.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/github.dep.yml
generated
BIN
.licenses/npm/@actions/github.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@octokit/auth-token.dep.yml
generated
BIN
.licenses/npm/@octokit/auth-token.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@octokit/core.dep.yml
generated
BIN
.licenses/npm/@octokit/core.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/@octokit/openapi-types-24.2.0.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/openapi-types-24.2.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/plugin-paginate-rest.dep.yml
generated
BIN
.licenses/npm/@octokit/plugin-paginate-rest.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@octokit/request.dep.yml
generated
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/@octokit/types-13.10.0.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/types-13.10.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/plugin-framework.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/plugin-framework.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/plugin.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/plugin.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/protoc.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/protoc.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/runtime-rpc.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/runtime-rpc.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/runtime.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/runtime.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@types/node.dep.yml
generated
BIN
.licenses/npm/@types/node.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/brace-expansion.dep.yml
generated
BIN
.licenses/npm/brace-expansion.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/call-bind-apply-helpers.dep.yml
generated
Normal file
BIN
.licenses/npm/call-bind-apply-helpers.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/dunder-proto.dep.yml
generated
Normal file
BIN
.licenses/npm/dunder-proto.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/es-define-property.dep.yml
generated
Normal file
BIN
.licenses/npm/es-define-property.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/es-errors.dep.yml
generated
Normal file
BIN
.licenses/npm/es-errors.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/es-object-atoms.dep.yml
generated
Normal file
BIN
.licenses/npm/es-object-atoms.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/es-set-tostringtag.dep.yml
generated
Normal file
BIN
.licenses/npm/es-set-tostringtag.dep.yml
generated
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/function-bind.dep.yml
generated
Normal file
BIN
.licenses/npm/function-bind.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/get-intrinsic.dep.yml
generated
Normal file
BIN
.licenses/npm/get-intrinsic.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/get-proto.dep.yml
generated
Normal file
BIN
.licenses/npm/get-proto.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/gopd.dep.yml
generated
Normal file
BIN
.licenses/npm/gopd.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/has-symbols.dep.yml
generated
Normal file
BIN
.licenses/npm/has-symbols.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/has-tostringtag.dep.yml
generated
Normal file
BIN
.licenses/npm/has-tostringtag.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/hasown.dep.yml
generated
Normal file
BIN
.licenses/npm/hasown.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/math-intrinsics.dep.yml
generated
Normal file
BIN
.licenses/npm/math-intrinsics.dep.yml
generated
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/typescript.dep.yml
generated
BIN
.licenses/npm/typescript.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/undici-types.dep.yml
generated
BIN
.licenses/npm/undici-types.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/undici.dep.yml
generated
BIN
.licenses/npm/undici.dep.yml
generated
Binary file not shown.
Binary file not shown.
77
README.md
77
README.md
@ -12,13 +12,29 @@ This action provides the following functionality for GitHub Actions users:
|
||||
- Registering problem matchers for error output
|
||||
- Configuring authentication for GPR or npm
|
||||
|
||||
## Breaking changes in V6
|
||||
|
||||
- Caching is now automatically enabled for npm projects when either the `devEngines.packageManager` field or the top-level `packageManager` field in `package.json` is set to `npm`. For other package managers, such as Yarn and pnpm, caching is disabled by default and must be configured manually using the `cache` input.
|
||||
|
||||
- The `always-auth` input has been removed, as it is deprecated and will no longer be supported in future npm releases. To ensure your workflows continue to run without warnings or errors, please remove any references to `always-auth` from your configuration.
|
||||
|
||||
## Breaking changes in V5
|
||||
|
||||
- Enabled caching by default with package manager detection if no cache input is provided.
|
||||
> For workflows with elevated privileges or access to sensitive information, we recommend disabling automatic caching by setting `package-manager-cache: false` when caching is not needed for secure operation.
|
||||
|
||||
- Upgraded action from node20 to node24.
|
||||
> Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. [See Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
|
||||
|
||||
For more details, see the full release notes on the [releases page](https://github.com/actions/setup-node/releases/v5.0.0)
|
||||
|
||||
## Usage
|
||||
|
||||
See [action.yml](action.yml)
|
||||
|
||||
<!-- start usage -->
|
||||
```yaml
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
# Version Spec of the version to use in SemVer notation.
|
||||
# It also admits such aliases as lts/*, latest, nightly and canary builds
|
||||
@ -57,6 +73,11 @@ See [action.yml](action.yml)
|
||||
# Default: ''
|
||||
cache: ''
|
||||
|
||||
# Controls automatic caching for npm. By default, caching for npm is enabled if either the devEngines.packageManager field or the top-level packageManager field in package.json specifies npm and no explicit cache input is provided.
|
||||
# To disable automatic caching for npm, set package-manager-cache to false.
|
||||
# default: true
|
||||
package-manager-cache: true
|
||||
|
||||
# Used to specify the path to a dependency file: package-lock.json, yarn.lock, etc.
|
||||
# It will generate hash from the target file for primary key. It works only If cache is specified.
|
||||
# Supports wildcards or a list of file names for caching multiple dependencies.
|
||||
@ -73,10 +94,6 @@ See [action.yml](action.yml)
|
||||
# Default: ''
|
||||
scope: ''
|
||||
|
||||
# Set always-auth option in npmrc file.
|
||||
# Default: ''
|
||||
always-auth: ''
|
||||
|
||||
# Optional mirror to download binaries from.
|
||||
# Artifacts need to match the official Node.js
|
||||
# Example:
|
||||
@ -98,10 +115,10 @@ See [action.yml](action.yml)
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 24
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -118,9 +135,9 @@ The `node-version` input supports the Semantic Versioning Specification, for mor
|
||||
|
||||
Examples:
|
||||
|
||||
- Major versions: `18`, `20`
|
||||
- More specific versions: `10.15`, `16.15.1` , `18.4.0`
|
||||
- NVM LTS syntax: `lts/erbium`, `lts/fermium`, `lts/*`, `lts/-n`
|
||||
- Major versions: `22`, `24`
|
||||
- More specific versions: `20.19`, `22.17.1` , `24.8.0`
|
||||
- NVM LTS syntax: `lts/iron`, `lts/jod`, `lts/*`, `lts/-n`
|
||||
- Latest release: `*` or `latest`/`current`/`node`
|
||||
|
||||
**Note:** Like the other values, `*` will get the latest [locally-cached Node.js version](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-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.
|
||||
@ -135,7 +152,7 @@ It's **always** recommended to commit the lockfile of your package manager for s
|
||||
|
||||
## 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 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.
|
||||
|
||||
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.
|
||||
|
||||
@ -147,10 +164,10 @@ See the examples of using cache for `yarn`/`pnpm` and `cache-dependency-path` in
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
@ -160,16 +177,30 @@ steps:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
cache-dependency-path: subdir/package-lock.json
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
Caching for npm dependencies is automatically enabled when your `package.json` contains either `devEngines.packageManager` field or top-level `packageManager` field set to `npm`, and no explicit cache input is provided.
|
||||
|
||||
This behavior is controlled by the `package-manager-cache` input, which defaults to `true`. To turn off automatic caching, set `package-manager-cache` to `false`.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
package-manager-cache: false
|
||||
- run: npm ci
|
||||
```
|
||||
> If your `package.json` file does not include a `packageManager` field set to `npm`, caching will be disabled unless you explicitly enable it. For workflows with elevated privileges or access to sensitive information, we recommend disabling automatic caching for npm by setting `package-manager-cache: false` when caching is not required for secure operation.
|
||||
|
||||
## Matrix Testing
|
||||
|
||||
```yaml
|
||||
@ -178,12 +209,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ 14, 16, 18 ]
|
||||
node: [ 20, 22, 24 ]
|
||||
name: Node ${{ matrix.node }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- run: npm ci
|
||||
@ -197,10 +228,10 @@ jobs:
|
||||
To get a higher rate limit, you can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token` input for the action:
|
||||
|
||||
```yaml
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
token: ${{ secrets.GH_DOTCOM_TOKEN }}
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
```
|
||||
|
||||
If the runner is not able to access github.com, any Nodejs versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
|
||||
|
||||
@ -76,115 +76,102 @@ describe('authutil tests', () => {
|
||||
}
|
||||
|
||||
it('Sets up npmrc for npmjs', async () => {
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'false');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['registry']).toBe('https://registry.npmjs.org/');
|
||||
expect(rc['always-auth']).toBe('false');
|
||||
});
|
||||
|
||||
it('Appends trailing slash to registry', async () => {
|
||||
await auth.configAuthentication('https://registry.npmjs.org', 'false');
|
||||
await auth.configAuthentication('https://registry.npmjs.org');
|
||||
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['registry']).toBe('https://registry.npmjs.org/');
|
||||
expect(rc['always-auth']).toBe('false');
|
||||
});
|
||||
|
||||
it('Configures scoped npm registries', async () => {
|
||||
process.env['INPUT_SCOPE'] = 'myScope';
|
||||
await auth.configAuthentication('https://registry.npmjs.org', 'false');
|
||||
await auth.configAuthentication('https://registry.npmjs.org');
|
||||
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['@myscope:registry']).toBe('https://registry.npmjs.org/');
|
||||
expect(rc['always-auth']).toBe('false');
|
||||
});
|
||||
|
||||
it('Automatically configures GPR scope', async () => {
|
||||
await auth.configAuthentication('npm.pkg.github.com', 'false');
|
||||
await auth.configAuthentication('npm.pkg.github.com');
|
||||
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['@ownername:registry']).toBe('npm.pkg.github.com/');
|
||||
expect(rc['always-auth']).toBe('false');
|
||||
});
|
||||
|
||||
it('Sets up npmrc for always-auth true', async () => {
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['registry']).toBe('https://registry.npmjs.org/');
|
||||
expect(rc['always-auth']).toBe('true');
|
||||
});
|
||||
|
||||
it('is already set the NODE_AUTH_TOKEN export it', async () => {
|
||||
process.env.NODE_AUTH_TOKEN = 'foobar';
|
||||
await auth.configAuthentication('npm.pkg.github.com', 'false');
|
||||
await auth.configAuthentication('npm.pkg.github.com');
|
||||
expect(fs.statSync(rcFile)).toBeDefined();
|
||||
const rc = readRcFile(rcFile);
|
||||
expect(rc['@ownername:registry']).toBe('npm.pkg.github.com/');
|
||||
expect(rc['always-auth']).toBe('false');
|
||||
expect(process.env.NODE_AUTH_TOKEN).toEqual('foobar');
|
||||
});
|
||||
|
||||
it('configAuthentication should overwrite non-scoped with non-scoped', async () => {
|
||||
fs.writeFileSync(rcFile, 'registry=NNN');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should overwrite only non-scoped', async () => {
|
||||
fs.writeFileSync(rcFile, `registry=NNN${os.EOL}@myscope:registry=MMM`);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`@myscope:registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`@myscope:registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should add non-scoped to scoped', async () => {
|
||||
fs.writeFileSync(rcFile, '@myscope:registry=NNN');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`@myscope:registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`@myscope:registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should overwrite scoped with scoped', async () => {
|
||||
process.env['INPUT_SCOPE'] = 'myscope';
|
||||
fs.writeFileSync(rcFile, `@myscope:registry=NNN`);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should overwrite only scoped', async () => {
|
||||
process.env['INPUT_SCOPE'] = 'myscope';
|
||||
fs.writeFileSync(rcFile, `registry=NNN${os.EOL}@myscope:registry=MMM`);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should add scoped to non-scoped', async () => {
|
||||
process.env['INPUT_SCOPE'] = 'myscope';
|
||||
fs.writeFileSync(rcFile, `registry=MMM`);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
@ -194,20 +181,20 @@ describe('authutil tests', () => {
|
||||
rcFile,
|
||||
`@otherscope:registry=NNN${os.EOL}@myscope:registry=MMM`
|
||||
);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`@otherscope:registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`@otherscope:registry=NNN${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
|
||||
it('configAuthentication should add scoped to another scoped', async () => {
|
||||
process.env['INPUT_SCOPE'] = 'myscope';
|
||||
fs.writeFileSync(rcFile, `@otherscope:registry=MMM`);
|
||||
await auth.configAuthentication('https://registry.npmjs.org/', 'true');
|
||||
await auth.configAuthentication('https://registry.npmjs.org/');
|
||||
const contents = fs.readFileSync(rcFile, {encoding: 'utf8'});
|
||||
expect(contents).toBe(
|
||||
`@otherscope:registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/${os.EOL}always-auth=true`
|
||||
`@otherscope:registry=MMM${os.EOL}//registry.npmjs.org/:_authToken=\${NODE_AUTH_TOKEN}${os.EOL}@myscope:registry=https://registry.npmjs.org/`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -114,10 +114,10 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CachePrimaryKey || key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -138,10 +138,10 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CachePrimaryKey || key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -162,10 +162,10 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CachePrimaryKey || key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`);
|
||||
|
||||
@ -184,10 +184,10 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CachePrimaryKey || key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -207,12 +207,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -237,12 +237,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? yarnFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -267,12 +267,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -297,12 +297,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? pnpmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? pnpmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? npmFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
|
||||
await run();
|
||||
@ -327,12 +327,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
saveCacheSpy.mockImplementation(() => {
|
||||
return -1;
|
||||
@ -360,12 +360,12 @@ describe('run', () => {
|
||||
key === State.CachePackageManager
|
||||
? inputs['cache']
|
||||
: key === State.CacheMatchedKey
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
? npmFileHash
|
||||
: key === State.CachePrimaryKey
|
||||
? yarnFileHash
|
||||
: key === State.CachePaths
|
||||
? '["/foo/bar"]'
|
||||
: 'not expected'
|
||||
);
|
||||
saveCacheSpy.mockImplementation(() => {
|
||||
throw new cache.ValidationError('Validation failed');
|
||||
|
||||
@ -227,7 +227,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '11.15.0';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -283,7 +282,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '19.0.0-v8-canary';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
@ -324,7 +322,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
const expectedUrl = `https://nodejs.org/download/v8-canary/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
|
||||
@ -569,7 +566,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = 'v20-v8-canary';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
os.platform = 'linux';
|
||||
|
||||
@ -1 +1 @@
|
||||
v20
|
||||
v24
|
||||
|
||||
@ -1 +1 @@
|
||||
nodejs 20.0.0
|
||||
nodejs 24.0.0
|
||||
|
||||
@ -1 +1 @@
|
||||
node 20.0.0
|
||||
node 24.0.0
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
"node": "^14.0.0"
|
||||
},
|
||||
"volta": {
|
||||
"node": "20.0.0"
|
||||
"node": "24.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"engines": {
|
||||
"node": "^20.0.0"
|
||||
"node": "^24.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ describe('main tests', () => {
|
||||
|
||||
let infoSpy: jest.SpyInstance;
|
||||
let warningSpy: jest.SpyInstance;
|
||||
let saveStateSpy: jest.SpyInstance;
|
||||
let inSpy: jest.SpyInstance;
|
||||
let setOutputSpy: jest.SpyInstance;
|
||||
let startGroupSpy: jest.SpyInstance;
|
||||
@ -53,6 +54,8 @@ describe('main tests', () => {
|
||||
setOutputSpy.mockImplementation(() => {});
|
||||
warningSpy = jest.spyOn(core, 'warning');
|
||||
warningSpy.mockImplementation(() => {});
|
||||
saveStateSpy = jest.spyOn(core, 'saveState');
|
||||
saveStateSpy.mockImplementation(() => {});
|
||||
startGroupSpy = jest.spyOn(core, 'startGroup');
|
||||
startGroupSpy.mockImplementation(() => {});
|
||||
endGroupSpy = jest.spyOn(core, 'endGroup');
|
||||
@ -280,4 +283,149 @@ describe('main tests', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('cache feature tests', () => {
|
||||
it('Should enable caching when packageManager is npm and cache input is not provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
packageManager: 'npm@10.8.2'
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'npm');
|
||||
});
|
||||
|
||||
it('Should enable caching when devEngines.packageManager.name is "npm" and cache input is not provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
devEngines: {
|
||||
packageManager: {name: 'npm'}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'npm');
|
||||
});
|
||||
|
||||
it('Should enable caching when devEngines.packageManager is array and one entry has name "npm"', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
devEngines: {
|
||||
packageManager: [{name: 'pnpm'}, {name: 'npm'}]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'npm');
|
||||
});
|
||||
|
||||
it('Should not enable caching if packageManager is "pnpm@8.0.0" and cache input is not provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
packageManager: 'pnpm@8.0.0'
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should not enable caching if devEngines.packageManager.name is "pnpm"', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
devEngines: {
|
||||
packageManager: {name: 'pnpm'}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should not enable caching if devEngines.packageManager is array without "npm"', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
devEngines: {
|
||||
packageManager: [{name: 'pnpm'}, {name: 'yarn'}]
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should not enable caching if packageManager field is missing in package.json and cache input is not provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = '';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
// packageManager field is not present
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should skip caching when package-manager-cache is false', async () => {
|
||||
inputs['package-manager-cache'] = 'false';
|
||||
inputs['cache'] = '';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
await main.run();
|
||||
expect(saveStateSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should enable caching with cache input explicitly provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = 'npm';
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
await main.run();
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'npm');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -255,7 +255,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '13.13.1-nightly20200415947ddec091';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -291,7 +290,6 @@ describe('setup-node', () => {
|
||||
];
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -333,7 +331,6 @@ describe('setup-node', () => {
|
||||
];
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -389,7 +386,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '18.0.0-nightly202204180699150267';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
@ -427,7 +423,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
const expectedUrl = `https://nodejs.org/download/nightly/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
|
||||
@ -473,7 +468,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
inputs['mirror'] = 'https://my-mirror.org';
|
||||
inputs['mirror-token'] = 'my-mirror-token';
|
||||
|
||||
@ -235,7 +235,6 @@ describe('setup-node', () => {
|
||||
const resolvedVersion = versionSpec;
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
const expectedUrl =
|
||||
@ -290,7 +289,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '11.15.0';
|
||||
const mirror = 'https://my_mirror_url';
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
inputs['mirror'] = mirror;
|
||||
inputs['mirror-token'] = 'faketoken';
|
||||
@ -327,7 +325,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '11.15.0';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -385,7 +382,6 @@ describe('setup-node', () => {
|
||||
const resolvedVersion = versionSpec;
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
@ -405,7 +401,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '11.15.0';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -448,7 +443,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
const expectedUrl =
|
||||
@ -560,7 +554,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['check-latest'] = 'true';
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -602,7 +595,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['check-latest'] = 'true';
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -882,7 +874,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
inputs['mirror'] = 'https://my_mirror_url';
|
||||
inputs['mirror-token'] = 'faketoken';
|
||||
|
||||
@ -194,7 +194,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '13.0.0-rc.0';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
// ... but not in the local cache
|
||||
@ -239,7 +238,6 @@ describe('setup-node', () => {
|
||||
const versionSpec = '14.7.0-rc.1';
|
||||
|
||||
inputs['node-version'] = versionSpec;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
findSpy.mockImplementation(() => '');
|
||||
@ -268,7 +266,6 @@ describe('setup-node', () => {
|
||||
|
||||
inputs['node-version'] = version;
|
||||
inputs['architecture'] = arch;
|
||||
inputs['always-auth'] = false;
|
||||
inputs['token'] = 'faketoken';
|
||||
|
||||
const expectedUrl = `https://nodejs.org/download/rc/v${version}/node-v${version}-${platform}-${arch}.${fileExtension}`;
|
||||
|
||||
@ -7,8 +7,13 @@ fi
|
||||
|
||||
node_version="$(node --version)"
|
||||
echo "Found node version '$node_version'"
|
||||
if [ -z "$(echo $node_version | grep --fixed-strings v$1)" ]; then
|
||||
echo "Unexpected version"
|
||||
|
||||
# Extract the major version from the node version (remove the 'v' prefix)
|
||||
actual_major_version=$(echo $node_version | sed -E 's/^v([0-9]+)\..*/\1/')
|
||||
expected_major_version=$(echo $1 | sed -E 's/^([0-9]+)\..*/\1/') # Extract major version from argument
|
||||
|
||||
if [ "$actual_major_version" != "$expected_major_version" ]; then
|
||||
echo "Expected Node.js $expected_major_version.x.x but found $node_version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@ -2,9 +2,6 @@ name: 'Setup Node.js environment'
|
||||
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.'
|
||||
default: 'false'
|
||||
node-version:
|
||||
description: 'Version Spec of the version to use. Examples: 12.x, 10.15.1, >=10.15.0.'
|
||||
node-version-file:
|
||||
@ -23,6 +20,9 @@ inputs:
|
||||
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
|
||||
cache:
|
||||
description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm.'
|
||||
package-manager-cache:
|
||||
description: 'Set to false to disable automatic caching. By default, caching is enabled when either devEngines.packageManager or the top-level packageManager field in package.json specifies npm as the package manager.'
|
||||
default: true
|
||||
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.'
|
||||
mirror:
|
||||
@ -37,7 +37,7 @@ outputs:
|
||||
node-version:
|
||||
description: 'The installed node version.'
|
||||
runs:
|
||||
using: 'node20'
|
||||
using: 'node24'
|
||||
main: 'dist/setup/index.js'
|
||||
post: 'dist/cache-save/index.js'
|
||||
post-if: success()
|
||||
|
||||
1571
dist/cache-save/index.js
vendored
1571
dist/cache-save/index.js
vendored
File diff suppressed because it is too large
Load Diff
9989
dist/setup/index.js
vendored
9989
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
@ -45,10 +45,10 @@ If `check-latest` is set to `true`, the action first checks if the cached versio
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16'
|
||||
node-version: '24'
|
||||
check-latest: true
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
@ -63,8 +63,8 @@ See [supported version syntax](https://github.com/actions/setup-node#supported-v
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
- run: npm ci
|
||||
@ -97,10 +97,10 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
architecture: 'x64' # optional, x64 or x86. If not specified, x64 will be used by default
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
@ -118,10 +118,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20.0.0-v8-canary' # it will install the latest v8 canary release for node 20.0.0
|
||||
node-version: '24.0.0-v8-canary' # it will install the latest v8 canary release for node 24.0.0
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -133,10 +133,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '20-v8-canary' # it will install the latest v8 canary release for node 20
|
||||
node-version: '24-v8-canary' # it will install the latest v8 canary release for node 24
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -149,10 +149,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 'v20.1.1-v8-canary20221103f7e2421e91'
|
||||
node-version: 'v24.0.0-v8-canary2025030537242e55ac'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -169,10 +169,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16-nightly' # it will install the latest nightly release for node 16
|
||||
node-version: '24-nightly' # it will install the latest nightly release for node 24
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -185,10 +185,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16.0.0-nightly' # it will install the latest nightly release for node 16.0.0
|
||||
node-version: '24.0.0-nightly' # it will install the latest nightly release for node 24.0.0
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -201,10 +201,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16.0.0-nightly20210420a0261d231c'
|
||||
node-version: '24.0.0-nightly202505066102159fa1'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -219,27 +219,28 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Node sample
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '16.0.0-rc.1'
|
||||
node-version: '24.0.0-rc.4'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
**Note:** Unlike nightly versions, which support version range specifiers, you must specify the exact version for a release candidate: `16.0.0-rc.1`.
|
||||
**Note:** Unlike nightly versions, which support version range specifiers, you must specify the exact version for a release candidate: `24.0.0-rc.4`.
|
||||
|
||||
## 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.
|
||||
Yarn caching handles both Yarn Classic (v1) and Yarn Berry (v2, v3, v4+).
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'yarn'
|
||||
- run: yarn install --frozen-lockfile # optional, --immutable
|
||||
- run: yarn test
|
||||
@ -255,13 +256,13 @@ steps:
|
||||
# NOTE: pnpm caching support requires pnpm version >= 6.10.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v2
|
||||
- uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 6.32.9
|
||||
- uses: actions/setup-node@v4
|
||||
version: 10
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm install
|
||||
- run: pnpm test
|
||||
@ -274,10 +275,10 @@ steps:
|
||||
**Using wildcard patterns to cache dependencies**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
- run: npm ci
|
||||
@ -287,10 +288,10 @@ steps:
|
||||
**Using a list of file paths to cache dependencies**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: |
|
||||
server/app/package-lock.json
|
||||
@ -299,6 +300,35 @@ steps:
|
||||
- run: npm test
|
||||
```
|
||||
|
||||
**Restore-Only Cache**
|
||||
|
||||
```yaml
|
||||
## In some workflows, you may want to restore a cache without saving it. This can help reduce cache writes and storage usage in workflows that only need to read from cache
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
# Restore Node.js modules cache (restore-only)
|
||||
- name: Restore Node modules cache
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
# Setup Node.js
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
# Install dependencies
|
||||
- run: npm install
|
||||
```
|
||||
|
||||
> For more details related to cache scenarios, please refer [Node – npm](https://github.com/actions/cache/blob/main/examples.md#node---npm).
|
||||
|
||||
## Multiple Operating Systems and Architectures
|
||||
|
||||
```yaml
|
||||
@ -312,21 +342,21 @@ jobs:
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
node_version:
|
||||
- 12
|
||||
- 14
|
||||
- 16
|
||||
- 20
|
||||
- 22
|
||||
- 24
|
||||
architecture:
|
||||
- x64
|
||||
# an extra windows-x86 run:
|
||||
include:
|
||||
- os: windows-2016
|
||||
node_version: 12
|
||||
- os: windows-latest
|
||||
node_version: 24
|
||||
architecture: x86
|
||||
name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node_version }}
|
||||
architecture: ${{ matrix.architecture }}
|
||||
@ -337,16 +367,16 @@ jobs:
|
||||
## Publish to npmjs and GPR with npm
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm ci
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
registry-url: 'https://npm.pkg.github.com'
|
||||
- run: npm publish
|
||||
@ -357,16 +387,16 @@ steps:
|
||||
## Publish to npmjs and GPR with yarn
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
registry-url: <registry url>
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.YARN_TOKEN }}
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
registry-url: 'https://npm.pkg.github.com'
|
||||
- run: yarn publish
|
||||
@ -377,10 +407,10 @@ steps:
|
||||
## Use private packages
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
# Skip post-install scripts here, as a malicious
|
||||
# script could steal NODE_AUTH_TOKEN.
|
||||
@ -397,10 +427,10 @@ Below you can find a sample "Setup .yarnrc.yml" step, that is going to allow you
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
- name: Setup .yarnrc.yml
|
||||
run: |
|
||||
yarn config set npmScopes.my-org.npmRegistryServer "https://npm.pkg.github.com"
|
||||
@ -416,9 +446,6 @@ To access private GitHub Packages within the same organization, go to "Manage Ac
|
||||
|
||||
Please refer to the [Ensuring workflow access to your package - Configuring a package's access control and visibility](https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-workflow-access-to-your-package) for more details.
|
||||
|
||||
### always-auth input
|
||||
The always-auth input sets `always-auth=true` in .npmrc file. With this option set [npm](https://docs.npmjs.com/cli/v6/using-npm/config#always-auth)/yarn sends the authentication credentials when making a request to the registries.
|
||||
|
||||
## Use private mirror
|
||||
|
||||
It is possible to use a private mirror hosting Node.js binaries. This mirror must be a full mirror of the official Node.js distribution.
|
||||
@ -427,9 +454,9 @@ It is possible to specify a token to authenticate with the mirror using the `mir
|
||||
The token will be passed as a bearer token in the `Authorization` header.
|
||||
|
||||
```yaml
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
mirror: 'https://nodejs.org/dist'
|
||||
mirror-token: 'your-mirror-token'
|
||||
```
|
||||
|
||||
662
package-lock.json
generated
662
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@ -1,9 +1,12 @@
|
||||
{
|
||||
"name": "setup-node",
|
||||
"version": "4.0.0",
|
||||
"version": "6.0.0",
|
||||
"private": true,
|
||||
"description": "setup node action",
|
||||
"main": "lib/setup-node.js",
|
||||
"engines": {
|
||||
"node": ">=24.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "ncc build -o dist/setup src/setup-node.ts && ncc build -o dist/cache-save src/cache-save.ts",
|
||||
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
|
||||
@ -25,20 +28,20 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^4.0.3",
|
||||
"@actions/cache": "^4.1.0",
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^5.1.1",
|
||||
"@actions/github": "^6.0.1",
|
||||
"@actions/glob": "^0.5.0",
|
||||
"@actions/http-client": "^2.2.1",
|
||||
"@actions/io": "^1.0.2",
|
||||
"@actions/tool-cache": "^2.0.2",
|
||||
"semver": "^7.6.3",
|
||||
"uuid": "^9.0.1"
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^20.11.25",
|
||||
"@types/node": "^24.1.0",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||
"@typescript-eslint/parser": "^5.54.0",
|
||||
@ -50,8 +53,8 @@
|
||||
"jest": "^29.7.0",
|
||||
"jest-circus": "^29.7.0",
|
||||
"jest-each": "^29.7.0",
|
||||
"prettier": "^2.8.4",
|
||||
"ts-jest": "^29.1.2",
|
||||
"prettier": "^3.6.2",
|
||||
"ts-jest": "^29.4.1",
|
||||
"typescript": "^5.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
|
||||
export function configAuthentication(registryUrl: string, alwaysAuth: string) {
|
||||
export function configAuthentication(registryUrl: string) {
|
||||
const npmrc: string = path.resolve(
|
||||
process.env['RUNNER_TEMP'] || process.cwd(),
|
||||
'.npmrc'
|
||||
@ -13,14 +13,10 @@ export function configAuthentication(registryUrl: string, alwaysAuth: string) {
|
||||
registryUrl += '/';
|
||||
}
|
||||
|
||||
writeRegistryToFile(registryUrl, npmrc, alwaysAuth);
|
||||
writeRegistryToFile(registryUrl, npmrc);
|
||||
}
|
||||
|
||||
function writeRegistryToFile(
|
||||
registryUrl: string,
|
||||
fileLocation: string,
|
||||
alwaysAuth: string
|
||||
) {
|
||||
function writeRegistryToFile(registryUrl: string, fileLocation: string) {
|
||||
let scope: string = core.getInput('scope');
|
||||
if (!scope && registryUrl.indexOf('npm.pkg.github.com') > -1) {
|
||||
scope = github.context.repo.owner;
|
||||
@ -47,8 +43,7 @@ function writeRegistryToFile(
|
||||
const authString: string =
|
||||
registryUrl.replace(/(^\w+:|^)/, '') + ':_authToken=${NODE_AUTH_TOKEN}';
|
||||
const registryString = `${scope}registry=${registryUrl}`;
|
||||
const alwaysAuthString = `always-auth=${alwaysAuth}`;
|
||||
newContents += `${authString}${os.EOL}${registryString}${os.EOL}${alwaysAuthString}`;
|
||||
newContents += `${authString}${os.EOL}${registryString}`;
|
||||
fs.writeFileSync(fileLocation, newContents);
|
||||
core.exportVariable('NPM_CONFIG_USERCONFIG', fileLocation);
|
||||
// Export empty node_auth_token if didn't exist so npm doesn't complain about not being able to find it
|
||||
|
||||
@ -7,6 +7,7 @@ import {getPackageManagerInfo} from './cache-utils';
|
||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
||||
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
||||
// throw an uncaught exception. Instead of failing this action, just warn.
|
||||
|
||||
process.on('uncaughtException', e => {
|
||||
const warningPrefix = '[warning]';
|
||||
core.info(`${warningPrefix}${e.message}`);
|
||||
|
||||
@ -167,14 +167,12 @@ const getCacheDirectoriesFromCacheDependencyPath = async (
|
||||
packageManagerInfo: PackageManagerInfo,
|
||||
cacheDependencyPath: string
|
||||
): Promise<string[]> => {
|
||||
const projectDirectories = await getProjectDirectoriesFromCacheDependencyPath(
|
||||
cacheDependencyPath
|
||||
);
|
||||
const projectDirectories =
|
||||
await getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath);
|
||||
const cacheFoldersPaths = await Promise.all(
|
||||
projectDirectories.map(async projectDirectory => {
|
||||
const cacheFolderPath = await packageManagerInfo.getCacheFolderPath(
|
||||
projectDirectory
|
||||
);
|
||||
const cacheFolderPath =
|
||||
await packageManagerInfo.getCacheFolderPath(projectDirectory);
|
||||
core.debug(
|
||||
`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`
|
||||
);
|
||||
|
||||
@ -221,8 +221,8 @@ export default class OfficialBuilds extends BaseDistribution {
|
||||
alias === '*'
|
||||
? numbered[numbered.length - 1]
|
||||
: n < 0
|
||||
? numbered[numbered.length - 1 + n]
|
||||
: aliases[alias];
|
||||
? numbered[numbered.length - 1 + n]
|
||||
: aliases[alias];
|
||||
|
||||
if (!release) {
|
||||
throw new Error(
|
||||
|
||||
61
src/main.ts
61
src/main.ts
@ -1,6 +1,7 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import os from 'os';
|
||||
import fs from 'fs';
|
||||
|
||||
import * as auth from './authutil';
|
||||
import * as path from 'path';
|
||||
@ -20,6 +21,9 @@ export async function run() {
|
||||
|
||||
let arch = core.getInput('architecture');
|
||||
const cache = core.getInput('cache');
|
||||
const packagemanagercache =
|
||||
(core.getInput('package-manager-cache') || 'true').toUpperCase() ===
|
||||
'TRUE';
|
||||
|
||||
// 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.
|
||||
@ -58,15 +62,29 @@ export async function run() {
|
||||
await printEnvDetailsAndSetOutput();
|
||||
|
||||
const registryUrl: string = core.getInput('registry-url');
|
||||
const alwaysAuth: string = core.getInput('always-auth');
|
||||
if (registryUrl) {
|
||||
auth.configAuthentication(registryUrl, alwaysAuth);
|
||||
auth.configAuthentication(registryUrl);
|
||||
}
|
||||
|
||||
if (cache && isCacheFeatureAvailable()) {
|
||||
core.saveState(State.CachePackageManager, cache);
|
||||
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
||||
await restoreCache(cache, cacheDependencyPath);
|
||||
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
||||
|
||||
if (isCacheFeatureAvailable()) {
|
||||
// if the cache input is provided, use it for caching.
|
||||
if (cache) {
|
||||
core.saveState(State.CachePackageManager, cache);
|
||||
await restoreCache(cache, cacheDependencyPath);
|
||||
// package manager npm is detected from package.json, enable auto-caching for npm.
|
||||
} else if (packagemanagercache) {
|
||||
const resolvedPackageManager = getNameFromPackageManagerField();
|
||||
if (resolvedPackageManager) {
|
||||
core.info(
|
||||
"Detected npm as the package manager from package.json's packageManager field. " +
|
||||
'Auto caching has been enabled for npm. If you want to disable it, set package-manager-cache input to false'
|
||||
);
|
||||
core.saveState(State.CachePackageManager, resolvedPackageManager);
|
||||
await restoreCache(resolvedPackageManager, cacheDependencyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const matchersPath = path.join(__dirname, '../..', '.github');
|
||||
@ -117,3 +135,34 @@ function resolveVersionInput(): string {
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
export function getNameFromPackageManagerField(): string | undefined {
|
||||
const npmRegex = /^(\^)?npm(@.*)?$/; // matches "npm", "npm@...", "^npm@..."
|
||||
try {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(process.env.GITHUB_WORKSPACE!, 'package.json'),
|
||||
'utf-8'
|
||||
)
|
||||
);
|
||||
|
||||
// Check devEngines.packageManager first (object or array)
|
||||
const devPM = packageJson?.devEngines?.packageManager;
|
||||
const devPMArray = devPM ? (Array.isArray(devPM) ? devPM : [devPM]) : [];
|
||||
for (const obj of devPMArray) {
|
||||
if (typeof obj?.name === 'string' && npmRegex.test(obj.name)) {
|
||||
return 'npm';
|
||||
}
|
||||
}
|
||||
|
||||
// Check top-level packageManager
|
||||
const topLevelPM = packageJson?.packageManager;
|
||||
if (typeof topLevelPM === 'string' && npmRegex.test(topLevelPM)) {
|
||||
return 'npm';
|
||||
}
|
||||
|
||||
return undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user