diff --git a/__tests__/cache-restore.test.ts b/__tests__/cache-restore.test.ts index 0bbf28126..c97b43b4e 100644 --- a/__tests__/cache-restore.test.ts +++ b/__tests__/cache-restore.test.ts @@ -131,6 +131,7 @@ describe('cache-restore', () => { ])( 'restored dependencies for %s', async (packageManager, toolVersion, fileHash) => { + const expectedCacheKey = `node-cache-${platform}-${arch}-${packageManager}-${fileHash}`; getCommandOutputSpy.mockImplementation((command: string) => { if (command.includes('version')) { return toolVersion; @@ -142,12 +143,20 @@ describe('cache-restore', () => { await restoreCache(packageManager, ''); expect(hashFilesSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenCalledWith( - `Cache restored from key: node-cache-${platform}-${arch}-${packageManager}-${fileHash}` + `Cache restored from key: ${expectedCacheKey}` ); expect(infoSpy).not.toHaveBeenCalledWith( `${packageManager} cache is not found` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true); + expect(setOutputSpy).toHaveBeenCalledWith( + 'cache-key', + expectedCacheKey + ); + expect(setOutputSpy).toHaveBeenCalledWith( + 'cache-matched-key', + expectedCacheKey + ); } ); }); @@ -161,6 +170,7 @@ describe('cache-restore', () => { ])( 'dependencies are changed %s', async (packageManager, toolVersion, fileHash) => { + const expectedCacheKey = `node-cache-${platform}-${arch}-${packageManager}-${fileHash}`; getCommandOutputSpy.mockImplementation((command: string) => { if (command.includes('version')) { return toolVersion; @@ -176,10 +186,72 @@ describe('cache-restore', () => { `${packageManager} cache is not found` ); expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', false); + expect(setOutputSpy).toHaveBeenCalledWith( + 'cache-key', + expectedCacheKey + ); + expect(setOutputSpy).toHaveBeenCalledWith( + 'cache-matched-key', + undefined + ); } ); }); + describe('Cache key output', () => { + const packageManager = 'npm'; + const cacheDependencyPath = 'package-lock.json'; + const primaryKey = `node-cache-${platform}-${arch}-${packageManager}-${npmFileHash}`; + const cacheKey = `node-cache-${platform}-${arch}-${packageManager}-abc123`; + + beforeEach(() => { + getCommandOutputSpy.mockImplementation(command => { + if (command.includes('npm config get cache')) return npmCachePath; + }); + }); + + it('sets the cache-key output', async () => { + restoreCacheSpy.mockResolvedValue(cacheKey); + await restoreCache(packageManager, cacheDependencyPath); + expect(setOutputSpy).toHaveBeenCalledWith('cache-key', primaryKey); + }); + + it('sets the cache-hit output to true when cache is found', async () => { + restoreCacheSpy.mockResolvedValue(cacheKey); + await restoreCache(packageManager, cacheDependencyPath); + expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true); + }); + + it('sets the cache-hit output to false when cache is not found', async () => { + restoreCacheSpy.mockResolvedValue(undefined); + await restoreCache(packageManager, cacheDependencyPath); + + expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', false); + }); + + it('sets the cache-matched-key output when cache is found', async () => { + (cache.restoreCache as jest.Mock).mockResolvedValue(cacheKey); + + await restoreCache(packageManager, cacheDependencyPath); + + expect(core.setOutput).toHaveBeenCalledWith( + 'cache-matched-key', + cacheKey + ); + }); + + it('sets the cache-matched-key output to undefined when cache is not found', async () => { + (cache.restoreCache as jest.Mock).mockResolvedValue(undefined); + + await restoreCache(packageManager, cacheDependencyPath); + + expect(core.setOutput).toHaveBeenCalledWith( + 'cache-matched-key', + undefined + ); + }); + }); + afterEach(() => { jest.resetAllMocks(); jest.clearAllMocks(); diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts index 17899dfa3..01dfe9093 100644 --- a/__tests__/cache-save.test.ts +++ b/__tests__/cache-save.test.ts @@ -27,6 +27,7 @@ describe('run', () => { let setFailedSpy: jest.SpyInstance; let getStateSpy: jest.SpyInstance; let saveCacheSpy: jest.SpyInstance; + let setOutputSpy: jest.SpyInstance; let getCommandOutputSpy: jest.SpyInstance; let hashFilesSpy: jest.SpyInstance; let existsSpy: jest.SpyInstance; @@ -53,6 +54,8 @@ describe('run', () => { saveCacheSpy = jest.spyOn(cache, 'saveCache'); saveCacheSpy.mockImplementation(() => undefined); + setOutputSpy = jest.spyOn(core, 'setOutput'); + // glob hashFilesSpy = jest.spyOn(glob, 'hashFiles'); hashFilesSpy.mockImplementation((pattern: string) => { @@ -228,6 +231,7 @@ describe('run', () => { expect(infoSpy).toHaveBeenLastCalledWith( `Cache saved with the key: ${npmFileHash}` ); + expect(core.setOutput).toHaveBeenCalledWith('cache-key', npmFileHash); expect(setFailedSpy).not.toHaveBeenCalled(); }); @@ -258,6 +262,7 @@ describe('run', () => { expect(infoSpy).toHaveBeenLastCalledWith( `Cache saved with the key: ${npmFileHash}` ); + expect(core.setOutput).toHaveBeenCalledWith('cache-key', npmFileHash); expect(setFailedSpy).not.toHaveBeenCalled(); }); @@ -288,6 +293,7 @@ describe('run', () => { expect(infoSpy).toHaveBeenLastCalledWith( `Cache saved with the key: ${yarnFileHash}` ); + expect(core.setOutput).toHaveBeenCalledWith('cache-key', yarnFileHash); expect(setFailedSpy).not.toHaveBeenCalled(); }); @@ -297,9 +303,9 @@ describe('run', () => { key === State.CachePackageManager ? inputs['cache'] : key === State.CacheMatchedKey - ? pnpmFileHash + ? 'no-match' : key === State.CachePrimaryKey - ? npmFileHash + ? pnpmFileHash : key === State.CachePaths ? '["/foo/bar"]' : 'not expected' @@ -316,8 +322,9 @@ describe('run', () => { ); expect(saveCacheSpy).toHaveBeenCalled(); expect(infoSpy).toHaveBeenLastCalledWith( - `Cache saved with the key: ${npmFileHash}` + `Cache saved with the key: ${pnpmFileHash}` ); + expect(core.setOutput).toHaveBeenCalledWith('cache-key', pnpmFileHash); expect(setFailedSpy).not.toHaveBeenCalled(); }); diff --git a/action.yml b/action.yml index 99db5869f..24d36704f 100644 --- a/action.yml +++ b/action.yml @@ -30,6 +30,10 @@ inputs: outputs: cache-hit: description: 'A boolean value to indicate if a cache was hit.' + cache-key: + description: 'The key used for the cache.' + cache-matched-key: + description: 'The key used for the cache that resulted in a cache hit.' node-version: description: 'The installed node version.' runs: diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index b3a950ff4..57fbda55b 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -83729,6 +83729,7 @@ const cachePackages = (packageManager) => __awaiter(void 0, void 0, void 0, func return; } core.info(`Cache saved with the key: ${primaryKey}`); + core.setOutput('cache-key', primaryKey); }); run(true); diff --git a/dist/setup/index.js b/dist/setup/index.js index 5d7eb1e5b..65f7f2790 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -93326,6 +93326,7 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, const primaryKey = `${keyPrefix}-${fileHash}`; core.debug(`primary key is ${primaryKey}`); core.saveState(constants_1.State.CachePrimaryKey, primaryKey); + core.setOutput('cache-key', primaryKey); const isManagedByYarnBerry = yield (0, cache_utils_1.repoHasYarnBerryManagedDependencies)(packageManagerInfo, cacheDependencyPath); let cacheKey; if (isManagedByYarnBerry) { @@ -93336,6 +93337,8 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, cacheKey = yield cache.restoreCache(cachePaths, primaryKey); } core.setOutput('cache-hit', Boolean(cacheKey)); + core.setOutput('cache-matched-key', cacheKey); + core.debug(`cache-matched-key is ${cacheKey}`); if (!cacheKey) { core.info(`${packageManager} cache is not found`); return; diff --git a/src/cache-restore.ts b/src/cache-restore.ts index af12ad83c..08eb44020 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -45,6 +45,7 @@ export const restoreCache = async ( core.debug(`primary key is ${primaryKey}`); core.saveState(State.CachePrimaryKey, primaryKey); + core.setOutput('cache-key', primaryKey); const isManagedByYarnBerry = await repoHasYarnBerryManagedDependencies( packageManagerInfo, @@ -61,6 +62,8 @@ export const restoreCache = async ( } core.setOutput('cache-hit', Boolean(cacheKey)); + core.setOutput('cache-matched-key', cacheKey); + core.debug(`cache-matched-key is ${cacheKey}`); if (!cacheKey) { core.info(`${packageManager} cache is not found`); diff --git a/src/cache-save.ts b/src/cache-save.ts index 2522127a3..470b8457a 100644 --- a/src/cache-save.ts +++ b/src/cache-save.ts @@ -66,6 +66,7 @@ const cachePackages = async (packageManager: string) => { } core.info(`Cache saved with the key: ${primaryKey}`); + core.setOutput('cache-key', primaryKey); }; run(true);