2021-08-23 02:14:47 +00:00
|
|
|
import path from 'path'
|
|
|
|
import fs from 'fs'
|
|
|
|
import os from 'os'
|
2021-09-11 15:10:44 +00:00
|
|
|
import * as core from '@actions/core'
|
|
|
|
import * as glob from '@actions/glob'
|
2021-09-11 18:08:18 +00:00
|
|
|
import * as exec from '@actions/exec'
|
2021-08-23 02:14:47 +00:00
|
|
|
|
2021-10-30 13:21:27 +00:00
|
|
|
import {AbstractCache, CacheEntryListener, CacheListener} from './cache-base'
|
2021-10-30 13:15:20 +00:00
|
|
|
import {getCacheKeyPrefix, hashFileNames, tryDelete} from './cache-utils'
|
2021-09-12 16:08:34 +00:00
|
|
|
|
2021-10-21 17:11:55 +00:00
|
|
|
const META_FILE_DIR = '.gradle-build-action'
|
2021-11-28 17:19:56 +00:00
|
|
|
const META_FILE = 'cache-metadata.json'
|
2021-10-21 17:11:55 +00:00
|
|
|
|
2021-10-27 22:05:07 +00:00
|
|
|
const INCLUDE_PATHS_PARAMETER = 'gradle-home-cache-includes'
|
|
|
|
const EXCLUDE_PATHS_PARAMETER = 'gradle-home-cache-excludes'
|
|
|
|
const ARTIFACT_BUNDLES_PARAMETER = 'gradle-home-cache-artifact-bundles'
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Represents the result of attempting to load or store a cache bundle entry.
|
|
|
|
* An undefined cacheKey indicates that the operation did not succeed.
|
|
|
|
* The collected results are then used to populate the `cache-metadata.json` file for later use.
|
|
|
|
*/
|
|
|
|
class CacheBundleResult {
|
|
|
|
readonly bundle: string
|
|
|
|
readonly cacheKey: string | undefined
|
|
|
|
|
|
|
|
constructor(bundle: string, cacheKey: string | undefined) {
|
|
|
|
this.bundle = bundle
|
|
|
|
this.cacheKey = cacheKey
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Caches and restores the entire Gradle User Home directory, extracting bundles of common artifacts
|
|
|
|
* for more efficient storage.
|
|
|
|
*/
|
2021-09-06 17:16:08 +00:00
|
|
|
export class GradleUserHomeCache extends AbstractCache {
|
2021-09-28 02:57:47 +00:00
|
|
|
private gradleUserHome: string
|
|
|
|
|
|
|
|
constructor(rootDir: string) {
|
2021-09-06 17:16:08 +00:00
|
|
|
super('gradle', 'Gradle User Home')
|
2021-09-28 02:57:47 +00:00
|
|
|
this.gradleUserHome = this.determineGradleUserHome(rootDir)
|
2021-08-23 02:14:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 03:35:01 +00:00
|
|
|
init(): void {
|
|
|
|
this.debug(`Initializing Gradle User Home with properties and init script: ${this.gradleUserHome}`)
|
|
|
|
initializeGradleUserHome(this.gradleUserHome)
|
2021-11-27 23:07:07 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Restore any artifact bundles after the main Gradle User Home entry is restored.
|
|
|
|
*/
|
2021-10-30 13:21:27 +00:00
|
|
|
async afterRestore(listener: CacheListener): Promise<void> {
|
2021-11-28 17:19:56 +00:00
|
|
|
await this.debugReportGradleUserHomeSize('as restored from cache')
|
2021-10-30 13:21:27 +00:00
|
|
|
await this.restoreArtifactBundles(listener)
|
2021-11-28 17:19:56 +00:00
|
|
|
await this.debugReportGradleUserHomeSize('after restoring common artifacts')
|
2021-09-11 18:08:18 +00:00
|
|
|
}
|
2021-09-11 15:10:44 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Restores any artifacts that were cached separately, based on the information in the `cache-metadata.json` file.
|
|
|
|
* Each artifact bundle is restored in parallel, except when debugging is enabled.
|
|
|
|
*/
|
2021-10-30 13:21:27 +00:00
|
|
|
private async restoreArtifactBundles(listener: CacheListener): Promise<void> {
|
2021-11-28 17:19:56 +00:00
|
|
|
const bundleMetadata = this.loadBundleMetadata()
|
|
|
|
const bundlePatterns = this.getArtifactBundleDefinitions()
|
2021-10-29 16:19:35 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const processes: Promise<CacheBundleResult>[] = []
|
2021-10-29 16:19:35 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
for (const [bundle, cacheKey] of bundleMetadata) {
|
2021-10-30 13:21:27 +00:00
|
|
|
const entryListener = listener.entry(bundle)
|
2021-10-30 12:24:34 +00:00
|
|
|
const bundlePattern = bundlePatterns.get(bundle)
|
|
|
|
|
|
|
|
// Handle case where the 'artifactBundlePatterns' have been changed
|
|
|
|
if (bundlePattern === undefined) {
|
2021-11-28 17:19:56 +00:00
|
|
|
core.info(`Found bundle metadata for ${bundle} but no such bundle defined`)
|
2021-10-30 13:21:27 +00:00
|
|
|
entryListener.markRequested('BUNDLE_NOT_CONFIGURED')
|
2021-10-30 12:24:34 +00:00
|
|
|
} else {
|
2021-11-28 17:19:56 +00:00
|
|
|
const p = this.restoreArtifactBundle(bundle, cacheKey, bundlePattern, entryListener)
|
2021-10-30 12:24:34 +00:00
|
|
|
// Run sequentially when debugging enabled
|
|
|
|
if (this.cacheDebuggingEnabled) {
|
|
|
|
await p
|
|
|
|
}
|
|
|
|
processes.push(p)
|
2021-09-12 20:08:22 +00:00
|
|
|
}
|
2021-09-12 02:56:40 +00:00
|
|
|
}
|
2021-09-12 20:08:22 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const results = await Promise.all(processes)
|
|
|
|
|
|
|
|
this.saveMetadataForCacheResults(results)
|
2021-09-12 02:56:40 +00:00
|
|
|
}
|
|
|
|
|
2021-10-30 12:24:34 +00:00
|
|
|
private async restoreArtifactBundle(
|
|
|
|
bundle: string,
|
2021-11-28 17:19:56 +00:00
|
|
|
cacheKey: string,
|
2021-10-30 12:24:34 +00:00
|
|
|
bundlePattern: string,
|
2021-10-30 13:21:27 +00:00
|
|
|
listener: CacheEntryListener
|
2021-11-28 17:19:56 +00:00
|
|
|
): Promise<CacheBundleResult> {
|
2021-10-30 13:21:27 +00:00
|
|
|
listener.markRequested(cacheKey)
|
2021-10-30 12:24:34 +00:00
|
|
|
|
2021-10-30 18:17:41 +00:00
|
|
|
const restoredEntry = await this.restoreCache([bundlePattern], cacheKey)
|
|
|
|
if (restoredEntry) {
|
2021-10-30 12:24:34 +00:00
|
|
|
core.info(`Restored ${bundle} with key ${cacheKey} to ${bundlePattern}`)
|
2021-10-30 18:17:41 +00:00
|
|
|
listener.markRestored(restoredEntry.key, restoredEntry.size)
|
2021-11-28 17:19:56 +00:00
|
|
|
return new CacheBundleResult(bundle, cacheKey)
|
2021-09-12 02:56:40 +00:00
|
|
|
} else {
|
2021-10-30 12:24:34 +00:00
|
|
|
core.info(`Did not restore ${bundle} with key ${cacheKey} to ${bundlePattern}`)
|
2021-11-28 17:19:56 +00:00
|
|
|
return new CacheBundleResult(bundle, undefined)
|
2021-09-11 18:08:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Save and delete any artifact bundles prior to the main Gradle User Home entry being saved.
|
|
|
|
*/
|
2021-10-30 13:21:27 +00:00
|
|
|
async beforeSave(listener: CacheListener): Promise<void> {
|
2021-11-28 17:19:56 +00:00
|
|
|
await this.debugReportGradleUserHomeSize('before saving common artifacts')
|
2021-10-20 21:01:36 +00:00
|
|
|
this.removeExcludedPaths()
|
2021-10-30 13:21:27 +00:00
|
|
|
await this.saveArtifactBundles(listener)
|
2021-11-28 17:19:56 +00:00
|
|
|
await this.debugReportGradleUserHomeSize(
|
2021-10-20 21:01:36 +00:00
|
|
|
"after saving common artifacts (only 'caches' and 'notifications' will be stored)"
|
2021-10-16 16:15:40 +00:00
|
|
|
)
|
2021-09-11 18:08:18 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Delete any file paths that are excluded by the `gradle-home-cache-excludes` parameter.
|
|
|
|
*/
|
2021-10-20 21:01:36 +00:00
|
|
|
private removeExcludedPaths(): void {
|
2021-10-29 13:34:44 +00:00
|
|
|
const rawPaths: string[] = core.getMultilineInput(EXCLUDE_PATHS_PARAMETER)
|
|
|
|
const resolvedPaths = rawPaths.map(x => path.resolve(this.gradleUserHome, x))
|
2021-10-20 21:01:36 +00:00
|
|
|
|
|
|
|
for (const p of resolvedPaths) {
|
|
|
|
this.debug(`Deleting excluded path: ${p}`)
|
|
|
|
tryDelete(p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Saves any artifacts that are configured to be cached separately, based on the artifact bundle definitions.
|
|
|
|
* These definitions are normally fixed, but can be overridden by the `gradle-home-cache-artifact-bundles` parameter.
|
|
|
|
* Each artifact bundle is saved in parallel, except when debugging is enabled.
|
|
|
|
*/
|
2021-10-30 13:21:27 +00:00
|
|
|
private async saveArtifactBundles(listener: CacheListener): Promise<void> {
|
2021-11-28 17:19:56 +00:00
|
|
|
const bundleMetadata = this.loadBundleMetadata()
|
2021-10-29 16:41:30 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const processes: Promise<CacheBundleResult>[] = []
|
|
|
|
for (const [bundle, pattern] of this.getArtifactBundleDefinitions()) {
|
|
|
|
const entryListener = listener.entry(bundle)
|
|
|
|
const previouslyRestoredKey = bundleMetadata.get(bundle)
|
|
|
|
const p = this.saveArtifactBundle(bundle, pattern, previouslyRestoredKey, entryListener)
|
2021-09-12 20:08:22 +00:00
|
|
|
// Run sequentially when debugging enabled
|
|
|
|
if (this.cacheDebuggingEnabled) {
|
|
|
|
await p
|
|
|
|
}
|
2021-09-12 02:56:40 +00:00
|
|
|
processes.push(p)
|
|
|
|
}
|
2021-09-12 20:08:22 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const results = await Promise.all(processes)
|
|
|
|
|
|
|
|
this.saveMetadataForCacheResults(results)
|
2021-09-12 02:56:40 +00:00
|
|
|
}
|
2021-09-11 15:10:44 +00:00
|
|
|
|
2021-10-30 13:21:27 +00:00
|
|
|
private async saveArtifactBundle(
|
|
|
|
bundle: string,
|
|
|
|
artifactPath: string,
|
2021-11-28 17:19:56 +00:00
|
|
|
previouslyRestoredKey: string | undefined,
|
2021-10-30 13:21:27 +00:00
|
|
|
listener: CacheEntryListener
|
2021-11-28 17:19:56 +00:00
|
|
|
): Promise<CacheBundleResult> {
|
2021-10-16 15:46:17 +00:00
|
|
|
const globber = await glob.create(artifactPath, {
|
|
|
|
implicitDescendants: false,
|
|
|
|
followSymbolicLinks: false
|
|
|
|
})
|
2021-10-15 18:34:38 +00:00
|
|
|
const bundleFiles = await globber.glob()
|
2021-09-12 20:08:22 +00:00
|
|
|
|
2021-09-15 12:36:54 +00:00
|
|
|
// Handle no matching files
|
2021-10-15 18:34:38 +00:00
|
|
|
if (bundleFiles.length === 0) {
|
2021-09-15 12:36:54 +00:00
|
|
|
this.debug(`No files found to cache for ${bundle}`)
|
2021-11-28 17:19:56 +00:00
|
|
|
return new CacheBundleResult(bundle, undefined)
|
2021-09-15 12:36:54 +00:00
|
|
|
}
|
2021-09-11 18:08:18 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const cacheKey = this.createCacheKeyForArtifacts(bundle, bundleFiles)
|
2021-09-15 12:36:54 +00:00
|
|
|
|
|
|
|
if (previouslyRestoredKey === cacheKey) {
|
2021-10-29 13:34:44 +00:00
|
|
|
this.debug(`No change to previously restored ${bundle}. Not caching.`)
|
2021-09-15 12:36:54 +00:00
|
|
|
} else {
|
2021-09-15 21:48:55 +00:00
|
|
|
core.info(`Caching ${bundle} with cache key: ${cacheKey}`)
|
2021-10-30 18:17:41 +00:00
|
|
|
const savedEntry = await this.saveCache([artifactPath], cacheKey)
|
|
|
|
if (savedEntry !== undefined) {
|
|
|
|
listener.markSaved(savedEntry.key, savedEntry.size)
|
|
|
|
}
|
2021-09-11 18:08:18 +00:00
|
|
|
}
|
2021-09-12 02:56:40 +00:00
|
|
|
|
2021-10-15 18:34:38 +00:00
|
|
|
for (const file of bundleFiles) {
|
2021-10-04 21:59:08 +00:00
|
|
|
tryDelete(file)
|
2021-09-15 12:36:54 +00:00
|
|
|
}
|
2021-11-28 17:19:56 +00:00
|
|
|
|
|
|
|
return new CacheBundleResult(bundle, cacheKey)
|
2021-09-15 12:36:54 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
protected createCacheKeyForArtifacts(bundle: string, files: string[]): string {
|
2021-10-16 15:44:35 +00:00
|
|
|
const cacheKeyPrefix = getCacheKeyPrefix()
|
2021-10-29 13:34:44 +00:00
|
|
|
const relativeFiles = files.map(x => path.relative(this.gradleUserHome, x))
|
2021-09-28 03:05:17 +00:00
|
|
|
const key = hashFileNames(relativeFiles)
|
|
|
|
|
2021-10-29 13:34:44 +00:00
|
|
|
this.debug(`Generating cache key for ${bundle} from files: ${relativeFiles}`)
|
2021-10-15 17:11:05 +00:00
|
|
|
|
2021-09-15 21:48:55 +00:00
|
|
|
return `${cacheKeyPrefix}${bundle}-${key}`
|
2021-09-12 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Load information about the previously restored/saved artifact bundles from the 'cache-metadata.json' file.
|
|
|
|
*/
|
|
|
|
private loadBundleMetadata(): Map<string, string> {
|
|
|
|
const bundleMetaFile = path.resolve(this.gradleUserHome, META_FILE_DIR, META_FILE)
|
|
|
|
if (!fs.existsSync(bundleMetaFile)) {
|
|
|
|
return new Map<string, string>()
|
|
|
|
}
|
|
|
|
const filedata = fs.readFileSync(bundleMetaFile, 'utf-8')
|
|
|
|
core.debug(`Loaded bundle metadata: ${filedata}`)
|
|
|
|
return new Map(JSON.parse(filedata))
|
|
|
|
}
|
2021-10-21 17:11:55 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Saves information about the artifact bundle restore/save into the 'cache-metadata.json' file.
|
|
|
|
*/
|
|
|
|
private saveMetadataForCacheResults(results: CacheBundleResult[]): void {
|
|
|
|
const metadata = new Map<string, string>()
|
|
|
|
for (const result of results) {
|
|
|
|
if (result.cacheKey !== undefined) {
|
|
|
|
metadata.set(result.bundle, result.cacheKey)
|
|
|
|
}
|
2021-10-21 17:11:55 +00:00
|
|
|
}
|
2021-11-28 17:19:56 +00:00
|
|
|
const filedata = JSON.stringify(Array.from(metadata))
|
|
|
|
core.debug(`Saving bundle metadata: ${filedata}`)
|
2021-10-21 17:11:55 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
const bundleMetaDir = path.resolve(this.gradleUserHome, META_FILE_DIR)
|
|
|
|
const bundleMetaFile = path.resolve(bundleMetaDir, META_FILE)
|
|
|
|
|
|
|
|
if (!fs.existsSync(bundleMetaDir)) {
|
|
|
|
fs.mkdirSync(bundleMetaDir, {recursive: true})
|
|
|
|
}
|
|
|
|
fs.writeFileSync(bundleMetaFile, filedata, 'utf-8')
|
2021-10-21 17:11:55 +00:00
|
|
|
}
|
|
|
|
|
2021-09-28 02:57:47 +00:00
|
|
|
protected determineGradleUserHome(rootDir: string): string {
|
|
|
|
const customGradleUserHome = process.env['GRADLE_USER_HOME']
|
|
|
|
if (customGradleUserHome) {
|
|
|
|
return path.resolve(rootDir, customGradleUserHome)
|
|
|
|
}
|
|
|
|
|
2021-09-12 16:08:34 +00:00
|
|
|
return path.resolve(os.homedir(), '.gradle')
|
2021-09-11 15:10:44 +00:00
|
|
|
}
|
|
|
|
|
2021-09-06 17:16:08 +00:00
|
|
|
protected cacheOutputExists(): boolean {
|
|
|
|
// Need to check for 'caches' directory to avoid incorrect detection on MacOS agents
|
2021-09-28 02:57:47 +00:00
|
|
|
const dir = path.resolve(this.gradleUserHome, 'caches')
|
2021-09-06 17:16:08 +00:00
|
|
|
return fs.existsSync(dir)
|
2021-08-23 02:14:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Determines the paths within Gradle User Home to cache.
|
|
|
|
* By default, this is the 'caches' and 'notifications' directories,
|
|
|
|
* but this can be overridden by the `gradle-home-cache-includes` parameter.
|
|
|
|
*/
|
2021-09-06 17:16:08 +00:00
|
|
|
protected getCachePath(): string[] {
|
2021-10-29 13:34:44 +00:00
|
|
|
const rawPaths: string[] = core.getMultilineInput(INCLUDE_PATHS_PARAMETER)
|
2021-10-20 15:52:04 +00:00
|
|
|
rawPaths.push(META_FILE_DIR)
|
|
|
|
const resolvedPaths = rawPaths.map(x => this.resolveCachePath(x))
|
|
|
|
this.debug(`Using cache paths: ${resolvedPaths}`)
|
|
|
|
return resolvedPaths
|
|
|
|
}
|
|
|
|
|
|
|
|
private resolveCachePath(rawPath: string): string {
|
|
|
|
if (rawPath.startsWith('!')) {
|
|
|
|
const resolved = this.resolveCachePath(rawPath.substring(1))
|
2021-10-20 21:01:36 +00:00
|
|
|
return `!${resolved}`
|
2021-10-20 15:52:04 +00:00
|
|
|
}
|
|
|
|
return path.resolve(this.gradleUserHome, rawPath)
|
2021-09-28 02:57:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* Return the artifact bundle definitions, which determine which artifacts will be cached
|
|
|
|
* separately from the rest of the Gradle User Home cache entry.
|
|
|
|
* This is normally a fixed set, but can be overridden by the `gradle-home-cache-artifact-bundles` parameter.
|
|
|
|
*/
|
|
|
|
private getArtifactBundleDefinitions(): Map<string, string> {
|
2021-10-29 13:34:44 +00:00
|
|
|
const artifactBundleDefinition = core.getInput(ARTIFACT_BUNDLES_PARAMETER)
|
|
|
|
this.debug(`Using artifact bundle definition: ${artifactBundleDefinition}`)
|
2021-10-15 18:45:15 +00:00
|
|
|
const artifactBundles = JSON.parse(artifactBundleDefinition)
|
2021-10-29 13:34:44 +00:00
|
|
|
return new Map(Array.from(artifactBundles, ([key, value]) => [key, path.resolve(this.gradleUserHome, value)]))
|
2021-08-23 02:14:47 +00:00
|
|
|
}
|
2021-10-15 17:11:05 +00:00
|
|
|
|
2021-11-28 17:19:56 +00:00
|
|
|
/**
|
|
|
|
* When cache debugging is enabled, this method will give a detailed report
|
|
|
|
* of the Gradle User Home contents.
|
|
|
|
*/
|
|
|
|
private async debugReportGradleUserHomeSize(label: string): Promise<void> {
|
2021-10-15 17:11:05 +00:00
|
|
|
if (!this.cacheDebuggingEnabled) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (!fs.existsSync(this.gradleUserHome)) {
|
|
|
|
return
|
|
|
|
}
|
2021-10-29 13:34:44 +00:00
|
|
|
const result = await exec.getExecOutput('du', ['-h', '-c', '-t', '5M'], {
|
|
|
|
cwd: this.gradleUserHome,
|
|
|
|
silent: true,
|
|
|
|
ignoreReturnCode: true
|
|
|
|
})
|
2021-10-15 17:11:05 +00:00
|
|
|
|
2021-10-16 16:15:40 +00:00
|
|
|
core.info(`Gradle User Home (directories >5M): ${label}`)
|
2021-10-15 17:11:05 +00:00
|
|
|
|
|
|
|
core.info(
|
|
|
|
result.stdout
|
|
|
|
.trimEnd()
|
|
|
|
.replace(/\t/g, ' ')
|
|
|
|
.split('\n')
|
|
|
|
.map(it => {
|
|
|
|
return ` ${it}`
|
|
|
|
})
|
|
|
|
.join('\n')
|
|
|
|
)
|
|
|
|
|
|
|
|
core.info('-----------------------')
|
|
|
|
}
|
2021-08-23 02:14:47 +00:00
|
|
|
}
|
2021-11-28 03:35:01 +00:00
|
|
|
|
|
|
|
function initializeGradleUserHome(gradleUserHome: string): void {
|
|
|
|
fs.mkdirSync(gradleUserHome, {recursive: true})
|
|
|
|
|
|
|
|
const propertiesFile = path.resolve(gradleUserHome, 'gradle.properties')
|
|
|
|
fs.writeFileSync(propertiesFile, 'org.gradle.daemon=false')
|
|
|
|
|
|
|
|
const initScript = path.resolve(gradleUserHome, 'init.gradle')
|
|
|
|
fs.writeFileSync(
|
|
|
|
initScript,
|
|
|
|
`
|
|
|
|
import org.gradle.util.GradleVersion
|
|
|
|
|
|
|
|
// Don't run against the included builds (if the main build has any).
|
|
|
|
def isTopLevelBuild = gradle.getParent() == null
|
|
|
|
if (isTopLevelBuild) {
|
|
|
|
def version = GradleVersion.current().baseVersion
|
|
|
|
def atLeastGradle4 = version >= GradleVersion.version("4.0")
|
|
|
|
def atLeastGradle6 = version >= GradleVersion.version("6.0")
|
|
|
|
|
|
|
|
if (atLeastGradle6) {
|
|
|
|
settingsEvaluated { settings ->
|
|
|
|
if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) {
|
|
|
|
registerCallbacks(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (atLeastGradle4) {
|
|
|
|
projectsEvaluated { gradle ->
|
|
|
|
if (gradle.rootProject.pluginManager.hasPlugin("com.gradle.build-scan")) {
|
|
|
|
registerCallbacks(gradle.rootProject.extensions["buildScan"], gradle.rootProject.name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def registerCallbacks(buildScanExtension, rootProjectName) {
|
|
|
|
buildScanExtension.with {
|
2021-11-28 15:03:42 +00:00
|
|
|
def buildOutcome = ""
|
2021-11-28 03:35:01 +00:00
|
|
|
def scanFile = new File("gradle-build-scan.txt")
|
2021-11-28 15:03:42 +00:00
|
|
|
|
|
|
|
buildFinished { result ->
|
|
|
|
buildOutcome = result.failure == null ? " succeeded" : " failed"
|
|
|
|
}
|
|
|
|
|
2021-11-28 03:35:01 +00:00
|
|
|
buildScanPublished { buildScan ->
|
|
|
|
scanFile.text = buildScan.buildScanUri
|
2021-11-28 03:49:10 +00:00
|
|
|
|
2021-11-28 15:03:42 +00:00
|
|
|
// Send commands directly to GitHub Actions via STDOUT.
|
2021-12-08 19:52:37 +00:00
|
|
|
def message = "Build '\${rootProjectName}'\${buildOutcome} - \${buildScan.buildScanUri}"
|
|
|
|
println("::notice ::\${message}")
|
2021-11-28 15:03:42 +00:00
|
|
|
println("::set-output name=build-scan-url::\${buildScan.buildScanUri}")
|
2021-11-28 03:35:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
)
|
|
|
|
}
|