Test GitHub Cache
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
		| @@ -18,6 +18,7 @@ export interface Inputs { | ||||
|   outputs: string[]; | ||||
|   cacheFrom: string[]; | ||||
|   cacheTo: string[]; | ||||
|   cacheGithub: boolean; | ||||
|   bake: boolean; | ||||
|   bakeFiles: string[]; | ||||
|   bakeTargets: string[]; | ||||
| @@ -41,6 +42,7 @@ export async function getInputs(): Promise<Inputs> { | ||||
|     outputs: await getInputList('outputs'), | ||||
|     cacheFrom: await getInputList('cache-from'), | ||||
|     cacheTo: await getInputList('cache-to'), | ||||
|     cacheGithub: /true/i.test(core.getInput('cache-github')), | ||||
|     bake: /true/i.test(core.getInput('bake')), | ||||
|     bakeFiles: await getInputList('bake-files'), | ||||
|     bakeTargets: await getInputList('bake-targets') | ||||
|   | ||||
							
								
								
									
										69
									
								
								src/github.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/github.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import md5 from 'md5'; | ||||
| import {Inputs} from './context'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as cache from '@actions/cache'; | ||||
| import * as core from '@actions/core'; | ||||
|  | ||||
| const cachePath = path.join(os.tmpdir(), 'docker-build-push'); | ||||
|  | ||||
| export async function restoreCache(inputs: Inputs): Promise<Inputs> { | ||||
|   if (inputs.bake || !inputs.cacheGithub) { | ||||
|     return inputs; | ||||
|   } | ||||
|  | ||||
|   const primaryKey = `${process.env.RUNNER_OS}-docker-build-push-${md5(inputs.context)}`; | ||||
|   stateHelper.setCachePrimaryKey(primaryKey); | ||||
|  | ||||
|   try { | ||||
|     const cacheKey = await cache.restoreCache([cachePath], primaryKey); | ||||
|  | ||||
|     if (!cacheKey) { | ||||
|       core.info(`GitHub Cache not found for key: ${primaryKey}`); | ||||
|     } else { | ||||
|       inputs.cacheFrom = [`type=local,src=${cachePath}`]; | ||||
|       stateHelper.setCacheMatchedKey(cacheKey); | ||||
|       core.info(`GitHub Cache restored from key: ${cacheKey}`); | ||||
|     } | ||||
|  | ||||
|     inputs.cacheTo = [`type=local,dest=${cachePath}`]; | ||||
|     return inputs; | ||||
|   } catch (err) { | ||||
|     if (err.name === cache.ValidationError.name) { | ||||
|       throw err; | ||||
|     } else { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return inputs; | ||||
| } | ||||
|  | ||||
| export async function saveCache(inputs: Inputs): Promise<void> { | ||||
|   if (inputs.bake || !inputs.cacheGithub) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (!stateHelper.cachePrimaryKey) { | ||||
|     core.warning(`Error retrieving GitHub Cache key from state.`); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (stateHelper.isExactKeyMatch(stateHelper.cachePrimaryKey, stateHelper.cacheMatchedKey)) { | ||||
|     core.info(`GitHub Cache hit occurred on the primary key ${stateHelper.cachePrimaryKey}, not saving cache.`); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     await cache.saveCache([cachePath], stateHelper.cachePrimaryKey); | ||||
|   } catch (err) { | ||||
|     if (err.name === cache.ValidationError.name) { | ||||
|       throw err; | ||||
|     } else if (err.name === cache.ReserveCacheError.name) { | ||||
|       core.info(err.message); | ||||
|     } else { | ||||
|       core.warning(err.message); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,6 +1,8 @@ | ||||
| import * as os from 'os'; | ||||
| import * as buildx from './buildx'; | ||||
| import {Inputs, getInputs, getArgs} from './context'; | ||||
| import * as github from './github'; | ||||
| import * as stateHelper from './state-helper'; | ||||
| import * as core from '@actions/core'; | ||||
| import * as exec from '@actions/exec'; | ||||
|  | ||||
| @@ -16,7 +18,7 @@ async function run(): Promise<void> { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const inputs: Inputs = await getInputs(); | ||||
|     let inputs: Inputs = await getInputs(); | ||||
|     const args: string[] = await getArgs(inputs); | ||||
|  | ||||
|     if (inputs.builder) { | ||||
| @@ -24,6 +26,8 @@ async function run(): Promise<void> { | ||||
|       await buildx.use(inputs.builder); | ||||
|     } | ||||
|  | ||||
|     inputs = await github.restoreCache(inputs); | ||||
|  | ||||
|     core.info(`🏃 Starting build...`); | ||||
|     await exec.exec('docker', args); | ||||
|   } catch (error) { | ||||
| @@ -31,4 +35,13 @@ async function run(): Promise<void> { | ||||
|   } | ||||
| } | ||||
|  | ||||
| run(); | ||||
| async function post(): Promise<void> { | ||||
|   const inputs: Inputs = await getInputs(); | ||||
|   await github.saveCache(inputs); | ||||
| } | ||||
|  | ||||
| if (!stateHelper.IsPost) { | ||||
|   run(); | ||||
| } else { | ||||
|   post(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								src/md5.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/md5.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| declare module 'md5' { | ||||
|   function md5(data: string, options?: {encoding: string; asBytes: boolean; asString: boolean}): string; | ||||
|   export = md5; | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/state-helper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/state-helper.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| import * as core from '@actions/core'; | ||||
|  | ||||
| export const IsPost = !!process.env['STATE_isPost']; | ||||
| export const cachePrimaryKey = process.env['STATE_cachePrimaryKey'] || ''; | ||||
| export const cacheMatchedKey = process.env['STATE_cacheMatchedKey'] || ''; | ||||
|  | ||||
| export function setCachePrimaryKey(cachePrimaryKey: string) { | ||||
|   core.saveState('cachePrimaryKey', cachePrimaryKey); | ||||
| } | ||||
|  | ||||
| export function setCacheMatchedKey(cacheMatchedKey: string) { | ||||
|   core.saveState('cacheMatchedKey', cacheMatchedKey); | ||||
| } | ||||
|  | ||||
| export function isExactKeyMatch(key: string, cacheKey?: string): boolean { | ||||
|   return !!( | ||||
|     cacheKey && | ||||
|     cacheKey.localeCompare(key, undefined, { | ||||
|       sensitivity: 'accent' | ||||
|     }) === 0 | ||||
|   ); | ||||
| } | ||||
|  | ||||
| if (!IsPost) { | ||||
|   core.saveState('isPost', 'true'); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 CrazyMax
					CrazyMax