mirror of
https://github.com/actions/setup-node.git
synced 2025-08-14 04:22:15 +00:00
initial commit
This commit is contained in:
parent
4dd8002ba1
commit
fdbef2dddd
2
.github/workflows/basic-validation.yml
vendored
2
.github/workflows/basic-validation.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@ -3,7 +3,7 @@ name: Check dist
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -2,7 +2,7 @@ name: CodeQL analysis
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [check-686]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
schedule:
|
schedule:
|
||||||
|
42
.github/workflows/e2e-cache.yml
vendored
42
.github/workflows/e2e-cache.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
@ -243,3 +243,43 @@ jobs:
|
|||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
sub2/*.lock
|
sub2/*.lock
|
||||||
sub3/*.lock
|
sub3/*.lock
|
||||||
|
|
||||||
|
test-cache-auto-enabled:
|
||||||
|
name: Test Cache Auto-Enabled
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||||
|
node-version: [18, 20, 22]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Change directory to __tests__/data
|
||||||
|
run: cd __tests__/data
|
||||||
|
- name: Setup Node
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
test-cache-explicitly-disabled:
|
||||||
|
name: Test Cache Explicitly Disabled
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
|
||||||
|
node-version: [18, 20, 22]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Change directory to __tests__/data
|
||||||
|
run: cd __tests__/data
|
||||||
|
- name: Setup Node
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: ''
|
||||||
|
- name: Verify node and npm
|
||||||
|
run: __tests__/verify-node.sh "${{ matrix.node-version }}"
|
||||||
|
shell: bash
|
||||||
|
2
.github/workflows/licensed.yml
vendored
2
.github/workflows/licensed.yml
vendored
@ -3,7 +3,7 @@ name: Licensed
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
2
.github/workflows/proxy.yml
vendored
2
.github/workflows/proxy.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
2
.github/workflows/versions.yml
vendored
2
.github/workflows/versions.yml
vendored
@ -6,7 +6,7 @@ on:
|
|||||||
- '**.md'
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- check-686
|
||||||
- releases/*
|
- releases/*
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
|
@ -135,7 +135,8 @@ It's **always** recommended to commit the lockfile of your package manager for s
|
|||||||
|
|
||||||
## Caching global packages data
|
## 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. If not set, caching is automatically enabled if a supported package manager is detected in your `package.json` (`devEngines.packageManager.name` or `packageManager` field).
|
||||||
|
If set to `''` (empty string), caching is explicitly disabled, even if a package manager is present.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"devEngines": {
|
||||||
|
"packageManager": {
|
||||||
|
"name": "npm"
|
||||||
|
}
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.0.0"
|
"node": "^20.0.0"
|
||||||
}
|
}
|
||||||
|
@ -240,6 +240,15 @@ describe('main tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('cache on GHES', () => {
|
describe('cache on GHES', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Reset mocks and environment variables before each test
|
||||||
|
jest.resetModules();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
jest.spyOn(core, 'saveState').mockImplementation(() => {});
|
||||||
|
jest.spyOn(core, 'warning').mockImplementation(() => {});
|
||||||
|
delete process.env['GITHUB_SERVER_URL'];
|
||||||
|
});
|
||||||
|
|
||||||
it('Should throw an error, because cache is not supported', async () => {
|
it('Should throw an error, because cache is not supported', async () => {
|
||||||
inputs['node-version'] = '12';
|
inputs['node-version'] = '12';
|
||||||
inputs['cache'] = 'npm';
|
inputs['cache'] = 'npm';
|
||||||
@ -253,6 +262,9 @@ describe('main tests', () => {
|
|||||||
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
||||||
isCacheActionAvailable.mockImplementation(() => false);
|
isCacheActionAvailable.mockImplementation(() => false);
|
||||||
|
|
||||||
|
// Mock package.json with no packageManager field
|
||||||
|
jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify({}));
|
||||||
|
|
||||||
await main.run();
|
await main.run();
|
||||||
|
|
||||||
expect(warningSpy).toHaveBeenCalledWith(
|
expect(warningSpy).toHaveBeenCalledWith(
|
||||||
@ -273,11 +285,107 @@ describe('main tests', () => {
|
|||||||
process.env['GITHUB_SERVER_URL'] = '';
|
process.env['GITHUB_SERVER_URL'] = '';
|
||||||
isCacheActionAvailable.mockImplementation(() => false);
|
isCacheActionAvailable.mockImplementation(() => false);
|
||||||
|
|
||||||
|
// Mock package.json with no packageManager field
|
||||||
|
jest.spyOn(fs, 'readFileSync').mockReturnValue(JSON.stringify({}));
|
||||||
|
|
||||||
await main.run();
|
await main.run();
|
||||||
|
|
||||||
expect(warningSpy).toHaveBeenCalledWith(
|
expect(warningSpy).toHaveBeenCalledWith(
|
||||||
'The runner was not able to contact the cache service. Caching will be skipped'
|
'The runner was not able to contact the cache service. Caching will be skipped'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should enable caching by default when packageManager field is defined', async () => {
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['cache'] = undefined; // User did not specify cache
|
||||||
|
|
||||||
|
inSpy.mockImplementation(name => inputs[name]);
|
||||||
|
const toolPath = path.normalize('/cache/node/18.0.0/x64');
|
||||||
|
findSpy.mockImplementation(() => toolPath);
|
||||||
|
|
||||||
|
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
||||||
|
isCacheActionAvailable.mockImplementation(() => true);
|
||||||
|
|
||||||
|
// packageManager in package.json
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(
|
||||||
|
JSON.stringify({
|
||||||
|
packageManager: 'yarn@3.2.0'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
// Should enable caching (saveState called with 'yarn')
|
||||||
|
expect(core.saveState).toHaveBeenCalledWith(expect.anything(), 'yarn');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should enable cache if devEngines.packageManager field is present', async () => {
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['cache'] = undefined; // Explicitly opt-in via package.json
|
||||||
|
|
||||||
|
inSpy.mockImplementation(name => inputs[name]);
|
||||||
|
findSpy.mockImplementation(() =>
|
||||||
|
path.normalize('/cache/node/12.16.1/x64')
|
||||||
|
);
|
||||||
|
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
||||||
|
isCacheActionAvailable.mockImplementation(() => true);
|
||||||
|
|
||||||
|
// devEngines.packageManager in package.json
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(
|
||||||
|
JSON.stringify({
|
||||||
|
devEngines: {
|
||||||
|
packageManager: {name: 'pnpm'}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
// Should enable caching (saveState called with 'pnpm')
|
||||||
|
expect(core.saveState).toHaveBeenCalledWith(expect.anything(), 'pnpm');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should NOT enable caching when neither cache nor packageManager is set', async () => {
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['cache'] = undefined;
|
||||||
|
|
||||||
|
inSpy.mockImplementation(name => inputs[name]);
|
||||||
|
findSpy.mockImplementation(() =>
|
||||||
|
path.normalize('/cache/node/12.16.1/x64')
|
||||||
|
);
|
||||||
|
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
||||||
|
isCacheActionAvailable.mockImplementation(() => true);
|
||||||
|
|
||||||
|
// package.json with no cache info
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(JSON.stringify({}));
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
expect(core.saveState).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should NOT enable caching when cache is explicitly disabled', async () => {
|
||||||
|
inputs['node-version'] = '12';
|
||||||
|
inputs['cache'] = ''; // Explicitly opt-out
|
||||||
|
|
||||||
|
inSpy.mockImplementation(name => inputs[name]);
|
||||||
|
findSpy.mockImplementation(() =>
|
||||||
|
path.normalize('/cache/node/12.16.1/x64')
|
||||||
|
);
|
||||||
|
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';
|
||||||
|
isCacheActionAvailable.mockImplementation(() => true);
|
||||||
|
|
||||||
|
// packageManager in package.json
|
||||||
|
(fs.readFileSync as jest.Mock).mockReturnValue(
|
||||||
|
JSON.stringify({
|
||||||
|
packageManager: 'yarn@3.2.0'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await main.run();
|
||||||
|
|
||||||
|
// Should NOT enable caching (saveState not called)
|
||||||
|
expect(core.saveState).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
14524
dist/cache-save/index.js
vendored
14524
dist/cache-save/index.js
vendored
File diff suppressed because one or more lines are too long
21364
dist/setup/index.js
vendored
21364
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
27
src/main.ts
27
src/main.ts
@ -1,6 +1,7 @@
|
|||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
import * as auth from './authutil';
|
import * as auth from './authutil';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
@ -63,10 +64,21 @@ export async function run() {
|
|||||||
auth.configAuthentication(registryUrl, alwaysAuth);
|
auth.configAuthentication(registryUrl, alwaysAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache && isCacheFeatureAvailable()) {
|
const packageManagerFromManifest = getNameFromPackageManagerField();
|
||||||
core.saveState(State.CachePackageManager, cache);
|
if (
|
||||||
|
cache !== '' &&
|
||||||
|
isCacheFeatureAvailable() &&
|
||||||
|
(cache !== undefined || packageManagerFromManifest)
|
||||||
|
) {
|
||||||
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
const cacheDependencyPath = core.getInput('cache-dependency-path');
|
||||||
await restoreCache(cache, cacheDependencyPath);
|
const packageManager =
|
||||||
|
cache !== undefined ? cache : packageManagerFromManifest;
|
||||||
|
if (!packageManager) {
|
||||||
|
// This should NOT happen due to your if, but this satisfies TypeScript.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
core.saveState(State.CachePackageManager, packageManager);
|
||||||
|
await restoreCache(packageManager, cacheDependencyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const matchersPath = path.join(__dirname, '../..', '.github');
|
const matchersPath = path.join(__dirname, '../..', '.github');
|
||||||
@ -117,3 +129,12 @@ function resolveVersionInput(): string {
|
|||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNameFromPackageManagerField(): string | undefined {
|
||||||
|
// Check devEngines.packageManager first
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||||
|
return (
|
||||||
|
packageJson.devEngines?.packageManager?.name ||
|
||||||
|
packageJson.packageManager?.replace(/^[^a-zA-Z0-9]+/, '').split('@')[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user