mirror of
https://github.com/actions/setup-node.git
synced 2025-10-01 03:55:30 +00:00
default to auto-caching only for npm package manager and documentation update
This commit is contained in:
parent
89d709d423
commit
470d7fe388
47
README.md
47
README.md
@ -14,8 +14,8 @@ This action provides the following functionality for GitHub Actions users:
|
||||
|
||||
## 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.
|
||||
- Enabled caching for npm dependencies by default when the package manager is detected and no cache input is provided.
|
||||
> 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 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)
|
||||
@ -67,7 +67,8 @@ See [action.yml](action.yml)
|
||||
# Default: ''
|
||||
cache: ''
|
||||
|
||||
# Used to disable automatic caching based on the package manager field in package.json. By default, caching is enabled if the package manager field is present and no cache input is provided'
|
||||
# Controls automatic caching for npm. By default, caching for npm is enabled if the 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
|
||||
|
||||
@ -115,7 +116,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 24
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -132,8 +133,8 @@ 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`
|
||||
- Major versions: `22`, `24`
|
||||
- More specific versions: `20.19`, `22.17.1` , `24.8.0`
|
||||
- NVM LTS syntax: `lts/erbium`, `lts/fermium`, `lts/*`, `lts/-n`
|
||||
- Latest release: `*` or `latest`/`current`/`node`
|
||||
|
||||
@ -151,18 +152,6 @@ It's **always** recommended to commit the lockfile of your package manager for s
|
||||
|
||||
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.
|
||||
|
||||
Caching is turned on by default when a `packageManager` field is detected in the `package.json` file and no `cache` input is provided. The `package-manager-cache` input provides control over this automatic caching behavior. By default, `package-manager-cache` is set to `true`, which enables caching when a valid package manager field is detected in the `package.json` file. To disable this automatic caching, set the `package-manager-cache` input to `false`.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
package-manager-cache: false
|
||||
- run: npm ci
|
||||
```
|
||||
> If no valid `packageManager` field is detected in the `package.json` file, caching will remain disabled unless explicitly configured. 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.
|
||||
|
||||
The action defaults to search for the dependency file (`package-lock.json`, `npm-shrinkwrap.json` or `yarn.lock`) in the repository root, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
|
||||
|
||||
**Note:** The action does not cache `node_modules`
|
||||
@ -176,7 +165,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
@ -189,13 +178,27 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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 a `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@v5
|
||||
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
|
||||
@ -204,7 +207,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ 14, 16, 18 ]
|
||||
node: [ 20, 22, 24 ]
|
||||
name: Node ${{ matrix.node }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
@ -226,7 +229,7 @@ To get a higher rate limit, you can [generate a personal access token on github.
|
||||
uses: actions/setup-node@v5
|
||||
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.
|
||||
|
@ -288,19 +288,20 @@ describe('main tests', () => {
|
||||
it('Should enable caching with the resolved package manager from packageManager field in package.json when the cache input is not provided', async () => {
|
||||
inputs['package-manager-cache'] = 'true';
|
||||
inputs['cache'] = ''; // No cache input is provided
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
|
||||
const readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
readFileSpy.mockImplementation(() =>
|
||||
JSON.stringify({
|
||||
packageManager: 'yarn@3.2.0'
|
||||
packageManager: 'npm@10.8.2'
|
||||
})
|
||||
);
|
||||
|
||||
await main.run();
|
||||
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'yarn');
|
||||
expect(saveStateSpy).toHaveBeenCalledWith(expect.anything(), 'npm');
|
||||
});
|
||||
|
||||
it('Should not enable caching if the packageManager field is missing in package.json and the cache input is not provided', async () => {
|
||||
@ -337,7 +338,7 @@ describe('main tests', () => {
|
||||
inputs['cache'] = 'npm'; // Explicit cache input provided
|
||||
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
isCacheActionAvailable.mockReturnValue(true);
|
||||
isCacheActionAvailable.mockImplementation(() => true);
|
||||
|
||||
await main.run();
|
||||
|
||||
|
@ -24,7 +24,7 @@ inputs:
|
||||
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 based on the package manager field in package.json. By default, caching is enabled if the package manager field is present.'
|
||||
description: 'Set to false to disable automatic caching. By default, caching is enabled when npm is the specified package manager in package.json.'
|
||||
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.'
|
||||
|
29
dist/setup/index.js
vendored
29
dist/setup/index.js
vendored
@ -99788,16 +99788,19 @@ function run() {
|
||||
}
|
||||
const resolvedPackageManager = getNameFromPackageManagerField();
|
||||
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
||||
if (cache && (0, cache_utils_1.isCacheFeatureAvailable)()) {
|
||||
core.saveState(constants_1.State.CachePackageManager, cache);
|
||||
yield (0, cache_restore_1.restoreCache)(cache, cacheDependencyPath);
|
||||
}
|
||||
else if (resolvedPackageManager && packagemanagercache) {
|
||||
core.info("Detected package manager from package.json's packageManager field: " +
|
||||
resolvedPackageManager +
|
||||
'. Auto caching has been enabled for it. If you want to disable it, set package-manager-cache input to false');
|
||||
core.saveState(constants_1.State.CachePackageManager, resolvedPackageManager);
|
||||
yield (0, cache_restore_1.restoreCache)(resolvedPackageManager, cacheDependencyPath);
|
||||
if ((0, cache_utils_1.isCacheFeatureAvailable)()) {
|
||||
// if the cache input is provided, use it for caching.
|
||||
if (cache) {
|
||||
core.saveState(constants_1.State.CachePackageManager, cache);
|
||||
yield (0, cache_restore_1.restoreCache)(cache, cacheDependencyPath);
|
||||
// package manager npm is detected from package.json, enable auto-caching for npm.
|
||||
}
|
||||
else if (resolvedPackageManager && packagemanagercache) {
|
||||
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(constants_1.State.CachePackageManager, resolvedPackageManager);
|
||||
yield (0, cache_restore_1.restoreCache)(resolvedPackageManager, cacheDependencyPath);
|
||||
}
|
||||
}
|
||||
const matchersPath = path.join(__dirname, '../..', '.github');
|
||||
core.info(`##[add-matcher]${path.join(matchersPath, 'tsc.json')}`);
|
||||
@ -99833,14 +99836,12 @@ function resolveVersionInput() {
|
||||
return version;
|
||||
}
|
||||
function getNameFromPackageManagerField() {
|
||||
// Check packageManager field in package.json
|
||||
const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'];
|
||||
// Enable auto-cache for npm
|
||||
try {
|
||||
const packageJson = JSON.parse(fs_1.default.readFileSync(path.join(process.env.GITHUB_WORKSPACE, 'package.json'), 'utf-8'));
|
||||
const pm = packageJson.packageManager;
|
||||
if (typeof pm === 'string') {
|
||||
const regex = new RegExp(`^(?:\\^)?(${SUPPORTED_PACKAGE_MANAGERS.join('|')})@`);
|
||||
const match = pm.match(regex);
|
||||
const match = pm.match(/^(?:\^)?(npm)@/);
|
||||
return match ? match[1] : undefined;
|
||||
}
|
||||
return undefined;
|
||||
|
@ -48,7 +48,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '16'
|
||||
node-version: '24'
|
||||
check-latest: true
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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
|
||||
@ -121,7 +121,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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
|
||||
```
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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
|
||||
```
|
||||
@ -152,7 +152,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: 'v20.1.1-v8-canary20221103f7e2421e91'
|
||||
node-version: 'v24.0.0-v8-canary2025030537242e55ac'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -172,7 +172,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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
|
||||
```
|
||||
@ -188,7 +188,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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
|
||||
```
|
||||
@ -204,7 +204,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '16.0.0-nightly20210420a0261d231c'
|
||||
node-version: '24.0.0-nightly202505066102159fa1'
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
```
|
||||
@ -222,24 +222,25 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'yarn'
|
||||
- run: yarn install --frozen-lockfile # optional, --immutable
|
||||
- run: yarn test
|
||||
@ -256,12 +257,12 @@ steps:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v2
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 6.32.9
|
||||
version: 10
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm install
|
||||
- run: pnpm test
|
||||
@ -277,7 +278,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
- run: npm ci
|
||||
@ -290,7 +291,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: '24'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: |
|
||||
server/app/package-lock.json
|
||||
@ -312,15 +313,15 @@ 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-2022
|
||||
node_version: 24
|
||||
architecture: x86
|
||||
name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }}
|
||||
steps:
|
||||
@ -340,7 +341,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm ci
|
||||
- run: npm publish
|
||||
@ -360,7 +361,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
registry-url: <registry url>
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn publish
|
||||
@ -380,7 +381,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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.
|
||||
@ -400,7 +401,7 @@ steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v5
|
||||
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"
|
||||
@ -429,7 +430,7 @@ The token will be passed as a bearer token in the `Authorization` header.
|
||||
```yaml
|
||||
- uses: actions/setup-node@v5
|
||||
with:
|
||||
node-version: '14.x'
|
||||
node-version: '24.x'
|
||||
mirror: 'https://nodejs.org/dist'
|
||||
mirror-token: 'your-mirror-token'
|
||||
```
|
||||
|
34
src/main.ts
34
src/main.ts
@ -69,17 +69,21 @@ export async function run() {
|
||||
|
||||
const resolvedPackageManager = getNameFromPackageManagerField();
|
||||
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
||||
if (cache && isCacheFeatureAvailable()) {
|
||||
core.saveState(State.CachePackageManager, cache);
|
||||
await restoreCache(cache, cacheDependencyPath);
|
||||
} else if (resolvedPackageManager && packagemanagercache) {
|
||||
core.info(
|
||||
"Detected package manager from package.json's packageManager field: " +
|
||||
resolvedPackageManager +
|
||||
'. Auto caching has been enabled for it. If you want to disable it, set package-manager-cache input to false'
|
||||
);
|
||||
core.saveState(State.CachePackageManager, resolvedPackageManager);
|
||||
await restoreCache(resolvedPackageManager, cacheDependencyPath);
|
||||
|
||||
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 (resolvedPackageManager && packagemanagercache) {
|
||||
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');
|
||||
@ -132,8 +136,7 @@ function resolveVersionInput(): string {
|
||||
}
|
||||
|
||||
export function getNameFromPackageManagerField(): string | undefined {
|
||||
// Check packageManager field in package.json
|
||||
const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'];
|
||||
// Enable auto-cache for npm
|
||||
try {
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(
|
||||
@ -143,10 +146,7 @@ export function getNameFromPackageManagerField(): string | undefined {
|
||||
);
|
||||
const pm = packageJson.packageManager;
|
||||
if (typeof pm === 'string') {
|
||||
const regex = new RegExp(
|
||||
`^(?:\\^)?(${SUPPORTED_PACKAGE_MANAGERS.join('|')})@`
|
||||
);
|
||||
const match = pm.match(regex);
|
||||
const match = pm.match(/^(?:\^)?(npm)@/);
|
||||
return match ? match[1] : undefined;
|
||||
}
|
||||
return undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user