From 9edc2a11bd4f338c8d7a6084bd92d3fac4c0ef22 Mon Sep 17 00:00:00 2001 From: Daz DeBoer Date: Fri, 29 Oct 2021 08:44:08 -0600 Subject: [PATCH] Only restore configuration-cache if Gradle Home is fully restored Fixes #107 --- .eslintrc.json | 2 +- src/cache-gradle-user-home.ts | 21 ++++++++++++++------- src/cache-utils.ts | 32 +++++++++++++++++++++++--------- src/caches.ts | 14 ++++++++++---- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index c96c48e..69a30d9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -11,7 +11,7 @@ "eslint-comments/no-use": "off", "import/no-namespace": "off", "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error", + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], "@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}], "@typescript-eslint/no-require-imports": "error", "@typescript-eslint/array-type": "error", diff --git a/src/cache-gradle-user-home.ts b/src/cache-gradle-user-home.ts index e000f6f..4dc6f51 100644 --- a/src/cache-gradle-user-home.ts +++ b/src/cache-gradle-user-home.ts @@ -5,7 +5,7 @@ import * as core from '@actions/core' import * as glob from '@actions/glob' import * as exec from '@actions/exec' -import {AbstractCache, getCacheKeyPrefix, hashFileNames, tryDelete} from './cache-utils' +import {AbstractCache, CachingReport, getCacheKeyPrefix, hashFileNames, tryDelete} from './cache-utils' const META_FILE_DIR = '.gradle-build-action' @@ -21,14 +21,17 @@ export class GradleUserHomeCache extends AbstractCache { this.gradleUserHome = this.determineGradleUserHome(rootDir) } - async afterRestore(): Promise { + async afterRestore(report: CachingReport): Promise { await this.reportGradleUserHomeSize('as restored from cache') - await this.restoreArtifactBundles() + const result = await this.restoreArtifactBundles() await this.reportGradleUserHomeSize('after restoring common artifacts') + if (!result) { + report.fullyRestored = false + } } - private async restoreArtifactBundles(): Promise { - const processes: Promise[] = [] + private async restoreArtifactBundles(): Promise { + const processes: Promise[] = [] for (const [bundle, pattern] of this.getArtifactBundles()) { const p = this.restoreArtifactBundle(bundle, pattern) // Run sequentially when debugging enabled @@ -38,10 +41,12 @@ export class GradleUserHomeCache extends AbstractCache { processes.push(p) } - await Promise.all(processes) + const results = await Promise.all(processes) + // Assume that no-bundles means not-fully-restored + return results.length > 0 && results.every(Boolean) } - private async restoreArtifactBundle(bundle: string, artifactPath: string): Promise { + private async restoreArtifactBundle(bundle: string, artifactPath: string): Promise { const bundleMetaFile = this.getBundleMetaFile(bundle) if (fs.existsSync(bundleMetaFile)) { const cacheKey = fs.readFileSync(bundleMetaFile, 'utf-8').trim() @@ -50,10 +55,12 @@ export class GradleUserHomeCache extends AbstractCache { core.info(`Restored ${bundle} with key ${cacheKey} to ${artifactPath}`) } else { this.debug(`Did not restore ${bundle} with key ${cacheKey} to ${artifactPath}`) + return false } } else { this.debug(`No metafile found to restore ${bundle}: ${bundleMetaFile}`) } + return true } private getBundleMetaFile(name: string): string { diff --git a/src/cache-utils.ts b/src/cache-utils.ts index efc8bc5..dc2d8a4 100644 --- a/src/cache-utils.ts +++ b/src/cache-utils.ts @@ -105,6 +105,14 @@ class CacheKey { } } +export class CachingReport { + fullyRestored: boolean + + constructor(fullyRestored: boolean) { + this.fullyRestored = fullyRestored + } +} + export abstract class AbstractCache { private cacheName: string private cacheDescription: string @@ -121,15 +129,13 @@ export abstract class AbstractCache { this.cacheDebuggingEnabled = isCacheDebuggingEnabled() } - async restore(): Promise { + async restore(): Promise { if (this.cacheOutputExists()) { core.info(`${this.cacheDescription} already exists. Not restoring from cache.`) - return + return new CachingReport(false) } - const cacheKey = generateCacheKey(this.cacheName) - - core.saveState(this.cacheKeyStateKey, cacheKey.key) + const cacheKey = this.prepareCacheKey() this.debug( `Requesting ${this.cacheDescription} with @@ -141,20 +147,28 @@ export abstract class AbstractCache { if (!cacheResult) { core.info(`${this.cacheDescription} cache not found. Will start with empty.`) - return + return new CachingReport(false) } core.saveState(this.cacheResultStateKey, cacheResult) core.info(`Restored ${this.cacheDescription} from cache key: ${cacheResult}`) + const report = new CachingReport(true) try { - await this.afterRestore() + await this.afterRestore(report) } catch (error) { core.warning(`Restore ${this.cacheDescription} failed in 'afterRestore': ${error}`) } - return + return report + } + + prepareCacheKey(): CacheKey { + const cacheKey = generateCacheKey(this.cacheName) + + core.saveState(this.cacheKeyStateKey, cacheKey.key) + return cacheKey } protected async restoreCache( @@ -175,7 +189,7 @@ export abstract class AbstractCache { } } - protected async afterRestore(): Promise {} + protected async afterRestore(_report: CachingReport): Promise {} async save(): Promise { if (!this.cacheOutputExists()) { diff --git a/src/caches.ts b/src/caches.ts index 31b402d..fe43c0f 100644 --- a/src/caches.ts +++ b/src/caches.ts @@ -13,10 +13,16 @@ export async function restore(buildRootDirectory: string): Promise { await core.group('Restore Gradle state from cache', async () => { core.saveState(BUILD_ROOT_DIR, buildRootDirectory) - return Promise.all([ - new GradleUserHomeCache(buildRootDirectory).restore(), - new ProjectDotGradleCache(buildRootDirectory).restore() - ]) + const gradleHomeRestore = await new GradleUserHomeCache(buildRootDirectory).restore() + + const projectDotGradleCache = new ProjectDotGradleCache(buildRootDirectory) + if (gradleHomeRestore.fullyRestored) { + // Only restore the configuration-cache if the Gradle Home is fully restored + await projectDotGradleCache.restore() + } else { + // Otherwise, prepare the cache key for later save() + projectDotGradleCache.prepareCacheKey() + } }) }