mirror of
https://github.com/gradle/gradle-build-action.git
synced 2024-11-22 17:12:51 +00:00
Cache generated-gradle-jars separately from Gradle User Home
Similar to wrapper distributions, these large files are common to many Gradle User Home cache entries. Storing them separately removes this redundancy from the Gradle User Home cache.
This commit is contained in:
parent
e833360307
commit
ac5d8920dd
3 changed files with 119 additions and 5 deletions
2
dist/main/index.js
vendored
2
dist/main/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/post/index.js
vendored
2
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
|
@ -4,11 +4,13 @@ import os from 'os'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as glob from '@actions/glob'
|
import * as glob from '@actions/glob'
|
||||||
import * as cache from '@actions/cache'
|
import * as cache from '@actions/cache'
|
||||||
|
import * as exec from '@actions/exec'
|
||||||
|
|
||||||
import {AbstractCache} from './cache-utils'
|
import {AbstractCache} from './cache-utils'
|
||||||
|
|
||||||
const CACHE_PATH = [
|
const CACHE_PATH = [
|
||||||
'~/.gradle/caches/*', // All directories in 'caches'
|
'~/.gradle/caches/*', // All directories in 'caches'
|
||||||
|
'!~/.gradle/caches/*/generated-gradle-jars', // Exclude generated-gradle-jars
|
||||||
'~/.gradle/notifications/*', // Prevent the re-rendering of first-use message for version
|
'~/.gradle/notifications/*', // Prevent the re-rendering of first-use message for version
|
||||||
'~/.gradle/wrapper/dists/*/*/*.zip.txt' // Only wrapper zips are required : Gradle will expand these on demand
|
'~/.gradle/wrapper/dists/*/*/*.zip.txt' // Only wrapper zips are required : Gradle will expand these on demand
|
||||||
]
|
]
|
||||||
|
@ -20,7 +22,12 @@ export class GradleUserHomeCache extends AbstractCache {
|
||||||
|
|
||||||
async restore(): Promise<void> {
|
async restore(): Promise<void> {
|
||||||
await super.restore()
|
await super.restore()
|
||||||
|
await this.reportCacheEntrySize()
|
||||||
|
await this.restoreWrapperZips()
|
||||||
|
await this.restoreGeneratedJars()
|
||||||
|
}
|
||||||
|
|
||||||
|
private async restoreWrapperZips(): Promise<void> {
|
||||||
const globber = await glob.create(
|
const globber = await glob.create(
|
||||||
'~/.gradle/wrapper/dists/*/*/*.zip.txt'
|
'~/.gradle/wrapper/dists/*/*/*.zip.txt'
|
||||||
)
|
)
|
||||||
|
@ -63,11 +70,70 @@ export class GradleUserHomeCache extends AbstractCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async restoreGeneratedJars(): Promise<void> {
|
||||||
|
const globber = await glob.create(
|
||||||
|
'~/.gradle/caches/*/generated-gradle-jars/*.jar.txt'
|
||||||
|
)
|
||||||
|
const generatedJarMarkers = await globber.glob()
|
||||||
|
|
||||||
|
core.info('Found the following generated jars')
|
||||||
|
for (const jarMarker of generatedJarMarkers) {
|
||||||
|
const generatedJar = jarMarker.substring(
|
||||||
|
0,
|
||||||
|
jarMarker.length - '.txt'.length
|
||||||
|
)
|
||||||
|
core.info(
|
||||||
|
`Jar marker: ${jarMarker}. Looking for jar ${generatedJar}`
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!fs.existsSync(generatedJar)) {
|
||||||
|
// Extract the wrapper URL hash
|
||||||
|
const jarKey = path.basename(generatedJar)
|
||||||
|
const cacheKey = `gradle-generated-jar-${jarKey}`
|
||||||
|
core.info(`Cache key: ${cacheKey}. Cache path: ${generatedJar}`)
|
||||||
|
|
||||||
|
const restoreKey = await cache.restoreCache(
|
||||||
|
[generatedJar],
|
||||||
|
cacheKey
|
||||||
|
)
|
||||||
|
if (restoreKey) {
|
||||||
|
core.info(
|
||||||
|
`Restored generated jar ${cacheKey} from cache to ${generatedJar}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`Did NOT restore generated jar from ${cacheKey} to ${generatedJar}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.info(`Generated jar file already exists: ${generatedJar}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async reportCacheEntrySize(): Promise<void> {
|
||||||
|
const gradleUserHome = path.resolve(os.homedir(), '.gradle')
|
||||||
|
if (!fs.existsSync(gradleUserHome)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
core.info('Gradle User Home cache entry size summary')
|
||||||
|
await exec.exec('du', ['-h', '-c', '-t', '5M'], {
|
||||||
|
cwd: gradleUserHome,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
})
|
||||||
|
core.info('-----------')
|
||||||
|
}
|
||||||
|
|
||||||
async save(): Promise<void> {
|
async save(): Promise<void> {
|
||||||
|
await this.cacheWrapperZips()
|
||||||
|
await this.cacheGeneratedJars()
|
||||||
|
await super.save()
|
||||||
|
}
|
||||||
|
|
||||||
|
private async cacheWrapperZips(): Promise<void> {
|
||||||
const globber = await glob.create('~/.gradle/wrapper/dists/*/*/*.zip')
|
const globber = await glob.create('~/.gradle/wrapper/dists/*/*/*.zip')
|
||||||
const wrapperZips = await globber.glob()
|
const wrapperZips = await globber.glob()
|
||||||
|
|
||||||
core.info('Found the following wrapper zips')
|
|
||||||
for (const wrapperZip of wrapperZips) {
|
for (const wrapperZip of wrapperZips) {
|
||||||
core.info(`Wrapper zip: ${wrapperZip}`)
|
core.info(`Wrapper zip: ${wrapperZip}`)
|
||||||
|
|
||||||
|
@ -91,6 +157,7 @@ export class GradleUserHomeCache extends AbstractCache {
|
||||||
) {
|
) {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
// TODO : Avoid warning for reserve cache error: this is expected
|
||||||
core.warning(error.message)
|
core.warning(error.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,9 +168,56 @@ export class GradleUserHomeCache extends AbstractCache {
|
||||||
`Wrapper marker file already exists: ${wrapperMarkerFile}`
|
`Wrapper marker file already exists: ${wrapperMarkerFile}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO : Should not need to delete. Just exclude from cache path.
|
||||||
|
// Delete the wrapper
|
||||||
|
fs.unlinkSync(wrapperZip)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await super.save()
|
private async cacheGeneratedJars(): Promise<void> {
|
||||||
|
const globber = await glob.create(
|
||||||
|
'~/.gradle/caches/*/generated-gradle-jars/*.jar'
|
||||||
|
)
|
||||||
|
const generatedJars = await globber.glob()
|
||||||
|
|
||||||
|
for (const generatedJar of generatedJars) {
|
||||||
|
core.info(`Generated jar: ${generatedJar}`)
|
||||||
|
|
||||||
|
const generatedJarMarkerFile = `${generatedJar}.txt`
|
||||||
|
|
||||||
|
if (!fs.existsSync(generatedJarMarkerFile)) {
|
||||||
|
// Key by jar file name: this includes Gradle version
|
||||||
|
const jarKey = path.basename(generatedJar)
|
||||||
|
const cacheKey = `gradle-generated-jar-${jarKey}`
|
||||||
|
|
||||||
|
core.info(`Caching generated jar with cache key: ${cacheKey}`)
|
||||||
|
try {
|
||||||
|
await cache.saveCache([generatedJar], 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
|
||||||
|
}
|
||||||
|
// TODO : Avoid warning for reserve cache error: this is expected
|
||||||
|
core.warning(error.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the marker file and delete the original
|
||||||
|
fs.writeFileSync(generatedJarMarkerFile, 'dummy')
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`Wrapper marker file already exists: ${generatedJarMarkerFile}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : Should not need to delete. Just exclude from cache path.
|
||||||
|
// Delete the jar
|
||||||
|
fs.unlinkSync(generatedJar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected cacheOutputExists(): boolean {
|
protected cacheOutputExists(): boolean {
|
||||||
|
|
Loading…
Reference in a new issue