diff --git a/packages/cache/__tests__/options.test.ts b/packages/cache/__tests__/options.test.ts index 83d9b227..46e540cb 100644 --- a/packages/cache/__tests__/options.test.ts +++ b/packages/cache/__tests__/options.test.ts @@ -9,6 +9,7 @@ const useAzureSdk = true const downloadConcurrency = 8 const timeoutInMs = 30000 const segmentTimeoutInMs = 3600000 +const dryRun = false const uploadConcurrency = 4 const uploadChunkSize = 32 * 1024 * 1024 @@ -19,7 +20,8 @@ test('getDownloadOptions sets defaults', async () => { useAzureSdk, downloadConcurrency, timeoutInMs, - segmentTimeoutInMs + segmentTimeoutInMs, + dryRun }) }) @@ -28,7 +30,8 @@ test('getDownloadOptions overrides all settings', async () => { useAzureSdk: false, downloadConcurrency: 14, timeoutInMs: 20000, - segmentTimeoutInMs: 3600000 + segmentTimeoutInMs: 3600000, + dryRun: true } const actualOptions = getDownloadOptions(expectedOptions) @@ -61,7 +64,8 @@ test('getDownloadOptions overrides download timeout minutes', async () => { useAzureSdk: false, downloadConcurrency: 14, timeoutInMs: 20000, - segmentTimeoutInMs: 3600000 + segmentTimeoutInMs: 3600000, + dryRun: true } process.env.SEGMENT_DOWNLOAD_TIMEOUT_MINS = '10' const actualOptions = getDownloadOptions(expectedOptions) @@ -72,4 +76,5 @@ test('getDownloadOptions overrides download timeout minutes', async () => { ) expect(actualOptions.timeoutInMs).toEqual(expectedOptions.timeoutInMs) expect(actualOptions.segmentTimeoutInMs).toEqual(600000) + expect(actualOptions.dryRun).toEqual(expectedOptions.dryRun) }) diff --git a/packages/cache/__tests__/restoreCache.test.ts b/packages/cache/__tests__/restoreCache.test.ts index 5318a007..c7499dc1 100644 --- a/packages/cache/__tests__/restoreCache.test.ts +++ b/packages/cache/__tests__/restoreCache.test.ts @@ -276,3 +276,39 @@ test('restore with cache found for restore key', async () => { expect(extractTarMock).toHaveBeenCalledWith(archivePath, compression) expect(getCompressionMock).toHaveBeenCalledTimes(1) }) + +test('restore with dry run', async () => { + const paths = ['node_modules'] + const key = 'node-test' + const options = {dryRun: true} + + const cacheEntry: ArtifactCacheEntry = { + cacheKey: key, + scope: 'refs/heads/main', + archiveLocation: 'www.actionscache.test/download' + } + const getCacheMock = jest.spyOn(cacheHttpClient, 'getCacheEntry') + getCacheMock.mockImplementation(async () => { + return Promise.resolve(cacheEntry) + }) + + const createTempDirectoryMock = jest.spyOn(cacheUtils, 'createTempDirectory') + const downloadCacheMock = jest.spyOn(cacheHttpClient, 'downloadCache') + + const compression = CompressionMethod.Gzip + const getCompressionMock = jest + .spyOn(cacheUtils, 'getCompressionMethod') + .mockReturnValue(Promise.resolve(compression)) + + const cacheKey = await restoreCache(paths, key, undefined, options) + + expect(cacheKey).toBe(key) + expect(getCompressionMock).toHaveBeenCalledTimes(1) + expect(getCacheMock).toHaveBeenCalledWith([key], paths, { + compressionMethod: compression, + enableCrossOsArchive: false + }) + // creating a tempDir and downloading the cache are skipped + expect(createTempDirectoryMock).toHaveBeenCalledTimes(0) + expect(downloadCacheMock).toHaveBeenCalledTimes(0) +}) diff --git a/packages/cache/src/cache.ts b/packages/cache/src/cache.ts index ffa13e78..d464bf96 100644 --- a/packages/cache/src/cache.ts +++ b/packages/cache/src/cache.ts @@ -100,6 +100,11 @@ export async function restoreCache( return undefined } + if (options?.dryRun) { + core.info('Dry run - skipping download') + return cacheEntry.cacheKey + } + archivePath = path.join( await utils.createTempDirectory(), utils.getCacheFileName(compressionMethod) diff --git a/packages/cache/src/options.ts b/packages/cache/src/options.ts index 652899a2..49101572 100644 --- a/packages/cache/src/options.ts +++ b/packages/cache/src/options.ts @@ -53,6 +53,15 @@ export interface DownloadOptions { * @default 3600000 */ segmentTimeoutInMs?: number + + /** + * Weather to skip downloading the cache entry. + * If dryRun is set to true, the restore function will only check if + * a matching cache entry exists and return the cache key if it does. + * + * @default false + */ + dryRun?: boolean } /** @@ -92,7 +101,8 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions { useAzureSdk: true, downloadConcurrency: 8, timeoutInMs: 30000, - segmentTimeoutInMs: 3600000 + segmentTimeoutInMs: 3600000, + dryRun: false } if (copy) { @@ -111,6 +121,10 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions { if (typeof copy.segmentTimeoutInMs === 'number') { result.segmentTimeoutInMs = copy.segmentTimeoutInMs } + + if (typeof copy.dryRun === 'boolean') { + result.dryRun = copy.dryRun + } } const segmentDownloadTimeoutMins = process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS'] @@ -129,6 +143,7 @@ export function getDownloadOptions(copy?: DownloadOptions): DownloadOptions { `Cache segment download timeout mins env var: ${process.env['SEGMENT_DOWNLOAD_TIMEOUT_MINS']}` ) core.debug(`Segment download timeout (ms): ${result.segmentTimeoutInMs}`) + core.debug(`Dry run: ${result.dryRun}`) return result }