mirror of
				https://github.com/actions/cache.git
				synced 2025-10-31 16:54:01 +00:00 
			
		
		
		
	Allow refreshing cache also with granular save.
This commit is contained in:
		
							parent
							
								
									34ae092a8c
								
							
						
					
					
						commit
						d35302b225
					
				| @ -4,7 +4,7 @@ import nock from "nock"; | ||||
| 
 | ||||
| import { Events, Inputs, RefKey } from "../src/constants"; | ||||
| import { saveImpl } from "../src/saveImpl"; | ||||
| import { StateProvider } from "../src/stateProvider"; | ||||
| import { NullStateProvider, StateProvider } from "../src/stateProvider"; | ||||
| import * as actionUtils from "../src/utils/actionUtils"; | ||||
| import * as testUtils from "../src/utils/testUtils"; | ||||
| 
 | ||||
| @ -471,7 +471,80 @@ test("save with cache hit and refresh-cache will try to delete and re-create ent | ||||
|         .mockImplementationOnce(() => { | ||||
|             return Promise.resolve(cacheId); | ||||
|         }); | ||||
|     await run(new StateProvider()); | ||||
|     await saveImpl(new StateProvider()); | ||||
| 
 | ||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||
|     expect(saveCacheMock).toHaveBeenCalledWith( | ||||
|         [inputPath], | ||||
|         primaryKey, | ||||
|         { | ||||
|             uploadChunkSize: 4000000 | ||||
|         }, | ||||
|         false | ||||
|     ); | ||||
| 
 | ||||
|     expect(logWarningMock).toHaveBeenCalledTimes(0); | ||||
|     expect(infoMock).toHaveBeenCalledTimes(3); | ||||
| 
 | ||||
|     expect(infoMock).toHaveBeenNthCalledWith( | ||||
|         1, | ||||
|         `Cache hit occurred on the primary key ${primaryKey}, attempting to refresh the contents of the cache.` | ||||
|     ); | ||||
|     expect(infoMock).toHaveBeenNthCalledWith( | ||||
|         2, | ||||
|         `Succesfully deleted cache with key: ${primaryKey}` | ||||
|     ); | ||||
|     expect(infoMock).toHaveBeenNthCalledWith( | ||||
|         3, | ||||
|         `Cache saved with key: ${primaryKey}` | ||||
|     ); | ||||
| 
 | ||||
|     expect(failedMock).toHaveBeenCalledTimes(0); | ||||
| }); | ||||
| 
 | ||||
| test("Granular save will use lookup to determine if cache needs to be updated or (not) saved.", async () => { | ||||
|     process.env["GITHUB_REPOSITORY"] = "owner/repo"; | ||||
|     process.env["GITHUB_TOKEN"] = | ||||
|         "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"; | ||||
|     process.env["GITHUB_ACTION"] = "__owner___run-repo"; | ||||
| 
 | ||||
|     const infoMock = jest.spyOn(core, "info"); | ||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||
|     const failedMock = jest.spyOn(core, "setFailed"); | ||||
| 
 | ||||
|     const primaryKey = testUtils.successCacheKey; | ||||
| 
 | ||||
|     const inputPath = "node_modules"; | ||||
|     testUtils.setInput(Inputs.Key, primaryKey); | ||||
|     testUtils.setInput(Inputs.RefreshCache, "true"); | ||||
|     testUtils.setInput(Inputs.Path, inputPath); | ||||
|     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); | ||||
| 
 | ||||
|     const restoreCacheMock = jest | ||||
|         .spyOn(cache, "restoreCache") | ||||
|         .mockImplementation(() => { | ||||
|             return Promise.resolve(primaryKey); | ||||
|         }); | ||||
| 
 | ||||
|     const cacheId = 4; | ||||
|     const saveCacheMock = jest | ||||
|         .spyOn(cache, "saveCache") | ||||
|         .mockImplementationOnce(() => { | ||||
|             return Promise.resolve(cacheId); | ||||
|         }); | ||||
| 
 | ||||
|     await saveImpl(new NullStateProvider()); | ||||
| 
 | ||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||
|     expect(restoreCacheMock).toHaveBeenCalledWith( | ||||
|         [inputPath], | ||||
|         primaryKey, | ||||
|         [], | ||||
|         { | ||||
|             lookupOnly: true | ||||
|         }, | ||||
|         false | ||||
|     ); | ||||
| 
 | ||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||
|     expect(saveCacheMock).toHaveBeenCalledWith( | ||||
| @ -524,7 +597,7 @@ test("save with cache hit and refresh-cache will throw a warning if there's no G | ||||
|         }); | ||||
| 
 | ||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||
|     await run(new StateProvider()); | ||||
|     await saveImpl(new StateProvider()); | ||||
| 
 | ||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||
|     expect(logWarningMock).toHaveBeenCalledWith( | ||||
|  | ||||
| @ -111,6 +111,45 @@ test("save with valid inputs uploads a cache", async () => { | ||||
|     expect(failedMock).toHaveBeenCalledTimes(0); | ||||
| }); | ||||
| 
 | ||||
| test("Granular save with refreshCache is able to save cache", async () => { | ||||
|     process.env["GITHUB_REPOSITORY"] = "owner/repo"; | ||||
|     process.env["GITHUB_TOKEN"] = | ||||
|         "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"; | ||||
|     process.env["GITHUB_ACTION"] = "__owner___run-repo"; | ||||
|     const failedMock = jest.spyOn(core, "setFailed"); | ||||
| 
 | ||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||
| 
 | ||||
|     const inputPath = "node_modules"; | ||||
|     process.env.CACHE_RESTORE_ONLY_MATCHED_KEY = primaryKey; | ||||
|     testUtils.setInput(Inputs.Key, primaryKey); | ||||
|     testUtils.setInput(Inputs.RefreshCache, "true"); | ||||
|     testUtils.setInput(Inputs.Path, inputPath); | ||||
|     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); | ||||
| 
 | ||||
|     const cacheId = 4; | ||||
| 
 | ||||
|     const saveCacheMock = jest | ||||
|         .spyOn(cache, "saveCache") | ||||
|         .mockImplementationOnce(() => { | ||||
|             return Promise.resolve(cacheId); | ||||
|         }); | ||||
| 
 | ||||
|     await saveOnlyRun(); | ||||
| 
 | ||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||
|     expect(saveCacheMock).toHaveBeenCalledWith( | ||||
|         [inputPath], | ||||
|         primaryKey, | ||||
|         { | ||||
|             uploadChunkSize: 4000000 | ||||
|         }, | ||||
|         false | ||||
|     ); | ||||
| 
 | ||||
|     expect(failedMock).toHaveBeenCalledTimes(0); | ||||
| }); | ||||
| 
 | ||||
| test("save failing logs the warning message", async () => { | ||||
|     const warningMock = jest.spyOn(core, "warning"); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										12
									
								
								dist/save-only/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								dist/save-only/index.js
									
									
									
									
										vendored
									
									
								
							| @ -77561,8 +77561,16 @@ function saveImpl(stateProvider) { | ||||
|                 return; | ||||
|             } | ||||
|             const refreshCache = utils.getInputAsBool(constants_1.Inputs.RefreshCache, { required: false }); | ||||
|             // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save (NO-OP in case of SaveOnly action)
 | ||||
|             const restoredKey = stateProvider.getCacheState(); | ||||
|             // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save.
 | ||||
|             let restoredKey = stateProvider.getCacheState(); | ||||
|             if (refreshCache && !restoredKey) { | ||||
|                 // If getCacheState didn't give us a key, we're likely using granular actions. Do a lookup to see if we need to refresh or just do a regular save.
 | ||||
|                 const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { | ||||
|                     required: true | ||||
|                 }); | ||||
|                 const enableCrossOsArchive = utils.getInputAsBool(constants_1.Inputs.EnableCrossOsArchive); | ||||
|                 restoredKey = yield cache.restoreCache(cachePaths, primaryKey, [], { lookupOnly: true }, enableCrossOsArchive); | ||||
|             } | ||||
|             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||
|                 const { GITHUB_TOKEN, GITHUB_REPOSITORY } = process.env || null; | ||||
|                 if (GITHUB_TOKEN && GITHUB_REPOSITORY && refreshCache === true) { | ||||
|  | ||||
							
								
								
									
										12
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							| @ -77561,8 +77561,16 @@ function saveImpl(stateProvider) { | ||||
|                 return; | ||||
|             } | ||||
|             const refreshCache = utils.getInputAsBool(constants_1.Inputs.RefreshCache, { required: false }); | ||||
|             // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save (NO-OP in case of SaveOnly action)
 | ||||
|             const restoredKey = stateProvider.getCacheState(); | ||||
|             // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save.
 | ||||
|             let restoredKey = stateProvider.getCacheState(); | ||||
|             if (refreshCache && !restoredKey) { | ||||
|                 // If getCacheState didn't give us a key, we're likely using granular actions. Do a lookup to see if we need to refresh or just do a regular save.
 | ||||
|                 const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { | ||||
|                     required: true | ||||
|                 }); | ||||
|                 const enableCrossOsArchive = utils.getInputAsBool(constants_1.Inputs.EnableCrossOsArchive); | ||||
|                 restoredKey = yield cache.restoreCache(cachePaths, primaryKey, [], { lookupOnly: true }, enableCrossOsArchive); | ||||
|             } | ||||
|             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||
|                 const { GITHUB_TOKEN, GITHUB_REPOSITORY } = process.env || null; | ||||
|                 if (GITHUB_TOKEN && GITHUB_REPOSITORY && refreshCache === true) { | ||||
|  | ||||
| @ -82,7 +82,6 @@ export async function restoreImpl( | ||||
|         } else { | ||||
|             core.info(`Cache restored from key: ${cacheKey}`); | ||||
|         } | ||||
| 
 | ||||
|         return cacheKey; | ||||
|     } catch (error: unknown) { | ||||
|         core.setFailed((error as Error).message); | ||||
|  | ||||
| @ -48,10 +48,26 @@ export async function saveImpl( | ||||
|             { required: false } | ||||
|         ); | ||||
| 
 | ||||
|         // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save (NO-OP in case of SaveOnly action)
 | ||||
|         // If matched restore key is same as primary key, either try to refresh the cache, or just notify and do not save.
 | ||||
| 
 | ||||
|         const restoredKey = stateProvider.getCacheState(); | ||||
|         let restoredKey = stateProvider.getCacheState(); | ||||
| 
 | ||||
|         if (refreshCache && !restoredKey) { | ||||
|             // If getCacheState didn't give us a key, we're likely using granular actions. Do a lookup to see if we need to refresh or just do a regular save.
 | ||||
|             const cachePaths = utils.getInputAsArray(Inputs.Path, { | ||||
|                 required: true | ||||
|             }); | ||||
|             const enableCrossOsArchive = utils.getInputAsBool( | ||||
|                 Inputs.EnableCrossOsArchive | ||||
|             ); | ||||
|             restoredKey = await cache.restoreCache( | ||||
|                 cachePaths, | ||||
|                 primaryKey, | ||||
|                 [], | ||||
|                 { lookupOnly: true }, | ||||
|                 enableCrossOsArchive | ||||
|             ); | ||||
|         } | ||||
|         if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||
|             const { GITHUB_TOKEN, GITHUB_REPOSITORY } = process.env || null; | ||||
|             if (GITHUB_TOKEN && GITHUB_REPOSITORY && refreshCache === true) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user