mirror of
				https://github.com/actions/cache.git
				synced 2025-10-31 02:14:19 +08:00 
			
		
		
		
	Provide better errors for unsupported event types (#68)
* Validate event type during restore * PR Feedback * Format * Linting
This commit is contained in:
		
							parent
							
								
									50a2fdee6f
								
							
						
					
					
						commit
						b7d83b4095
					
				| @ -3,7 +3,7 @@ import * as exec from "@actions/exec"; | ||||
| import * as io from "@actions/io"; | ||||
| import * as path from "path"; | ||||
| import * as cacheHttpClient from "../src/cacheHttpClient"; | ||||
| import { Inputs } from "../src/constants"; | ||||
| import { Events, Inputs } from "../src/constants"; | ||||
| import { ArtifactCacheEntry } from "../src/contracts"; | ||||
| import run from "../src/restore"; | ||||
| import * as actionUtils from "../src/utils/actionUtils"; | ||||
| @ -26,12 +26,38 @@ beforeAll(() => { | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => { | ||||
|         const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||
|         return actualUtils.isValidEvent(); | ||||
|     }); | ||||
| 
 | ||||
|     jest.spyOn(actionUtils, "getSupportedEvents").mockImplementation(() => { | ||||
|         const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||
|         return actualUtils.getSupportedEvents(); | ||||
|     }); | ||||
| 
 | ||||
|     jest.spyOn(io, "which").mockImplementation(tool => { | ||||
|         return Promise.resolve(tool); | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| beforeEach(() => { | ||||
|     process.env[Events.Key] = Events.Push; | ||||
| }); | ||||
| 
 | ||||
| afterEach(() => { | ||||
|     testUtils.clearInputs(); | ||||
|     delete process.env[Events.Key]; | ||||
| }); | ||||
| 
 | ||||
| test("restore with invalid event", async () => { | ||||
|     const failedMock = jest.spyOn(core, "setFailed"); | ||||
|     const invalidEvent = "commit_comment"; | ||||
|     process.env[Events.Key] = invalidEvent; | ||||
|     await run(); | ||||
|     expect(failedMock).toHaveBeenCalledWith( | ||||
|         `Event Validation Error: The event type ${invalidEvent} is not supported. Only push, pull_request events are supported at this time.` | ||||
|     ); | ||||
| }); | ||||
| 
 | ||||
| test("restore with no path should fail", async () => { | ||||
| @ -255,6 +281,82 @@ test("restore with cache found", async () => { | ||||
|     expect(failedMock).toHaveBeenCalledTimes(0); | ||||
| }); | ||||
| 
 | ||||
| test("restore with a pull request event and cache found", async () => { | ||||
|     const key = "node-test"; | ||||
|     const cachePath = path.resolve("node_modules"); | ||||
|     testUtils.setInputs({ | ||||
|         path: "node_modules", | ||||
|         key | ||||
|     }); | ||||
| 
 | ||||
|     process.env[Events.Key] = Events.PullRequest; | ||||
| 
 | ||||
|     const infoMock = jest.spyOn(core, "info"); | ||||
|     const warningMock = jest.spyOn(core, "warning"); | ||||
|     const failedMock = jest.spyOn(core, "setFailed"); | ||||
|     const stateMock = jest.spyOn(core, "saveState"); | ||||
| 
 | ||||
|     const cacheEntry: ArtifactCacheEntry = { | ||||
|         cacheKey: key, | ||||
|         scope: "refs/heads/master", | ||||
|         archiveLocation: "https://www.example.com/download" | ||||
|     }; | ||||
|     const getCacheMock = jest.spyOn(cacheHttpClient, "getCacheEntry"); | ||||
|     getCacheMock.mockImplementation(() => { | ||||
|         return Promise.resolve(cacheEntry); | ||||
|     }); | ||||
|     const tempPath = "/foo/bar"; | ||||
| 
 | ||||
|     const createTempDirectoryMock = jest.spyOn( | ||||
|         actionUtils, | ||||
|         "createTempDirectory" | ||||
|     ); | ||||
|     createTempDirectoryMock.mockImplementation(() => { | ||||
|         return Promise.resolve(tempPath); | ||||
|     }); | ||||
| 
 | ||||
|     const archivePath = path.join(tempPath, "cache.tgz"); | ||||
|     const setCacheStateMock = jest.spyOn(actionUtils, "setCacheState"); | ||||
|     const downloadCacheMock = jest.spyOn(cacheHttpClient, "downloadCache"); | ||||
| 
 | ||||
|     const fileSize = 142; | ||||
|     const getArchiveFileSizeMock = jest | ||||
|         .spyOn(actionUtils, "getArchiveFileSize") | ||||
|         .mockReturnValue(fileSize); | ||||
| 
 | ||||
|     const mkdirMock = jest.spyOn(io, "mkdirP"); | ||||
|     const execMock = jest.spyOn(exec, "exec"); | ||||
|     const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); | ||||
| 
 | ||||
|     await run(); | ||||
| 
 | ||||
|     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||
|     expect(getCacheMock).toHaveBeenCalledWith([key]); | ||||
|     expect(setCacheStateMock).toHaveBeenCalledWith(cacheEntry); | ||||
|     expect(createTempDirectoryMock).toHaveBeenCalledTimes(1); | ||||
|     expect(downloadCacheMock).toHaveBeenCalledWith(cacheEntry, archivePath); | ||||
|     expect(getArchiveFileSizeMock).toHaveBeenCalledWith(archivePath); | ||||
|     expect(mkdirMock).toHaveBeenCalledWith(cachePath); | ||||
| 
 | ||||
|     const IS_WINDOWS = process.platform === "win32"; | ||||
|     const tarArchivePath = IS_WINDOWS | ||||
|         ? archivePath.replace(/\\/g, "/") | ||||
|         : archivePath; | ||||
|     const tarCachePath = IS_WINDOWS ? cachePath.replace(/\\/g, "/") : cachePath; | ||||
|     const args = IS_WINDOWS ? ["-xz", "--force-local"] : ["-xz"]; | ||||
|     args.push(...["-f", tarArchivePath, "-C", tarCachePath]); | ||||
| 
 | ||||
|     expect(execMock).toHaveBeenCalledTimes(1); | ||||
|     expect(execMock).toHaveBeenCalledWith(`"tar"`, args); | ||||
| 
 | ||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledWith(true); | ||||
| 
 | ||||
|     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); | ||||
|     expect(warningMock).toHaveBeenCalledTimes(0); | ||||
|     expect(failedMock).toHaveBeenCalledTimes(0); | ||||
| }); | ||||
| 
 | ||||
| test("restore with cache found for restore key", async () => { | ||||
|     const key = "node-test"; | ||||
|     const restoreKey = "node-"; | ||||
|  | ||||
| @ -12,3 +12,9 @@ export enum State { | ||||
|     CacheKey = "CACHE_KEY", | ||||
|     CacheResult = "CACHE_RESULT" | ||||
| } | ||||
| 
 | ||||
| export enum Events { | ||||
|     Key = "GITHUB_EVENT_NAME", | ||||
|     Push = "push", | ||||
|     PullRequest = "pull_request" | ||||
| } | ||||
|  | ||||
| @ -3,12 +3,22 @@ import { exec } from "@actions/exec"; | ||||
| import * as io from "@actions/io"; | ||||
| import * as path from "path"; | ||||
| import * as cacheHttpClient from "./cacheHttpClient"; | ||||
| import { Inputs, State } from "./constants"; | ||||
| import { Events, Inputs, State } from "./constants"; | ||||
| import * as utils from "./utils/actionUtils"; | ||||
| 
 | ||||
| async function run(): Promise<void> { | ||||
|     try { | ||||
|         // Validate inputs, this can cause task failure
 | ||||
|         if (!utils.isValidEvent()) { | ||||
|             core.setFailed( | ||||
|                 `Event Validation Error: The event type ${ | ||||
|                     process.env[Events.Key] | ||||
|                 } is not supported. Only ${utils | ||||
|                     .getSupportedEvents() | ||||
|                     .join(", ")} events are supported at this time.` | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         let cachePath = utils.resolvePath( | ||||
|             core.getInput(Inputs.Path, { required: true }) | ||||
|         ); | ||||
|  | ||||
| @ -4,7 +4,8 @@ import * as fs from "fs"; | ||||
| import * as os from "os"; | ||||
| import * as path from "path"; | ||||
| import * as uuidV4 from "uuid/v4"; | ||||
| import { Outputs, State } from "../constants"; | ||||
| 
 | ||||
| import { Events, Outputs, State } from "../constants"; | ||||
| import { ArtifactCacheEntry } from "../contracts"; | ||||
| 
 | ||||
| // From https://github.com/actions/toolkit/blob/master/packages/tool-cache/src/tool-cache.ts#L23
 | ||||
| @ -83,3 +84,15 @@ export function resolvePath(filePath: string): string { | ||||
| 
 | ||||
|     return path.resolve(filePath); | ||||
| } | ||||
| 
 | ||||
| export function getSupportedEvents(): string[] { | ||||
|     return [Events.Push, Events.PullRequest]; | ||||
| } | ||||
| 
 | ||||
| // Currently the cache token is only authorized for push and pull_request events
 | ||||
| // All other events will fail when reading and saving the cache
 | ||||
| // See GitHub Context https://help.github.com/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context
 | ||||
| export function isValidEvent(): boolean { | ||||
|     const githubEvent = process.env[Events.Key] || ""; | ||||
|     return getSupportedEvents().includes(githubEvent); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Josh Gross
						Josh Gross