Skip to content

Commit

Permalink
Avoid failing build on distributions cache errors
Browse files Browse the repository at this point in the history
- Warn and continue on failure to restore a Gradle distribution from cache
- Warn and continue on failure to save a Gradle distribution to cache
- Extract common functionality for consistent handling of cache failures

Fixes #116
  • Loading branch information
bigdaz committed Nov 5, 2021
1 parent 3812292 commit 4e89983
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 31 deletions.
2 changes: 1 addition & 1 deletion dist/main/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/main/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/post/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/post/index.js.map

Large diffs are not rendered by default.

20 changes: 3 additions & 17 deletions src/cache-base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as core from '@actions/core'
import * as cache from '@actions/cache'
import * as github from '@actions/github'
import {isCacheDebuggingEnabled, getCacheKeyPrefix, hashStrings} from './cache-utils'
import {isCacheDebuggingEnabled, getCacheKeyPrefix, hashStrings, handleCacheFailure} from './cache-utils'

const JOB_CONTEXT_PARAMETER = 'workflow-job-context'

Expand Down Expand Up @@ -176,12 +176,7 @@ export abstract class AbstractCache {
try {
return await cache.restoreCache(cachePath, cacheKey, cacheRestoreKeys)
} catch (error) {
if (error instanceof cache.ValidationError) {
// Validation errors should fail the build action
throw error
}
// Warn about any other error and continue
core.warning(`Failed to restore ${cacheKey}: ${error}`)
handleCacheFailure(error, `Failed to restore ${cacheKey}`)
return undefined
}
}
Expand Down Expand Up @@ -231,16 +226,7 @@ export abstract class AbstractCache {
try {
return await cache.saveCache(cachePath, cacheKey)
} catch (error) {
if (error instanceof cache.ValidationError) {
// Validation errors should fail the build action
throw error
} else if (error instanceof cache.ReserveCacheError) {
// Reserve cache errors are expected if the artifact has been previously cached
this.debug(error.message)
} else {
// Warn about any other error and continue
core.warning(String(error))
}
handleCacheFailure(error, `Failed to save cache entry ${cacheKey}`)
}
return undefined
}
Expand Down
19 changes: 19 additions & 0 deletions src/cache-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as core from '@actions/core'
import * as cache from '@actions/cache'
import * as crypto from 'crypto'
import * as path from 'path'
import * as fs from 'fs'
Expand Down Expand Up @@ -39,6 +40,24 @@ export function hashFileNames(fileNames: string[]): string {
return hashStrings(fileNames.map(x => x.replace(new RegExp(`\\${path.sep}`, 'g'), '/')))
}

export function handleCacheFailure(error: unknown, message: string): void {
if (error instanceof cache.ValidationError) {
// Fail on cache validation errors
throw error
}
if (error instanceof cache.ReserveCacheError) {
// Reserve cache errors are expected if the artifact has been previously cached
if (isCacheDebuggingEnabled()) {
core.info(message)
} else {
core.debug(message)
}
} else {
// Warn on all other errors
core.warning(`${message}: ${error}`)
}
}

/**
* Attempt to delete a file or directory, waiting to allow locks to be released
*/
Expand Down
21 changes: 11 additions & 10 deletions src/provision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as cache from '@actions/cache'
import * as toolCache from '@actions/tool-cache'

import * as gradlew from './gradlew'
import {isCacheDisabled, isCacheReadOnly} from './cache-utils'
import {handleCacheFailure, isCacheDisabled, isCacheReadOnly} from './cache-utils'

const gradleVersionsBaseUrl = 'https://services.gradle.org/versions'

Expand Down Expand Up @@ -109,23 +109,24 @@ async function downloadAndCacheGradleDistribution(versionInfo: GradleVersionInfo
}

const cacheKey = `gradle-${versionInfo.version}`
const restoreKey = await cache.restoreCache([downloadPath], cacheKey)
if (restoreKey) {
core.info(`Restored Gradle distribution ${cacheKey} from cache to ${downloadPath}`)
return downloadPath
try {
const restoreKey = await cache.restoreCache([downloadPath], cacheKey)
if (restoreKey) {
core.info(`Restored Gradle distribution ${cacheKey} from cache to ${downloadPath}`)
return downloadPath
}
} catch (error) {
handleCacheFailure(error, `Restore Gradle distribution ${versionInfo.version} failed`)
}

core.info(`Gradle distribution ${versionInfo.version} not found in cache. Will download.`)
await downloadGradleDistribution(versionInfo, downloadPath)

if (!isCacheReadOnly()) {
try {
await cache.saveCache([downloadPath], cacheKey)
} catch (error) {
// Fail on validation errors or non-errors (the latter to keep Typescript happy)
if (error instanceof cache.ValidationError || !(error instanceof Error)) {
throw error
}
core.warning(error.message)
handleCacheFailure(error, `Save Gradle distribution ${versionInfo.version} failed`)
}
}
return downloadPath
Expand Down

0 comments on commit 4e89983

Please sign in to comment.