-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Limit automatic caching to npm, update workflows and documentation #1374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
HarithaVattikuti
merged 10 commits into
actions:main
from
priyagupta108:enable-npm-cache-default
Oct 14, 2025
Merged
Changes from 4 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
470d7fe
default to auto-caching only for npm package manager and documentatio…
priyagupta108 7024c21
refactor: enhance package manager detection for auto-caching
priyagupta108 8f225c5
add devEngines.packageManager detection logic for npm auto-caching
priyagupta108 33371d0
chore: bump version to 6.0.0 and update documentation
priyagupta108 1ba05d5
docs: update README and action.yml for npm caching logic clarification
priyagupta108 1b58234
chore: update Node.js version in workflows
priyagupta108 6b226b8
chore: update Node.js versions in versions.yml
priyagupta108 9b3f664
chore: update rc Node.js version in versions.yml
priyagupta108 232ec05
chore: switch macos-13 runner to macos-latest-large in workflow
priyagupta108 eeb8627
docs: update README and advanced usage documentation
priyagupta108 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,10 @@ 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 the `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. | ||
|
|
||
| ## Breaking changes in V5 | ||
|
|
||
| - Enabled caching by default with package manager detection if no cache input is provided. | ||
|
|
@@ -28,7 +32,7 @@ See [action.yml](action.yml) | |
|
|
||
| <!-- start usage --> | ||
| ```yaml | ||
| - uses: actions/setup-node@v5 | ||
| - 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 | ||
|
|
@@ -67,7 +71,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 | ||
|
|
||
|
|
@@ -113,9 +118,9 @@ See [action.yml](action.yml) | |
| ```yaml | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: actions/setup-node@v5 | ||
| - uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: 18 | ||
| node-version: 24 | ||
| - run: npm ci | ||
| - run: npm test | ||
| ``` | ||
|
|
@@ -132,8 +137,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` | ||
priyagupta108 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Latest release: `*` or `latest`/`current`/`node` | ||
|
|
||
|
|
@@ -151,18 +156,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` | ||
|
|
@@ -174,9 +167,9 @@ See the examples of using cache for `yarn`/`pnpm` and `cache-dependency-path` in | |
| ```yaml | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: actions/setup-node@v5 | ||
| - uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: 20 | ||
| node-version: 24 | ||
| cache: 'npm' | ||
| - run: npm ci | ||
| - run: npm test | ||
|
|
@@ -187,15 +180,29 @@ steps: | |
| ```yaml | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - uses: actions/setup-node@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 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@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 | ||
|
|
@@ -204,12 +211,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@v5 | ||
| - name: Setup node | ||
| uses: actions/setup-node@v5 | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: ${{ matrix.node }} | ||
| - run: npm ci | ||
|
|
@@ -223,10 +230,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@v5 | ||
| 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/[email protected]/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -285,34 +285,72 @@ describe('main tests', () => { | |
| }); | ||
|
|
||
| describe('cache feature tests', () => { | ||
| it('Should enable caching with the resolved package manager from packageManager field in package.json when the cache input is not provided', async () => { | ||
| it('Should enable caching when packageManager is npm and cache input is not provided', async () => { | ||
| inputs['package-manager-cache'] = 'true'; | ||
| inputs['cache'] = ''; // No cache input is provided | ||
| inputs['cache'] = ''; | ||
| isCacheActionAvailable.mockImplementation(() => true); | ||
|
|
||
| inSpy.mockImplementation(name => inputs[name]); | ||
| const readFileSpy = jest.spyOn(fs, 'readFileSync'); | ||
| readFileSpy.mockImplementation(() => | ||
| JSON.stringify({ | ||
| packageManager: '[email protected]' | ||
| }) | ||
| ); | ||
|
|
||
| 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({ | ||
| packageManager: '[email protected]' | ||
| devEngines: { | ||
| packageManager: {name: 'npm'} | ||
| } | ||
| }) | ||
| ); | ||
|
|
||
| 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 () => { | ||
| it('Should enable caching when devEngines.packageManager is array and one entry has name "npm"', async () => { | ||
| inputs['package-manager-cache'] = 'true'; | ||
| inputs['cache'] = ''; // No cache input is provided | ||
| 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 "[email protected]" 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 | ||
| packageManager: '[email protected]' | ||
| }) | ||
| ); | ||
|
|
||
|
|
@@ -321,26 +359,72 @@ describe('main tests', () => { | |
| expect(saveStateSpy).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('Should skip caching when package-manager-cache is false', async () => { | ||
| inputs['package-manager-cache'] = 'false'; | ||
| inputs['cache'] = ''; // No cache input is provided | ||
|
|
||
| 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 enable caching with cache input explicitly provided', async () => { | ||
| it('Should not enable caching if devEngines.packageManager is array without "npm"', async () => { | ||
| inputs['package-manager-cache'] = 'true'; | ||
| inputs['cache'] = 'npm'; // Explicit cache input provided | ||
| 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]); | ||
| isCacheActionAvailable.mockReturnValue(true); | ||
| 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'); | ||
| }); | ||
| }); | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.