/* * Capture information for each executed Gradle build to display in the job summary. */ import org.gradle.util.GradleVersion def BUILD_SCAN_PLUGIN_ID = "com.gradle.build-scan" def BUILD_SCAN_EXTENSION = "buildScan" def DEVELOCITY_PLUGIN_ID = "com.gradle.develocity" def DEVELOCITY_EXTENSION = "develocity" def GE_PLUGIN_ID = "com.gradle.enterprise" def GE_EXTENSION = "gradleEnterprise" // Only run against root build. Do not run against included builds. def isTopLevelBuild = gradle.getParent() == null if (isTopLevelBuild) { def resultsWriter = new ResultsWriter() def version = GradleVersion.current().baseVersion def atLeastGradle3 = version >= GradleVersion.version("3.0") def atLeastGradle6 = version >= GradleVersion.version("6.0") def invocationId = "-${System.currentTimeMillis()}" if (atLeastGradle6) { // By default, use standard mechanisms to capture build results def useBuildService = version >= GradleVersion.version("6.6") if (useBuildService) { captureUsingBuildService(invocationId) } else { captureUsingBuildFinished(gradle, invocationId, resultsWriter) } // Use the Develocity plugin to also capture build scan links, when available settingsEvaluated { settings -> def captureBuildScanLink = { // Prefer the 'develocity' extension, if available if (settings.extensions.findByName(DEVELOCITY_EXTENSION)) { captureUsingBuildScanPublished(settings.extensions[DEVELOCITY_EXTENSION].buildScan, invocationId, resultsWriter) } else { captureUsingBuildScanPublished(settings.extensions[GE_EXTENSION].buildScan, invocationId, resultsWriter) } } settings.pluginManager.withPlugin(GE_PLUGIN_ID, captureBuildScanLink) settings.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) { // Develocity plugin applies GE plugin: avoid duplicate call if (settings.pluginManager.hasPlugin(GE_PLUGIN_ID)) return captureBuildScanLink() } } } else if (atLeastGradle3) { projectsEvaluated { gradle -> // By default, use 'buildFinished' to capture build results captureUsingBuildFinished(gradle, invocationId, resultsWriter) def captureBuildScanLink = { // Prefer the 'develocity' extension, if available if (gradle.rootProject.extensions.findByName(DEVELOCITY_EXTENSION)) { captureUsingBuildScanPublished(gradle.rootProject.extensions[DEVELOCITY_EXTENSION].buildScan, invocationId, resultsWriter) } else { captureUsingBuildScanPublished(gradle.rootProject.extensions[BUILD_SCAN_EXTENSION], invocationId, resultsWriter) } } gradle.rootProject.pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID, captureBuildScanLink) gradle.rootProject.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) { // Develocity plugin applies Build Scan plugin: avoid duplicate call if (gradle.rootProject.pluginManager.hasPlugin(BUILD_SCAN_PLUGIN_ID)) return captureBuildScanLink() } } } } def captureUsingBuildService(invocationId) { gradle.ext.invocationId = invocationId apply from: 'gradle-actions.build-result-capture-service.plugin.groovy' } void captureUsingBuildFinished(gradle, String invocationId, ResultsWriter resultsWriter) { gradle.buildFinished { result -> println "Got buildFinished: ${result}" def buildResults = [ rootProjectName: rootProject.name, rootProjectDir: rootProject.projectDir.absolutePath, requestedTasks: gradle.startParameter.taskNames.join(" "), gradleVersion: GradleVersion.current().version, gradleHomeDir: gradle.gradleHomeDir.absolutePath, buildFailed: result.failure != null, configCacheHit: false ] resultsWriter.writeToResultsFile("build-results", invocationId, buildResults) } } // The `buildScanPublished` hook allows the capture of the Build Scan URI. // Results captured this way will overwrite any results from 'buildFinished'. void captureUsingBuildScanPublished(buildScanExtension, String invocationId, ResultsWriter resultsWriter) { buildScanExtension.with { buildScanPublished { buildScan -> def scanResults = [ buildScanUri: buildScan.buildScanUri.toASCIIString(), buildScanFailed: false ] resultsWriter.writeToResultsFile("build-scans", invocationId, scanResults) def githubOutput = System.getenv("GITHUB_OUTPUT") if (githubOutput) { new File(githubOutput) << "build-scan-url=${buildScan.buildScanUri}\n" } else { // Retained for compatibility with older GHES versions println("::set-output name=build-scan-url::${buildScan.buildScanUri}") } } onError { error -> def scanResults = [ buildScanUri: null, buildScanFailed: true ] resultsWriter.writeToResultsFile("build-scans", invocationId, scanResults) } } } class ResultsWriter { void writeToResultsFile(String subDir, String invocationId, def content) { def runnerTempDir = System.getProperty("RUNNER_TEMP") ?: System.getenv("RUNNER_TEMP") def githubActionStep = System.getProperty("GITHUB_ACTION") ?: System.getenv("GITHUB_ACTION") if (!runnerTempDir || !githubActionStep) { return } try { def buildResultsDir = new File(runnerTempDir, ".gradle-actions/${subDir}") buildResultsDir.mkdirs() def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json") if (!buildResultsFile.exists()) { buildResultsFile << groovy.json.JsonOutput.toJson(content) } } catch (Exception e) { println "\ngradle action failed to write build-results file. Will continue.\n> ${e.getLocalizedMessage()}" } } }