Only restore configuration-cache if Gradle Home is fully restored

Fixes #107
This commit is contained in:
Daz DeBoer 2021-10-29 08:44:08 -06:00
parent 079e4844d6
commit 9edc2a11bd
No known key found for this signature in database
GPG key ID: DD6B9F0B06683D5D
4 changed files with 48 additions and 21 deletions

View file

@ -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",

View file

@ -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<void> {
async afterRestore(report: CachingReport): Promise<void> {
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<void> {
const processes: Promise<void>[] = []
private async restoreArtifactBundles(): Promise<boolean> {
const processes: Promise<boolean>[] = []
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<void> {
private async restoreArtifactBundle(bundle: string, artifactPath: string): Promise<boolean> {
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 {

View file

@ -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<void> {
async restore(): Promise<CachingReport> {
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<void> {}
protected async afterRestore(_report: CachingReport): Promise<void> {}
async save(): Promise<void> {
if (!this.cacheOutputExists()) {

View file

@ -13,10 +13,16 @@ export async function restore(buildRootDirectory: string): Promise<void> {
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()
}
})
}