mirror of
				https://github.com/gradle/gradle-build-action.git
				synced 2025-10-31 15:18:57 +08:00 
			
		
		
		
	Report sizes of cache entries
Using the patched version of @actions/cache, we now report the total size of cache entries restored/saved, as well as details of each one.
This commit is contained in:
		| @@ -5,7 +5,7 @@ describe('caching report', () => { | |||||||
|         it('with one requested entry report', async () => { |         it('with one requested entry report', async () => { | ||||||
|             const report = new CacheListener() |             const report = new CacheListener() | ||||||
|             report.entry('foo').markRequested('1', ['2']) |             report.entry('foo').markRequested('1', ['2']) | ||||||
|             report.entry('bar').markRequested('3').markRestored('4') |             report.entry('bar').markRequested('3').markRestored('4', 500) | ||||||
|             expect(report.fullyRestored).toBe(false) |             expect(report.fullyRestored).toBe(false) | ||||||
|         }) |         }) | ||||||
|     }) |     }) | ||||||
| @@ -22,13 +22,13 @@ describe('caching report', () => { | |||||||
|         }) |         }) | ||||||
|         it('with restored entry report', async () => { |         it('with restored entry report', async () => { | ||||||
|             const report = new CacheListener() |             const report = new CacheListener() | ||||||
|             report.entry('bar').markRequested('3').markRestored('4') |             report.entry('bar').markRequested('3').markRestored('4', 300) | ||||||
|             expect(report.fullyRestored).toBe(true) |             expect(report.fullyRestored).toBe(true) | ||||||
|         }) |         }) | ||||||
|         it('with multiple restored entry reportss', async () => { |         it('with multiple restored entry reportss', async () => { | ||||||
|             const report = new CacheListener() |             const report = new CacheListener() | ||||||
|             report.entry('foo').markRestored('4') |             report.entry('foo').markRestored('4', 3300) | ||||||
|             report.entry('bar').markRequested('3').markRestored('4') |             report.entry('bar').markRequested('3').markRestored('4', 333) | ||||||
|             expect(report.fullyRestored).toBe(true) |             expect(report.fullyRestored).toBe(true) | ||||||
|         }) |         }) | ||||||
|     }) |     }) | ||||||
| @@ -64,7 +64,7 @@ describe('caching report', () => { | |||||||
|             const report = new CacheListener() |             const report = new CacheListener() | ||||||
|             const entryReport = report.entry('foo') |             const entryReport = report.entry('foo') | ||||||
|             entryReport.markRequested('1', ['2', '3']) |             entryReport.markRequested('1', ['2', '3']) | ||||||
|             entryReport.markSaved('4') |             entryReport.markSaved('4', 100) | ||||||
|  |  | ||||||
|             const stringRep = report.stringify() |             const stringRep = report.stringify() | ||||||
|             const reportClone: CacheListener = CacheListener.rehydrate(stringRep) |             const reportClone: CacheListener = CacheListener.rehydrate(stringRep) | ||||||
| @@ -85,7 +85,7 @@ describe('caching report', () => { | |||||||
|  |  | ||||||
|             // Check type and call method on rehydrated entry report |             // Check type and call method on rehydrated entry report | ||||||
|             expect(entryClone).toBeInstanceOf(CacheEntryListener) |             expect(entryClone).toBeInstanceOf(CacheEntryListener) | ||||||
|             entryClone.markSaved('4') |             entryClone.markSaved('4', 100) | ||||||
|  |  | ||||||
|             expect(entryClone.requestedKey).toBe('1') |             expect(entryClone.requestedKey).toBe('1') | ||||||
|             expect(entryClone.requestedRestoreKeys).toEqual(['2', '3']) |             expect(entryClone.requestedRestoreKeys).toEqual(['2', '3']) | ||||||
|   | |||||||
| @@ -98,13 +98,15 @@ export class CacheEntryListener { | |||||||
|         return this |         return this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     markRestored(key: string): CacheEntryListener { |     markRestored(key: string, size: number | undefined): CacheEntryListener { | ||||||
|         this.restoredKey = key |         this.restoredKey = key | ||||||
|  |         this.restoredSize = size | ||||||
|         return this |         return this | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     markSaved(key: string): CacheEntryListener { |     markSaved(key: string, size: number | undefined): CacheEntryListener { | ||||||
|         this.savedKey = key |         this.savedKey = key | ||||||
|  |         this.savedSize = size | ||||||
|         return this |         return this | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -149,7 +151,7 @@ export abstract class AbstractCache { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         core.saveState(this.cacheResultStateKey, cacheResult) |         core.saveState(this.cacheResultStateKey, cacheResult) | ||||||
|         entryReport.markRestored(cacheResult) |         entryReport.markRestored(cacheResult.key, cacheResult.size) | ||||||
|         core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult}`) |         core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult}`) | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
| @@ -170,7 +172,7 @@ export abstract class AbstractCache { | |||||||
|         cachePath: string[], |         cachePath: string[], | ||||||
|         cacheKey: string, |         cacheKey: string, | ||||||
|         cacheRestoreKeys: string[] = [] |         cacheRestoreKeys: string[] = [] | ||||||
|     ): Promise<string | undefined> { |     ): Promise<cache.CacheEntry | undefined> { | ||||||
|         try { |         try { | ||||||
|             return await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys) |             return await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys) | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
| @@ -214,18 +216,20 @@ export abstract class AbstractCache { | |||||||
|  |  | ||||||
|         core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`) |         core.info(`Caching ${this.cacheDescription} with cache key: ${cacheKey}`) | ||||||
|         const cachePath = this.getCachePath() |         const cachePath = this.getCachePath() | ||||||
|         await this.saveCache(cachePath, cacheKey) |         const savedEntry = await this.saveCache(cachePath, cacheKey) | ||||||
|  |  | ||||||
|         listener.entry(this.cacheDescription).markSaved(cacheKey) |         if (savedEntry) { | ||||||
|  |             listener.entry(this.cacheDescription).markSaved(savedEntry.key, savedEntry.size) | ||||||
|  |         } | ||||||
|  |  | ||||||
|         return |         return | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected async beforeSave(_listener: CacheListener): Promise<void> {} |     protected async beforeSave(_listener: CacheListener): Promise<void> {} | ||||||
|  |  | ||||||
|     protected async saveCache(cachePath: string[], cacheKey: string): Promise<void> { |     protected async saveCache(cachePath: string[], cacheKey: string): Promise<cache.CacheEntry | undefined> { | ||||||
|         try { |         try { | ||||||
|             await cache.saveCache(cachePath, cacheKey) |             return await cache.saveCache(cachePath, cacheKey) | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|             if (error instanceof cache.ValidationError) { |             if (error instanceof cache.ValidationError) { | ||||||
|                 // Validation errors should fail the build action |                 // Validation errors should fail the build action | ||||||
| @@ -238,6 +242,7 @@ export abstract class AbstractCache { | |||||||
|                 core.warning(String(error)) |                 core.warning(String(error)) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         return undefined | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected debug(message: string): void { |     protected debug(message: string): void { | ||||||
|   | |||||||
| @@ -67,10 +67,10 @@ export class GradleUserHomeCache extends AbstractCache { | |||||||
|         const cacheKey = fs.readFileSync(bundleMetaFile, 'utf-8').trim() |         const cacheKey = fs.readFileSync(bundleMetaFile, 'utf-8').trim() | ||||||
|         listener.markRequested(cacheKey) |         listener.markRequested(cacheKey) | ||||||
|  |  | ||||||
|         const restoredKey = await this.restoreCache([bundlePattern], cacheKey) |         const restoredEntry = await this.restoreCache([bundlePattern], cacheKey) | ||||||
|         if (restoredKey) { |         if (restoredEntry) { | ||||||
|             core.info(`Restored ${bundle} with key ${cacheKey} to ${bundlePattern}`) |             core.info(`Restored ${bundle} with key ${cacheKey} to ${bundlePattern}`) | ||||||
|             listener.markRestored(restoredKey) |             listener.markRestored(restoredEntry.key, restoredEntry.size) | ||||||
|         } else { |         } else { | ||||||
|             core.info(`Did not restore ${bundle} with key ${cacheKey} to ${bundlePattern}`) |             core.info(`Did not restore ${bundle} with key ${cacheKey} to ${bundlePattern}`) | ||||||
|             tryDelete(bundleMetaFile) |             tryDelete(bundleMetaFile) | ||||||
| @@ -154,9 +154,11 @@ export class GradleUserHomeCache extends AbstractCache { | |||||||
|             this.debug(`No change to previously restored ${bundle}. Not caching.`) |             this.debug(`No change to previously restored ${bundle}. Not caching.`) | ||||||
|         } else { |         } else { | ||||||
|             core.info(`Caching ${bundle} with cache key: ${cacheKey}`) |             core.info(`Caching ${bundle} with cache key: ${cacheKey}`) | ||||||
|             await this.saveCache([artifactPath], cacheKey) |             const savedEntry = await this.saveCache([artifactPath], cacheKey) | ||||||
|             this.writeBundleMetaFile(bundleMetaFile, cacheKey) |             if (savedEntry !== undefined) { | ||||||
|             listener.markSaved(cacheKey) |                 this.writeBundleMetaFile(bundleMetaFile, cacheKey) | ||||||
|  |                 listener.markSaved(savedEntry.key, savedEntry.size) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const file of bundleFiles) { |         for (const file of bundleFiles) { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import {GradleUserHomeCache} from './cache-gradle-user-home' | |||||||
| import {ProjectDotGradleCache} from './cache-project-dot-gradle' | import {ProjectDotGradleCache} from './cache-project-dot-gradle' | ||||||
| import * as core from '@actions/core' | import * as core from '@actions/core' | ||||||
| import {isCacheDisabled, isCacheReadOnly} from './cache-utils' | import {isCacheDisabled, isCacheReadOnly} from './cache-utils' | ||||||
| import {CacheListener} from './cache-base' | import {CacheEntryListener, CacheListener} from './cache-base' | ||||||
|  |  | ||||||
| const BUILD_ROOT_DIR = 'BUILD_ROOT_DIR' | const BUILD_ROOT_DIR = 'BUILD_ROOT_DIR' | ||||||
| const CACHE_LISTENER = 'CACHE_LISTENER' | const CACHE_LISTENER = 'CACHE_LISTENER' | ||||||
| @@ -54,11 +54,41 @@ export async function save(): Promise<void> { | |||||||
| } | } | ||||||
|  |  | ||||||
| function logCachingReport(listener: CacheListener): void { | function logCachingReport(listener: CacheListener): void { | ||||||
|     core.info('---------- CACHING REPORT -------------') |     core.info(`---------- Caching Summary ------------- | ||||||
|  | Restored Entries Count: ${getCount(listener.cacheEntries, e => e.restoredSize)} | ||||||
|  |                   Size: ${getSum(listener.cacheEntries, e => e.restoredSize)} | ||||||
|  | Saved Entries    Count: ${getCount(listener.cacheEntries, e => e.savedSize)} | ||||||
|  |                   Size: ${getSum(listener.cacheEntries, e => e.savedSize)}`) | ||||||
|  |  | ||||||
|  |     core.startGroup('Cache Entry details') | ||||||
|     for (const entry of listener.cacheEntries) { |     for (const entry of listener.cacheEntries) { | ||||||
|         core.info(`${entry.entryName} |         core.info(`Entry: ${entry.entryName} | ||||||
|     Requested Key: ${entry.requestedKey ?? ''} |     Requested Key : ${entry.requestedKey ?? ''} | ||||||
|     Restored Key : ${entry.restoredKey ?? ''} |     Restored  Key : ${entry.restoredKey ?? ''} | ||||||
|     Saved Key    : ${entry.savedKey ?? ''}`) |               Size: ${formatSize(entry.restoredSize)} | ||||||
|  |     Saved     Key : ${entry.savedKey ?? ''} | ||||||
|  |               Size: ${formatSize(entry.savedSize)}`) | ||||||
|     } |     } | ||||||
|  |     core.endGroup() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getCount( | ||||||
|  |     cacheEntries: CacheEntryListener[], | ||||||
|  |     predicate: (value: CacheEntryListener) => number | undefined | ||||||
|  | ): number { | ||||||
|  |     return cacheEntries.filter(e => predicate(e) !== undefined).length | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getSum( | ||||||
|  |     cacheEntries: CacheEntryListener[], | ||||||
|  |     predicate: (value: CacheEntryListener) => number | undefined | ||||||
|  | ): string { | ||||||
|  |     return formatSize(cacheEntries.map(e => predicate(e) ?? 0).reduce((p, v) => p + v, 0)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function formatSize(bytes: number | undefined): string { | ||||||
|  |     if (bytes === undefined || bytes === 0) { | ||||||
|  |         return '' | ||||||
|  |     } | ||||||
|  |     return `${Math.round(bytes / (1024 * 1024))} MB (${bytes} B)` | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user