mirror of
https://github.com/gradle/actions.git
synced 2025-04-20 09:49:19 +08:00
Attempt to provision best gradle version for cache-cleanup
This commit is contained in:
parent
edf9e3c8c7
commit
c6e631b4a7
@ -1,5 +1,6 @@
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import {versionIsAtLeast} from './execution/gradle'
|
||||||
|
|
||||||
export interface BuildResult {
|
export interface BuildResult {
|
||||||
get rootProjectName(): string
|
get rootProjectName(): string
|
||||||
@ -32,6 +33,18 @@ export class BuildResults {
|
|||||||
const allHomes = this.results.map(buildResult => buildResult.gradleHomeDir)
|
const allHomes = this.results.map(buildResult => buildResult.gradleHomeDir)
|
||||||
return Array.from(new Set(allHomes))
|
return Array.from(new Set(allHomes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
highestGradleVersion(): string | null {
|
||||||
|
if (this.results.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return this.results
|
||||||
|
.map(result => result.gradleVersion)
|
||||||
|
.reduce((maxVersion: string, currentVersion: string) => {
|
||||||
|
if (!maxVersion) return currentVersion
|
||||||
|
return versionIsAtLeast(currentVersion, maxVersion) ? currentVersion : maxVersion
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadBuildResults(): BuildResults {
|
export function loadBuildResults(): BuildResults {
|
||||||
|
@ -4,6 +4,8 @@ import * as exec from '@actions/exec'
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import * as provisioner from '../execution/provision'
|
import * as provisioner from '../execution/provision'
|
||||||
|
import {BuildResults} from '../build-results'
|
||||||
|
import {versionIsAtLeast} from '../execution/gradle'
|
||||||
|
|
||||||
export class CacheCleaner {
|
export class CacheCleaner {
|
||||||
private readonly gradleUserHome: string
|
private readonly gradleUserHome: string
|
||||||
@ -21,13 +23,37 @@ export class CacheCleaner {
|
|||||||
return timestamp
|
return timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceCleanup(): Promise<void> {
|
async forceCleanup(buildResults: BuildResults): Promise<void> {
|
||||||
|
const executable = await this.gradleExecutableForCleanup(buildResults)
|
||||||
const cleanTimestamp = core.getState('clean-timestamp')
|
const cleanTimestamp = core.getState('clean-timestamp')
|
||||||
await this.forceCleanupFilesOlderThan(cleanTimestamp)
|
await this.forceCleanupFilesOlderThan(cleanTimestamp, executable)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to use the newest Gradle version that was used to run a build, at least 8.11.
|
||||||
|
*
|
||||||
|
* This will avoid the need to provision a Gradle version for the cleanup when not necessary.
|
||||||
|
*/
|
||||||
|
private async gradleExecutableForCleanup(buildResults: BuildResults): Promise<string> {
|
||||||
|
const preferredVersion = buildResults.highestGradleVersion()
|
||||||
|
if (preferredVersion && versionIsAtLeast(preferredVersion, '8.11')) {
|
||||||
|
try {
|
||||||
|
return await provisioner.provisionGradleAtLeast(preferredVersion)
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore the case where the preferred version cannot be located in https://services.gradle.org/versions/all.
|
||||||
|
// This can happen for snapshot Gradle versions.
|
||||||
|
core.info(
|
||||||
|
`Failed to provision Gradle ${preferredVersion} for cache cleanup. Falling back to default version.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to the minimum version required for cache-cleanup
|
||||||
|
return await provisioner.provisionGradleAtLeast('8.11')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visible for testing
|
// Visible for testing
|
||||||
async forceCleanupFilesOlderThan(cleanTimestamp: string): Promise<void> {
|
async forceCleanupFilesOlderThan(cleanTimestamp: string, executable: string): Promise<void> {
|
||||||
// Run a dummy Gradle build to trigger cache cleanup
|
// Run a dummy Gradle build to trigger cache cleanup
|
||||||
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
||||||
fs.mkdirSync(cleanupProjectDir, {recursive: true})
|
fs.mkdirSync(cleanupProjectDir, {recursive: true})
|
||||||
@ -55,9 +81,6 @@ export class CacheCleaner {
|
|||||||
)
|
)
|
||||||
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
||||||
|
|
||||||
// TODO: This is ineffective: we should be using the newest version of Gradle that ran a build, or a newer version if it's available on PATH.
|
|
||||||
const executable = await provisioner.provisionGradleAtLeast('8.12')
|
|
||||||
|
|
||||||
await core.group('Executing Gradle to clean up caches', async () => {
|
await core.group('Executing Gradle to clean up caches', async () => {
|
||||||
core.info(`Cleaning up caches last used before ${cleanTimestamp}`)
|
core.info(`Cleaning up caches last used before ${cleanTimestamp}`)
|
||||||
await this.executeCleanupBuild(executable, cleanupProjectDir)
|
await this.executeCleanupBuild(executable, cleanupProjectDir)
|
||||||
|
@ -102,7 +102,7 @@ export async function save(
|
|||||||
cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT)
|
cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT)
|
||||||
} else if (cacheConfig.shouldPerformCacheCleanup(buildResults.anyFailed())) {
|
} else if (cacheConfig.shouldPerformCacheCleanup(buildResults.anyFailed())) {
|
||||||
cacheListener.setCacheCleanupEnabled()
|
cacheListener.setCacheCleanupEnabled()
|
||||||
await performCacheCleanup(gradleUserHome)
|
await performCacheCleanup(gradleUserHome, buildResults)
|
||||||
} else {
|
} else {
|
||||||
core.info('Not performing cache-cleanup due to build failure')
|
core.info('Not performing cache-cleanup due to build failure')
|
||||||
cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_FAILURE)
|
cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_FAILURE)
|
||||||
@ -114,10 +114,10 @@ export async function save(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performCacheCleanup(gradleUserHome: string): Promise<void> {
|
async function performCacheCleanup(gradleUserHome: string, buildResults: BuildResults): Promise<void> {
|
||||||
const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!)
|
const cacheCleaner = new CacheCleaner(gradleUserHome, process.env['RUNNER_TEMP']!)
|
||||||
try {
|
try {
|
||||||
await cacheCleaner.forceCleanup()
|
await cacheCleaner.forceCleanup(buildResults)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
core.warning(`Cache cleanup failed. Will continue. ${String(e)}`)
|
core.warning(`Cache cleanup failed. Will continue. ${String(e)}`)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ test('will cleanup unused dependency jars and build-cache entries', async () =>
|
|||||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||||
expect(fs.readdirSync(buildCacheDir).length).toBe(4) // gc.properties, build-cache-1.lock, and 2 task entries
|
expect(fs.readdirSync(buildCacheDir).length).toBe(4) // gc.properties, build-cache-1.lock, and 2 task entries
|
||||||
|
|
||||||
await cacheCleaner.forceCleanupFilesOlderThan(timestamp)
|
await cacheCleaner.forceCleanupFilesOlderThan(timestamp, 'gradle')
|
||||||
|
|
||||||
expect(fs.existsSync(commonsMath31)).toBe(false)
|
expect(fs.existsSync(commonsMath31)).toBe(false)
|
||||||
expect(fs.existsSync(commonsMath311)).toBe(true)
|
expect(fs.existsSync(commonsMath311)).toBe(true)
|
||||||
@ -68,7 +68,7 @@ test('will cleanup unused gradle versions', async () => {
|
|||||||
// The wrapper won't be removed if it was recently downloaded. Age it.
|
// The wrapper won't be removed if it was recently downloaded. Age it.
|
||||||
setUtimes(wrapper802, new Date(Date.now() - 48 * 60 * 60 * 1000))
|
setUtimes(wrapper802, new Date(Date.now() - 48 * 60 * 60 * 1000))
|
||||||
|
|
||||||
await cacheCleaner.forceCleanupFilesOlderThan(timestamp)
|
await cacheCleaner.forceCleanupFilesOlderThan(timestamp, 'gradle')
|
||||||
|
|
||||||
expect(fs.existsSync(gradle802)).toBe(false)
|
expect(fs.existsSync(gradle802)).toBe(false)
|
||||||
expect(fs.existsSync(transforms3)).toBe(false)
|
expect(fs.existsSync(transforms3)).toBe(false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user