Capture build results when config-cache is enabled

When enabled, the configuration-cache will cause the build to fail when a
`buildFinished` listener is added. Instead, use a BuildService to listen for task
failures and to write the results on build completion.
This commit is contained in:
Daz DeBoer 2022-06-04 22:53:36 -06:00
parent 500607bc35
commit 5203a0b09d
No known key found for this signature in database
GPG key ID: DD6B9F0B06683D5D
5 changed files with 56 additions and 7 deletions

View file

@ -23,13 +23,13 @@ jobs:
- name: Build kotlin-dsl project - name: Build kotlin-dsl project
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl
run: ./gradlew assemble run: ./gradlew assemble
- name: Build kotlin-dsl project - name: Build kotlin-dsl project without build scan
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl
run: ./gradlew check --no-scan run: ./gradlew check --no-scan
- name: Build groovy-dsl project - name: Build groovy-dsl project
working-directory: .github/workflow-samples/groovy-dsl working-directory: .github/workflow-samples/groovy-dsl
run: ./gradlew assemble run: ./gradlew assemble
- name: Build kotlin-dsl project again - name: Build kotlin-dsl project with multiple gradle invocations
working-directory: .github/workflow-samples/kotlin-dsl working-directory: .github/workflow-samples/kotlin-dsl
run: | run: |
./gradlew tasks --no-daemon ./gradlew tasks --no-daemon

View file

@ -172,6 +172,7 @@ export class GradleStateCache {
const initScriptFilenames = [ const initScriptFilenames = [
'build-result-capture.init.gradle', 'build-result-capture.init.gradle',
'build-result-capture-service.plugin.groovy',
'project-root-capture.init.gradle', 'project-root-capture.init.gradle',
'project-root-capture.plugin.groovy' 'project-root-capture.plugin.groovy'
] ]

View file

@ -0,0 +1,44 @@
import org.gradle.tooling.events.*
import org.gradle.tooling.events.task.*
import org.gradle.util.GradleVersion
// Can't use settingsEvaluated since this script is applied inside a settingsEvaluated handler
// But projectsEvaluated is good enough, since the build service won't catch configuration failures anyway
projectsEvaluated {
def projectTracker = gradle.sharedServices.registerIfAbsent("gradle-build-action-buildResultsRecorder", BuildResultsRecorder, { spec ->
spec.getParameters().getRootProject().set(gradle.rootProject.name);
spec.getParameters().getRequestedTasks().set(gradle.startParameter.taskNames.join(" "));
})
gradle.services.get(BuildEventsListenerRegistry).onTaskCompletion(projectTracker)
}
abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder.Params>, OperationCompletionListener, AutoCloseable {
private boolean buildFailed = false
interface Params extends BuildServiceParameters {
Property<String> getRootProject();
Property<String> getRequestedTasks();
}
public void onFinish(FinishEvent finishEvent) {
if (finishEvent instanceof TaskFinishEvent && finishEvent.result instanceof TaskFailureResult) {
buildFailed = true
}
}
@Override
public void close() {
def buildResults = [
rootProject: getParameters().getRootProject().get(),
requestedTasks: getParameters().getRequestedTasks().get(),
gradleVersion: GradleVersion.current().version,
buildFailed: buildFailed,
buildScanUri: null
]
def buildResultsDir = new File(System.getenv("RUNNER_TEMP"), ".build-results")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, System.getenv("GITHUB_ACTION") + System.currentTimeMillis() + ".json")
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
}
}

View file

@ -12,9 +12,12 @@ if (isTopLevelBuild) {
def atLeastGradle6 = version >= GradleVersion.version("6.0") def atLeastGradle6 = version >= GradleVersion.version("6.0")
if (atLeastGradle6) { if (atLeastGradle6) {
def useBuildService = version >= GradleVersion.version("6.6")
settingsEvaluated { settings -> settingsEvaluated { settings ->
if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) { if (settings.pluginManager.hasPlugin("com.gradle.enterprise")) {
captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject.name) captureUsingBuildScanPublished(settings.extensions["gradleEnterprise"].buildScan, settings.rootProject.name)
} else if (useBuildService) {
captureUsingBuildService(settings)
} else { } else {
captureUsingBuildFinished(gradle) captureUsingBuildFinished(gradle)
} }
@ -30,7 +33,6 @@ if (isTopLevelBuild) {
} }
} }
def captureUsingBuildScanPublished(buildScanExtension, rootProjectName) { def captureUsingBuildScanPublished(buildScanExtension, rootProjectName) {
buildScanExtension.with { buildScanExtension.with {
def requestedTasks = gradle.startParameter.taskNames.join(" ") def requestedTasks = gradle.startParameter.taskNames.join(" ")
@ -78,3 +80,7 @@ def captureUsingBuildFinished(gradle) {
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults) buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
} }
} }
def captureUsingBuildService(settings) {
apply from: 'build-result-capture-service.plugin.groovy'
}

View file

@ -1,11 +1,10 @@
package com.gradle.gradlebuildaction package com.gradle.gradlebuildaction
import groovy.json.JsonSlurper import groovy.json.JsonSlurper
import spock.lang.Ignore
import static org.junit.Assume.assumeTrue import static org.junit.Assume.assumeTrue
class TestBuildResultOutput extends BaseInitScriptTest { class TestBuildResultRecorder extends BaseInitScriptTest {
def initScript = 'build-result-capture.init.gradle' def initScript = 'build-result-capture.init.gradle'
def "produces build results file for build with #testGradleVersion"() { def "produces build results file for build with #testGradleVersion"() {
@ -35,7 +34,6 @@ class TestBuildResultOutput extends BaseInitScriptTest {
testGradleVersion << ALL_VERSIONS testGradleVersion << ALL_VERSIONS
} }
@Ignore
def "produces build results file for build with --configuration-cache on #testGradleVersion"() { def "produces build results file for build with --configuration-cache on #testGradleVersion"() {
assumeTrue testGradleVersion.compatibleWithCurrentJvm assumeTrue testGradleVersion.compatibleWithCurrentJvm