mirror of
				https://hub.gitmirror.com/https://github.com/gradle/actions.git
				synced 2025-10-28 08:30:02 +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 path from 'path' | ||||
| import {versionIsAtLeast} from './execution/gradle' | ||||
| 
 | ||||
| export interface BuildResult { | ||||
|     get rootProjectName(): string | ||||
| @ -32,6 +33,18 @@ export class BuildResults { | ||||
|         const allHomes = this.results.map(buildResult => buildResult.gradleHomeDir) | ||||
|         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 { | ||||
|  | ||||
| @ -4,6 +4,8 @@ import * as exec from '@actions/exec' | ||||
| import fs from 'fs' | ||||
| import path from 'path' | ||||
| import * as provisioner from '../execution/provision' | ||||
| import {BuildResults} from '../build-results' | ||||
| import {versionIsAtLeast} from '../execution/gradle' | ||||
| 
 | ||||
| export class CacheCleaner { | ||||
|     private readonly gradleUserHome: string | ||||
| @ -21,13 +23,37 @@ export class CacheCleaner { | ||||
|         return timestamp | ||||
|     } | ||||
| 
 | ||||
|     async forceCleanup(): Promise<void> { | ||||
|     async forceCleanup(buildResults: BuildResults): Promise<void> { | ||||
|         const executable = await this.gradleExecutableForCleanup(buildResults) | ||||
|         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
 | ||||
|     async forceCleanupFilesOlderThan(cleanTimestamp: string): Promise<void> { | ||||
|     async forceCleanupFilesOlderThan(cleanTimestamp: string, executable: string): Promise<void> { | ||||
|         // Run a dummy Gradle build to trigger cache cleanup
 | ||||
|         const cleanupProjectDir = path.resolve(this.tmpDir, 'dummy-cleanup-project') | ||||
|         fs.mkdirSync(cleanupProjectDir, {recursive: true}) | ||||
| @ -55,9 +81,6 @@ export class CacheCleaner { | ||||
|         ) | ||||
|         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 () => { | ||||
|             core.info(`Cleaning up caches last used before ${cleanTimestamp}`) | ||||
|             await this.executeCleanupBuild(executable, cleanupProjectDir) | ||||
|  | ||||
| @ -102,7 +102,7 @@ export async function save( | ||||
|             cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT) | ||||
|         } else if (cacheConfig.shouldPerformCacheCleanup(buildResults.anyFailed())) { | ||||
|             cacheListener.setCacheCleanupEnabled() | ||||
|             await performCacheCleanup(gradleUserHome) | ||||
|             await performCacheCleanup(gradleUserHome, buildResults) | ||||
|         } else { | ||||
|             core.info('Not performing cache-cleanup due to build 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']!) | ||||
|     try { | ||||
|         await cacheCleaner.forceCleanup() | ||||
|         await cacheCleaner.forceCleanup(buildResults) | ||||
|     } catch (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.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(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.
 | ||||
|     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(transforms3)).toBe(false) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 daz
						daz