diff --git a/.github/workflows/e2e-cache.yml b/.github/workflows/e2e-cache.yml index 9c294f16c..69e75fece 100644 --- a/.github/workflows/e2e-cache.yml +++ b/.github/workflows/e2e-cache.yml @@ -101,6 +101,8 @@ jobs: node-yarn2-depencies-caching: name: Test yarn 2 (Node ${{ matrix.node-version}}, ${{ matrix.os }}) runs-on: ${{ matrix.os }} + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: false strategy: fail-fast: false matrix: diff --git a/README.md b/README.md index 1b66c7b1b..44384203f 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*` ### Caching packages dependencies -The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `yarn`, `pnpm`. The `cache` input is optional, and caching is turned off by default. +The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `yarn`, `pnpm`. The `cache` input is optional, and caching is turned off by default. By default, action hashes the dependency file from the project root. Use `cache-dependency-path` to specify custom file dependency lookup path. The field accepts wildcards or an array of files to be cached. **Caching npm dependencies:** ```yaml @@ -66,6 +66,34 @@ steps: - run: yarn install - run: yarn test ``` + +**Caching all npm dependencies:** +```yaml +steps: +- uses: actions/checkout@v2 +- uses: actions/setup-node@v2 + with: + node-version: '14' + cache: 'npm' + cache-dependency-path: '**/package-lock.json' +- run: npm install +- run: npm test +``` + +**Caching specific paths** +```yaml +steps: +- uses: actions/checkout@v2 +- uses: actions/setup-node@v2 + with: + node-version: '14' + cache: 'npm' + cache-dependency-path: | + server/app/package-lock.json + frontend/app/package-lock.json +- run: npm install +- run: npm test +``` Yarn caching handles both yarn versions: 1 or 2. **Caching pnpm (v6.10+) dependencies:** @@ -90,8 +118,6 @@ steps: - run: pnpm test ``` -> At the moment, only `lock` files in the project root are supported. - ### Matrix Testing: ```yaml jobs: diff --git a/action.yml b/action.yml index 943d53102..2da00f3e3 100644 --- a/action.yml +++ b/action.yml @@ -21,6 +21,8 @@ inputs: default: ${{ github.token }} cache: description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm' + cache-dependency-path: + description: 'Used to specify path to a dependencies lock file: package-lock.json, yarn.lock, etc. Supports wildcards or an array of file names.' # TODO: add input to control forcing to pull from cloud or dist. # escape valve for someone having issues or needing the absolute latest which isn't cached yet # Deprecated option, do not use. Will not be supported after October 1, 2019 diff --git a/dist/setup/index.js b/dist/setup/index.js index 1a213700a..d0f495dd9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -6894,7 +6894,8 @@ function run() { if (isGhes()) { throw new Error('Caching is not supported on GHES'); } - yield cache_restore_1.restoreCache(cache); + const cacheDependencyPath = core.getInput('cache-dependency-path'); + yield cache_restore_1.restoreCache(cache, cacheDependencyPath); } const matchersPath = path.join(__dirname, '../..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'tsc.json')}`); @@ -44655,15 +44656,20 @@ const path_1 = __importDefault(__webpack_require__(622)); const fs_1 = __importDefault(__webpack_require__(747)); const constants_1 = __webpack_require__(196); const cache_utils_1 = __webpack_require__(570); -exports.restoreCache = (packageManager) => __awaiter(void 0, void 0, void 0, function* () { +exports.restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const packageManagerInfo = yield cache_utils_1.getPackageManagerInfo(packageManager); if (!packageManagerInfo) { throw new Error(`Caching for '${packageManager}' is not supported`); } const platform = process.env.RUNNER_OS; const cachePath = yield cache_utils_1.getCacheDirectoryPath(packageManagerInfo, packageManager); - const lockFilePath = findLockFile(packageManagerInfo); + const lockFilePath = cacheDependencyPath + ? cacheDependencyPath + : findLockFile(packageManagerInfo); const fileHash = yield glob.hashFiles(lockFilePath); + if (!fileHash) { + throw new Error('Some specified paths were not resolved, unable to cache dependencies.'); + } const primaryKey = `node-cache-${platform}-${packageManager}-${fileHash}`; core.debug(`primary key is ${primaryKey}`); core.saveState(constants_1.State.CachePrimaryKey, primaryKey); diff --git a/src/cache-restore.ts b/src/cache-restore.ts index a9100252e..cd128cb15 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -11,7 +11,10 @@ import { PackageManagerInfo } from './cache-utils'; -export const restoreCache = async (packageManager: string) => { +export const restoreCache = async ( + packageManager: string, + cacheDependencyPath?: string +) => { const packageManagerInfo = await getPackageManagerInfo(packageManager); if (!packageManagerInfo) { throw new Error(`Caching for '${packageManager}' is not supported`); @@ -22,9 +25,17 @@ export const restoreCache = async (packageManager: string) => { packageManagerInfo, packageManager ); - const lockFilePath = findLockFile(packageManagerInfo); + const lockFilePath = cacheDependencyPath + ? cacheDependencyPath + : findLockFile(packageManagerInfo); const fileHash = await glob.hashFiles(lockFilePath); + if (!fileHash) { + throw new Error( + 'Some specified paths were not resolved, unable to cache dependencies.' + ); + } + const primaryKey = `node-cache-${platform}-${packageManager}-${fileHash}`; core.debug(`primary key is ${primaryKey}`); diff --git a/src/main.ts b/src/main.ts index 2590c9cee..956bc1449 100644 --- a/src/main.ts +++ b/src/main.ts @@ -51,7 +51,8 @@ export async function run() { if (isGhes()) { throw new Error('Caching is not supported on GHES'); } - await restoreCache(cache); + const cacheDependencyPath = core.getInput('cache-dependency-path'); + await restoreCache(cache, cacheDependencyPath); } const matchersPath = path.join(__dirname, '../..', '.github');