2022-08-26 07:04:11 -06:00
|
|
|
import * as core from '@actions/core'
|
2024-07-22 11:35:12 -06:00
|
|
|
import * as exec from '@actions/exec'
|
|
|
|
|
|
2022-06-12 09:53:04 -06:00
|
|
|
import fs from 'fs'
|
|
|
|
|
import path from 'path'
|
2024-07-22 11:35:12 -06:00
|
|
|
import * as provisioner from '../execution/provision'
|
2022-06-12 09:53:04 -06:00
|
|
|
|
|
|
|
|
export class CacheCleaner {
|
|
|
|
|
private readonly gradleUserHome: string
|
|
|
|
|
private readonly tmpDir: string
|
|
|
|
|
|
|
|
|
|
constructor(gradleUserHome: string, tmpDir: string) {
|
|
|
|
|
this.gradleUserHome = gradleUserHome
|
|
|
|
|
this.tmpDir = tmpDir
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-21 19:03:05 -06:00
|
|
|
async prepare(): Promise<string> {
|
|
|
|
|
// Save the current timestamp
|
|
|
|
|
const timestamp = Date.now().toString()
|
|
|
|
|
core.saveState('clean-timestamp', timestamp)
|
|
|
|
|
return timestamp
|
2022-06-12 09:53:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async forceCleanup(): Promise<void> {
|
2024-03-21 19:03:05 -06:00
|
|
|
const cleanTimestamp = core.getState('clean-timestamp')
|
|
|
|
|
await this.forceCleanupFilesOlderThan(cleanTimestamp)
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 11:35:12 -06:00
|
|
|
// Visible for testing
|
2024-03-21 19:03:05 -06:00
|
|
|
async forceCleanupFilesOlderThan(cleanTimestamp: string): Promise<void> {
|
2022-06-21 08:18:58 -06:00
|
|
|
// Run a dummy Gradle build to trigger cache cleanup
|
2022-06-12 09:53:04 -06:00
|
|
|
const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project')
|
|
|
|
|
fs.mkdirSync(cleanupProjectDir, {recursive: true})
|
|
|
|
|
fs.writeFileSync(
|
|
|
|
|
path.resolve(cleanupProjectDir, 'settings.gradle'),
|
|
|
|
|
'rootProject.name = "dummy-cleanup-project"'
|
|
|
|
|
)
|
2024-03-21 19:03:05 -06:00
|
|
|
fs.writeFileSync(
|
|
|
|
|
path.resolve(cleanupProjectDir, 'init.gradle'),
|
|
|
|
|
`
|
|
|
|
|
beforeSettings { settings ->
|
|
|
|
|
def cleanupTime = ${cleanTimestamp}
|
|
|
|
|
|
|
|
|
|
settings.caches {
|
|
|
|
|
cleanup = Cleanup.ALWAYS
|
|
|
|
|
|
|
|
|
|
releasedWrappers.removeUnusedEntriesOlderThan.set(cleanupTime)
|
|
|
|
|
snapshotWrappers.removeUnusedEntriesOlderThan.set(cleanupTime)
|
|
|
|
|
downloadedResources.removeUnusedEntriesOlderThan.set(cleanupTime)
|
|
|
|
|
createdResources.removeUnusedEntriesOlderThan.set(cleanupTime)
|
|
|
|
|
buildCache.removeUnusedEntriesOlderThan.set(cleanupTime)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`
|
|
|
|
|
)
|
2022-06-12 09:53:04 -06:00
|
|
|
fs.writeFileSync(path.resolve(cleanupProjectDir, 'build.gradle'), 'task("noop") {}')
|
|
|
|
|
|
2024-08-31 11:11:24 -06:00
|
|
|
// Gradle >= 8.9 required for cache cleanup
|
|
|
|
|
const executable = await provisioner.provisionGradleAtLeast('8.9')
|
2024-07-22 11:35:12 -06:00
|
|
|
|
|
|
|
|
await core.group('Executing Gradle to clean up caches', async () => {
|
|
|
|
|
core.info(`Cleaning up caches last used before ${cleanTimestamp}`)
|
2024-08-31 11:11:24 -06:00
|
|
|
await this.executeCleanupBuild(executable, cleanupProjectDir)
|
2024-07-22 11:35:12 -06:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async executeCleanupBuild(executable: string, cleanupProjectDir: string): Promise<void> {
|
|
|
|
|
const args = [
|
2024-06-28 12:39:09 -06:00
|
|
|
'-g',
|
|
|
|
|
this.gradleUserHome,
|
2024-03-21 19:03:05 -06:00
|
|
|
'-I',
|
|
|
|
|
'init.gradle',
|
2024-06-28 13:25:56 -06:00
|
|
|
'--info',
|
2024-06-28 12:39:09 -06:00
|
|
|
'--no-daemon',
|
|
|
|
|
'--no-scan',
|
|
|
|
|
'--build-cache',
|
|
|
|
|
'-DGITHUB_DEPENDENCY_GRAPH_ENABLED=false',
|
|
|
|
|
'noop'
|
2024-07-22 11:35:12 -06:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
const result = await exec.getExecOutput(executable, args, {
|
|
|
|
|
cwd: cleanupProjectDir,
|
|
|
|
|
silent: true
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
core.info(result.stdout)
|
2022-06-12 09:53:04 -06:00
|
|
|
}
|
|
|
|
|
}
|