From e6a6894ab6f44fae852e569ffa2955b98bf0d14b Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Thu, 8 Jun 2023 13:44:41 +0200 Subject: [PATCH] review updates --- .github/workflows/e2e-cache.yml | 75 ++++++++ .github/workflows/yarn-subprojects.yml | 81 --------- __tests__/cache-save.test.ts | 239 ++++++++++++------------- dist/cache-save/index.js | 17 +- dist/setup/index.js | 10 +- src/cache-restore.ts | 1 + src/cache-save.ts | 14 +- src/cache-utils.ts | 21 +-- src/constants.ts | 3 +- 9 files changed, 219 insertions(+), 242 deletions(-) delete mode 100644 .github/workflows/yarn-subprojects.yml diff --git a/.github/workflows/e2e-cache.yml b/.github/workflows/e2e-cache.yml index fab3dcd74..0d0da14c7 100644 --- a/.github/workflows/e2e-cache.yml +++ b/.github/workflows/e2e-cache.yml @@ -134,3 +134,78 @@ jobs: - name: Verify node and yarn run: __tests__/verify-node.sh "${{ matrix.node-version }}" shell: bash + + yarn-subprojects: + name: Test yarn subprojects + strategy: + matrix: + node-version: [12, 14, 16] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: prepare sub-projects + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: false + run: | + rm package.json + rm package-lock.json + echo "create yarn2 project in the sub2" + mkdir sub2 + cd sub2 + cat <package.json + { + "name": "subproject", + "dependencies": { + "random": "^3.0.6", + "uuid": "^9.0.0" + } + } + EOT + yarn set version 2.4.3 + yarn install + + echo "create yarn3 project in the sub3" + cd .. + mkdir sub3 + cd sub3 + cat <package.json + { + "name": "subproject", + "dependencies": { + "random": "^3.0.6", + "uuid": "^9.0.0" + } + } + EOT + yarn set version 3.5.1 + yarn install + + echo "create yarn1 project in the root" + cd .. + cat <package.json + { + "name": "subproject", + "dependencies": { + "random": "^3.0.6", + "uuid": "^9.0.0" + } + } + EOT + yarn set version 1.22.19 + yarn install + + # expect + # - no errors + # - log + # ##[debug]Cache Paths: + # ##[debug]["sub2/.yarn/cache","sub3/.yarn/cache","../../../.cache/yarn/v6"] + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + cache-dependency-path: | + **/*.lock + yarn.lock diff --git a/.github/workflows/yarn-subprojects.yml b/.github/workflows/yarn-subprojects.yml deleted file mode 100644 index 4bdd44d4d..000000000 --- a/.github/workflows/yarn-subprojects.yml +++ /dev/null @@ -1,81 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI - -on: - push: - - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - node-version: [16] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: prepare sub-projects - env: - YARN_ENABLE_IMMUTABLE_INSTALLS: false - run: | - echo "create yarn2 project in the sub2" - mkdir sub2 - cd sub2 - cat <package.json - { - "name": "subproject", - "dependencies": { - "random": "^3.0.6", - "uuid": "^9.0.0" - } - } - EOT - yarn set version 2.4.3 - yarn install - - echo "create yarn3 project in the sub3" - cd .. - mkdir sub3 - cd sub3 - cat <package.json - { - "name": "subproject", - "dependencies": { - "random": "^3.0.6", - "uuid": "^9.0.0" - } - } - EOT - yarn set version 3.5.1 - yarn install - - echo "create yarn1 project in the root" - cd .. - cat <package.json - { - "name": "subproject", - "dependencies": { - "random": "^3.0.6", - "uuid": "^9.0.0" - } - } - EOT - yarn set version 1.22.19 - yarn install - - # expect - # - no errors - # - log - # ##[debug]Cache Paths: - # ##[debug]["sub2/.yarn/cache","sub3/.yarn/cache","../../../.cache/yarn/v6"] - - name: Setup Node - uses: ./ - with: - node-version: ${{ matrix.node-version }} - cache: 'yarn' - cache-dependency-path: | - **/*.lock - yarn.lock diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts index c84621c53..a989d2b11 100644 --- a/__tests__/cache-save.test.ts +++ b/__tests__/cache-save.test.ts @@ -107,22 +107,20 @@ describe('run', () => { describe('Validate unchanged cache is not saved', () => { it('should not save cache for yarn1', async () => { inputs['cache'] = 'yarn'; - getStateSpy.mockImplementation(() => yarnFileHash); - getCommandOutputSpy - .mockImplementationOnce(() => '1.2.3') - .mockImplementationOnce(() => `${commonPath}/yarn1`); + getStateSpy.mockImplementation(key => + key === State.CachePrimaryKey || key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(2); - expect(debugSpy).toHaveBeenCalledWith( - 'Consumed yarn version is 1.2.3 (working dir: "")' - ); - expect(debugSpy).toHaveBeenCalledWith( - 'yarn\'s cache folder "/some/random/path/yarn1" configured for the root directory' - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).toHaveBeenCalledWith( `Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.` ); @@ -131,22 +129,28 @@ describe('run', () => { it('should not save cache for yarn2', async () => { inputs['cache'] = 'yarn'; - getStateSpy.mockImplementation(() => yarnFileHash); - getCommandOutputSpy - .mockImplementationOnce(() => '2.2.3') - .mockImplementationOnce(() => `${commonPath}/yarn2`); + getStateSpy.mockImplementation(key => + key === State.CachePrimaryKey || key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(2); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); + /* expect(debugSpy).toHaveBeenCalledWith( 'Consumed yarn version is 2.2.3 (working dir: "")' ); expect(debugSpy).toHaveBeenCalledWith( 'yarn\'s cache folder "/some/random/path/yarn2" configured for the root directory' ); + */ expect(infoSpy).toHaveBeenCalledWith( `Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.` ); @@ -155,39 +159,40 @@ describe('run', () => { it('should not save cache for npm', async () => { inputs['cache'] = 'npm'; - getStateSpy.mockImplementation(() => npmFileHash); + getStateSpy.mockImplementation(key => + key === State.CachePrimaryKey || key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `npm's cache folder "${commonPath}/npm" configured for the root directory` - ); - expect(infoSpy).toHaveBeenCalledWith( - `Cache hit occurred on the primary key ${npmFileHash}, not saving cache.` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(setFailedSpy).not.toHaveBeenCalled(); }); it('should not save cache for pnpm', async () => { inputs['cache'] = 'pnpm'; - getStateSpy.mockImplementation(() => pnpmFileHash); - getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/pnpm`); + getStateSpy.mockImplementation(key => + key === State.CachePrimaryKey || key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `pnpm's cache folder "${commonPath}/pnpm" configured for the root directory` - ); - expect(infoSpy).toHaveBeenCalledWith( - `Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(setFailedSpy).not.toHaveBeenCalled(); }); }); @@ -195,28 +200,22 @@ describe('run', () => { describe('action saves the cache', () => { it('saves cache from yarn 1', async () => { inputs['cache'] = 'yarn'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return yarnFileHash; - } else { - return npmFileHash; - } - }); - getCommandOutputSpy - .mockImplementationOnce(() => '1.2.3') - .mockImplementationOnce(() => `${commonPath}/yarn1`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePrimaryKey + ? npmFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(2); - expect(debugSpy).toHaveBeenCalledWith( - 'Consumed yarn version is 1.2.3 (working dir: "")' - ); - expect(debugSpy).toHaveBeenCalledWith( - 'yarn\'s cache folder "/some/random/path/yarn1" configured for the root directory' - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.` ); @@ -229,28 +228,22 @@ describe('run', () => { it('saves cache from yarn 2', async () => { inputs['cache'] = 'yarn'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return yarnFileHash; - } else { - return npmFileHash; - } - }); - getCommandOutputSpy - .mockImplementationOnce(() => '2.2.3') - .mockImplementationOnce(() => `${commonPath}/yarn2`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? yarnFileHash + : key === State.CachePrimaryKey + ? npmFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(2); - expect(debugSpy).toHaveBeenCalledWith( - 'Consumed yarn version is 2.2.3 (working dir: "")' - ); - expect(debugSpy).toHaveBeenCalledWith( - 'yarn\'s cache folder "/some/random/path/yarn2" configured for the root directory' - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${yarnFileHash}, not saving cache.` ); @@ -263,23 +256,22 @@ describe('run', () => { it('saves cache from npm', async () => { inputs['cache'] = 'npm'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return npmFileHash; - } else { - return yarnFileHash; - } - }); - getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? npmFileHash + : key === State.CachePrimaryKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `npm's cache folder "${commonPath}/npm" configured for the root directory` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${npmFileHash}, not saving cache.` ); @@ -292,23 +284,22 @@ describe('run', () => { it('saves cache from pnpm', async () => { inputs['cache'] = 'pnpm'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return pnpmFileHash; - } else { - return npmFileHash; - } - }); - getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/pnpm`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? pnpmFileHash + : key === State.CachePrimaryKey + ? npmFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `pnpm's cache folder "${commonPath}/pnpm" configured for the root directory` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.` ); @@ -321,14 +312,15 @@ describe('run', () => { it('save with -1 cacheId , should not fail workflow', async () => { inputs['cache'] = 'npm'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return npmFileHash; - } else { - return yarnFileHash; - } - }); - getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? npmFileHash + : key === State.CachePrimaryKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); saveCacheSpy.mockImplementation(() => { return -1; }); @@ -336,11 +328,9 @@ describe('run', () => { await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `npm's cache folder "${commonPath}/npm" configured for the root directory` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${npmFileHash}, not saving cache.` ); @@ -353,14 +343,15 @@ describe('run', () => { it('saves with error from toolkit, should fail workflow', async () => { inputs['cache'] = 'npm'; - getStateSpy.mockImplementation((name: string) => { - if (name === State.CacheMatchedKey) { - return npmFileHash; - } else { - return yarnFileHash; - } - }); - getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/npm`); + getStateSpy.mockImplementation((key: string) => + key === State.CacheMatchedKey + ? npmFileHash + : key === State.CachePrimaryKey + ? yarnFileHash + : key === State.CachePaths + ? '["/foo/bar"]' + : 'not expected' + ); saveCacheSpy.mockImplementation(() => { throw new cache.ValidationError('Validation failed'); }); @@ -368,11 +359,9 @@ describe('run', () => { await run(); expect(getInputSpy).toHaveBeenCalled(); - expect(getStateSpy).toHaveBeenCalledTimes(2); - expect(getCommandOutputSpy).toHaveBeenCalledTimes(1); - expect(debugSpy).toHaveBeenCalledWith( - `npm's cache folder "${commonPath}/npm" configured for the root directory` - ); + expect(getStateSpy).toHaveBeenCalledTimes(3); + expect(getCommandOutputSpy).toHaveBeenCalledTimes(0); + expect(debugSpy).toHaveBeenCalledTimes(0); expect(infoSpy).not.toHaveBeenCalledWith( `Cache hit occurred on the primary key ${npmFileHash}, not saving cache.` ); diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index da0215cc1..adf3ccbd3 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -60370,16 +60370,16 @@ exports.run = run; const cachePackages = (packageManager) => __awaiter(void 0, void 0, void 0, function* () { const state = core.getState(constants_1.State.CacheMatchedKey); const primaryKey = core.getState(constants_1.State.CachePrimaryKey); + const cachePaths = JSON.parse(core.getState(constants_1.State.CachePaths) || '[]'); const packageManagerInfo = yield cache_utils_1.getPackageManagerInfo(packageManager); if (!packageManagerInfo) { core.debug(`Caching for '${packageManager}' is not supported`); return; } - // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) - // export declare function getInput(name: string, options?: InputOptions): string; - const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; - const cachePaths = yield cache_utils_1.getCacheDirectories(packageManagerInfo, cacheDependencyPath); if (cachePaths.length === 0) { + // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) + // export declare function getInput(name: string, options?: InputOptions): string; + const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; throw new Error(`Cache folder paths are not retrieved for ${packageManager} with cache-dependency-path = ${cacheDependencyPath}`); } if (primaryKey === state) { @@ -60524,12 +60524,11 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ } else { const globber = yield glob.create(cacheDependencyPath); - cacheDependenciesPaths = (yield globber.glob()) || ['']; + cacheDependenciesPaths = yield globber.glob(); exports.memoizedCacheDependencies[cacheDependencyPath] = cacheDependenciesPaths; } const existingDirectories = cacheDependenciesPaths .map(path_1.default.dirname) - .filter(path => path != null) .filter(util_1.unique()) .filter(fs_1.default.existsSync) .filter(directory => fs_1.default.lstatSync(directory).isDirectory()); @@ -60549,9 +60548,8 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ */ const getCacheDirectoriesFromCacheDependencyPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath); - const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => packageManagerInfo - .getCacheFolderPath(projectDirectory) - .then(cacheFolderPath => { + const cacheFoldersPaths = yield Promise.all(projectDirectories.map((projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { + const cacheFolderPath = packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }))); @@ -60622,6 +60620,7 @@ var State; (function (State) { State["CachePrimaryKey"] = "CACHE_KEY"; State["CacheMatchedKey"] = "CACHE_RESULT"; + State["CachePaths"] = "CACHE_PATHS"; })(State = exports.State || (exports.State = {})); var Outputs; (function (Outputs) { diff --git a/dist/setup/index.js b/dist/setup/index.js index ab004fe01..81a98d074 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -71145,6 +71145,7 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, } const platform = process.env.RUNNER_OS; const cachePaths = yield cache_utils_1.getCacheDirectories(packageManagerInfo, cacheDependencyPath); + core.saveState(constants_1.State.CachePaths, cachePaths); const lockFilePath = cacheDependencyPath ? cacheDependencyPath : findLockFile(packageManagerInfo); @@ -71306,12 +71307,11 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ } else { const globber = yield glob.create(cacheDependencyPath); - cacheDependenciesPaths = (yield globber.glob()) || ['']; + cacheDependenciesPaths = yield globber.glob(); exports.memoizedCacheDependencies[cacheDependencyPath] = cacheDependenciesPaths; } const existingDirectories = cacheDependenciesPaths .map(path_1.default.dirname) - .filter(path => path != null) .filter(util_1.unique()) .filter(fs_1.default.existsSync) .filter(directory => fs_1.default.lstatSync(directory).isDirectory()); @@ -71331,9 +71331,8 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ */ const getCacheDirectoriesFromCacheDependencyPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath); - const cacheFoldersPaths = yield Promise.all(projectDirectories.map(projectDirectory => packageManagerInfo - .getCacheFolderPath(projectDirectory) - .then(cacheFolderPath => { + const cacheFoldersPaths = yield Promise.all(projectDirectories.map((projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { + const cacheFolderPath = packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }))); @@ -71404,6 +71403,7 @@ var State; (function (State) { State["CachePrimaryKey"] = "CACHE_KEY"; State["CacheMatchedKey"] = "CACHE_RESULT"; + State["CachePaths"] = "CACHE_PATHS"; })(State = exports.State || (exports.State = {})); var Outputs; (function (Outputs) { diff --git a/src/cache-restore.ts b/src/cache-restore.ts index cddc41276..e138707c2 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -25,6 +25,7 @@ export const restoreCache = async ( packageManagerInfo, cacheDependencyPath ); + core.saveState(State.CachePaths, cachePaths); const lockFilePath = cacheDependencyPath ? cacheDependencyPath : findLockFile(packageManagerInfo); diff --git a/src/cache-save.ts b/src/cache-save.ts index 6b53a904c..96f6a7d47 100644 --- a/src/cache-save.ts +++ b/src/cache-save.ts @@ -1,7 +1,7 @@ import * as core from '@actions/core'; import * as cache from '@actions/cache'; import {State} from './constants'; -import {getCacheDirectories, getPackageManagerInfo} from './cache-utils'; +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 @@ -23,6 +23,7 @@ export async function run() { const cachePackages = async (packageManager: string) => { const state = core.getState(State.CacheMatchedKey); const primaryKey = core.getState(State.CachePrimaryKey); + const cachePaths = JSON.parse(core.getState(State.CachePaths) || '[]'); const packageManagerInfo = await getPackageManagerInfo(packageManager); if (!packageManagerInfo) { @@ -30,15 +31,10 @@ const cachePackages = async (packageManager: string) => { return; } - // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) - // export declare function getInput(name: string, options?: InputOptions): string; - const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; - const cachePaths = await getCacheDirectories( - packageManagerInfo, - cacheDependencyPath - ); - if (cachePaths.length === 0) { + // TODO: core.getInput has a bug - it can return undefined despite its definition (tests only?) + // export declare function getInput(name: string, options?: InputOptions): string; + const cacheDependencyPath = core.getInput('cache-dependency-path') || ''; throw new Error( `Cache folder paths are not retrieved for ${packageManager} with cache-dependency-path = ${cacheDependencyPath}` ); diff --git a/src/cache-utils.ts b/src/cache-utils.ts index 484ea3be6..f85a7b271 100644 --- a/src/cache-utils.ts +++ b/src/cache-utils.ts @@ -133,13 +133,12 @@ const getProjectDirectoriesFromCacheDependencyPath = async ( cacheDependenciesPaths = memoized; } else { const globber = await glob.create(cacheDependencyPath); - cacheDependenciesPaths = (await globber.glob()) || ['']; + cacheDependenciesPaths = await globber.glob(); memoizedCacheDependencies[cacheDependencyPath] = cacheDependenciesPaths; } const existingDirectories: string[] = cacheDependenciesPaths .map(path.dirname) - .filter(path => path != null) .filter(unique()) .filter(fs.existsSync) .filter(directory => fs.lstatSync(directory).isDirectory()); @@ -170,16 +169,14 @@ const getCacheDirectoriesFromCacheDependencyPath = async ( cacheDependencyPath ); const cacheFoldersPaths = await Promise.all( - projectDirectories.map(projectDirectory => - packageManagerInfo - .getCacheFolderPath(projectDirectory) - .then(cacheFolderPath => { - core.debug( - `${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"` - ); - return cacheFolderPath; - }) - ) + projectDirectories.map(async projectDirectory => { + const cacheFolderPath = + packageManagerInfo.getCacheFolderPath(projectDirectory); + core.debug( + `${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"` + ); + return cacheFolderPath; + }) ); // uniq in order to do not cache the same directories twice return cacheFoldersPaths.filter(unique()); diff --git a/src/constants.ts b/src/constants.ts index 021418c2a..cd017266f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -6,7 +6,8 @@ export enum LockType { export enum State { CachePrimaryKey = 'CACHE_KEY', - CacheMatchedKey = 'CACHE_RESULT' + CacheMatchedKey = 'CACHE_RESULT', + CachePaths = 'CACHE_PATHS' } export enum Outputs {