Disable cache-cleanup on config-cache hit (#295)

Fixes #19
This commit is contained in:
Daz DeBoer 2024-07-18 22:32:30 -06:00 committed by GitHub
commit 7a630bc41b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 216 additions and 136 deletions

View file

@ -43,6 +43,7 @@ jobs:
uses: ./setup-gradle
with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches
cache-write-only: true # Ensure we start with a clean cache entry
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6
- name: Groovy build with configuration-cache enabled
@ -52,6 +53,7 @@ jobs:
verify-build-groovy:
env:
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy
GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_1
needs: seed-build-groovy
strategy:
fail-fast: false
@ -64,6 +66,47 @@ jobs:
- name: Initialize integ-test
uses: ./.github/actions/init-integ-test
- name: Setup Java to ensure consistency
uses: actions/setup-java@v4
with:
distribution: 'liberica'
java-version: 17
- name: Setup Gradle
uses: ./setup-gradle
with:
cache-read-only: false
cache-cleanup: on-success
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6
- name: Groovy build with configuration-cache enabled
id: execute
working-directory: .github/workflow-samples/groovy-dsl
run: gradle test --configuration-cache
- name: Verify configuration-cache hit
shell: bash
run: |
if [ -e ".github/workflow-samples/groovy-dsl/task-configured.txt" ]; then
echo "Configuration cache was not used - task was configured unexpectedly"
exit 1
fi
# Ensure that cache-cleanup doesn't remove all necessary files
verify-no-cache-cleanup-groovy:
env:
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy
GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_2
needs: verify-build-groovy
strategy:
fail-fast: false
matrix:
os: ${{fromJSON(inputs.runner-os)}}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Initialize integ-test
uses: ./.github/actions/init-integ-test
- name: Setup Java to ensure consistency
uses: actions/setup-java@v4
with:
@ -79,19 +122,19 @@ jobs:
id: execute
working-directory: .github/workflow-samples/groovy-dsl
run: gradle test --configuration-cache
- name: Check that configuration-cache was used
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
if (fs.existsSync('.github/workflow-samples/groovy-dsl/task-configured.txt')) {
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
}
- name: Verify configuration-cache hit
shell: bash
run: |
if [ -e ".github/workflow-samples/groovy-dsl/task-configured.txt" ]; then
echo "Configuration cache was not used - task was configured unexpectedly"
exit 1
fi
# Check that the build can run when no extracted cache entries are restored
gradle-user-home-not-fully-restored:
env:
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-groovy
GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_x
needs: seed-build-groovy
strategy:
fail-fast: false
@ -144,6 +187,7 @@ jobs:
uses: ./setup-gradle
with:
cache-read-only: false # For testing, allow writing cache entries on non-default branches
cache-write-only: true # Ensure we start with a clean cache entry
cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
gradle-version: 8.6
- name: Execute 'help' with configuration-cache enabled
@ -152,7 +196,8 @@ jobs:
modify-build-kotlin:
env:
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin-modified
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin
GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_1
needs: seed-build-kotlin
strategy:
fail-fast: false
@ -183,7 +228,8 @@ jobs:
# Test restore configuration-cache from the third build invocation
verify-build-kotlin:
env:
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin-modified
GRADLE_BUILD_ACTION_CACHE_KEY_JOB: restore-cc-kotlin
GRADLE_BUILD_ACTION_CACHE_KEY_JOB_EXECUTION: ${{github.sha}}_2
needs: modify-build-kotlin
strategy:
fail-fast: false
@ -211,12 +257,10 @@ jobs:
id: execute
working-directory: .github/workflow-samples/kotlin-dsl
run: gradle test --configuration-cache
- name: Check that configuration-cache was used
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
if (fs.existsSync('.github/workflow-samples/kotlin-dsl/task-configured.txt')) {
core.setFailed('Configuration cache was not used - task was configured unexpectedly')
}
- name: Verify configuration-cache hit
shell: bash
run: |
if [ -e ".github/workflow-samples/kotlin-dsl/task-configured.txt" ]; then
echo "Configuration cache was not used - task was configured unexpectedly"
exit 1
fi

View file

@ -8,6 +8,7 @@ export interface BuildResult {
get gradleVersion(): string
get gradleHomeDir(): string
get buildFailed(): boolean
get configCacheHit(): boolean
get buildScanUri(): string
get buildScanFailed(): boolean
}
@ -23,6 +24,10 @@ export class BuildResults {
return this.results.some(result => result.buildFailed)
}
anyConfigCacheHit(): boolean {
return this.results.some(result => result.configCacheHit)
}
uniqueGradleHomes(): string[] {
const allHomes = this.results.map(buildResult => buildResult.gradleHomeDir)
return Array.from(new Set(allHomes))
@ -32,7 +37,9 @@ export class BuildResults {
export function loadBuildResults(): BuildResults {
const results = getUnprocessedResults().map(filePath => {
const content = fs.readFileSync(filePath, 'utf8')
return JSON.parse(content) as BuildResult
const buildResult = JSON.parse(content) as BuildResult
addScanResults(filePath, buildResult)
return buildResult
})
return new BuildResults(results)
}
@ -42,7 +49,7 @@ export function markBuildResultsProcessed(): void {
}
function getUnprocessedResults(): string[] {
const buildResultsDir = path.resolve(process.env['RUNNER_TEMP']!, '.build-results')
const buildResultsDir = path.resolve(process.env['RUNNER_TEMP']!, '.gradle-actions', 'build-results')
if (!fs.existsSync(buildResultsDir)) {
return []
}
@ -57,6 +64,22 @@ function getUnprocessedResults(): string[] {
})
}
function addScanResults(buildResultsFile: string, buildResult: BuildResult): void {
const buildScansDir = path.resolve(process.env['RUNNER_TEMP']!, '.gradle-actions', 'build-scans')
if (!fs.existsSync(buildScansDir)) {
return
}
const buildScanResults = path.resolve(buildScansDir, path.basename(buildResultsFile))
if (fs.existsSync(buildScanResults)) {
const content = fs.readFileSync(buildScanResults, 'utf8')
const scanResults = JSON.parse(content)
Object.assign(buildResult, scanResults)
}
return
}
function isProcessed(resultFile: string): boolean {
const markerFile = `${resultFile}.processed`
return fs.existsSync(markerFile)

View file

@ -19,6 +19,9 @@ export const DEFAULT_CLEANUP_ENABLED_REASON = `[Cache cleanup](https://github.co
export const CLEANUP_DISABLED_DUE_TO_FAILURE =
'[Cache cleanup was disabled due to build failure](https://github.com/gradle/actions/blob/v3/docs/setup-gradle.md#enabling-cache-cleanup). Use `cache-cleanup: always` to override this behavior.'
export const CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT =
'[Cache cleanup was disabled due to configuration-cache reuse](https://github.com/gradle/actions/blob/v3/docs/setup-gradle.md#enabling-cache-cleanup). This is expected.'
/**
* Collects information on what entries were saved and restored during the action.
* This information is used to generate a summary of the cache usage.

View file

@ -1,5 +1,10 @@
import * as core from '@actions/core'
import {CacheListener, EXISTING_GRADLE_HOME, CLEANUP_DISABLED_DUE_TO_FAILURE} from './cache-reporting'
import {
CacheListener,
EXISTING_GRADLE_HOME,
CLEANUP_DISABLED_DUE_TO_FAILURE,
CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT
} from './cache-reporting'
import {GradleUserHomeCache} from './gradle-user-home-cache'
import {CacheCleaner} from './cache-cleaner'
import {DaemonController} from '../daemon-controller'
@ -90,7 +95,10 @@ export async function save(
await daemonController.stopAllDaemons()
if (cacheConfig.isCacheCleanupEnabled()) {
if (cacheConfig.shouldPerformCacheCleanup(buildResults.anyFailed())) {
if (buildResults.anyConfigCacheHit()) {
core.info('Not performing cache-cleanup due to config-cache reuse')
cacheListener.setCacheCleanupDisabled(CLEANUP_DISABLED_DUE_TO_CONFIG_CACHE_HIT)
} else if (cacheConfig.shouldPerformCacheCleanup(buildResults.anyFailed())) {
cacheListener.setCacheCleanupEnabled()
await performCacheCleanup(gradleUserHome)
} else {

View file

@ -1,23 +1,27 @@
import org.gradle.tooling.events.*
import org.gradle.tooling.events.task.*
import org.gradle.internal.operations.*
import org.gradle.initialization.*
import org.gradle.api.internal.tasks.execution.*
import org.gradle.execution.*
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
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 {
settingsEvaluated { settings ->
def projectTracker = gradle.sharedServices.registerIfAbsent("gradle-action-buildResultsRecorder", BuildResultsRecorder, { spec ->
spec.getParameters().getRootProjectName().set(gradle.rootProject.name)
spec.getParameters().getRootProjectDir().set(gradle.rootProject.rootDir.absolutePath)
spec.getParameters().getRootProjectName().set(settings.rootProject.name)
spec.getParameters().getRootProjectDir().set(settings.rootDir.absolutePath)
spec.getParameters().getRequestedTasks().set(gradle.startParameter.taskNames.join(" "))
spec.getParameters().getGradleHomeDir().set(gradle.gradleHomeDir.absolutePath)
spec.getParameters().getInvocationId().set(gradle.ext.invocationId)
})
gradle.services.get(BuildEventsListenerRegistry).onTaskCompletion(projectTracker)
gradle.services.get(BuildEventListenerRegistryInternal).onOperationCompletion(projectTracker)
}
abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder.Params>, OperationCompletionListener, AutoCloseable {
abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder.Params>, BuildOperationListener, AutoCloseable {
private boolean buildFailed = false
private boolean configCacheHit = true
interface Params extends BuildServiceParameters {
Property<String> getRootProjectName()
Property<String> getRootProjectDir()
@ -26,9 +30,19 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
Property<String> getInvocationId()
}
public void onFinish(FinishEvent finishEvent) {
if (finishEvent instanceof TaskFinishEvent && finishEvent.result instanceof TaskFailureResult) {
buildFailed = true
void started(BuildOperationDescriptor buildOperation, OperationStartEvent startEvent) {}
void progress(OperationIdentifier operationIdentifier, OperationProgressEvent progressEvent) {}
void finished(BuildOperationDescriptor buildOperation, OperationFinishEvent finishEvent) {
if (buildOperation.details in EvaluateSettingsBuildOperationType.Details) {
// Got EVALUATE SETTINGS event: not a config-cache hit"
configCacheHit = false
}
if (buildOperation.details in RunRootBuildWorkBuildOperationType.Details) {
if (finishEvent.failure != null) {
buildFailed = true
}
}
}
@ -41,8 +55,7 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
gradleVersion: GradleVersion.current().version,
gradleHomeDir: getParameters().getGradleHomeDir().get(),
buildFailed: buildFailed,
buildScanUri: null,
buildScanFailed: false
configCacheHit: configCacheHit
]
def runnerTempDir = System.getProperty("RUNNER_TEMP") ?: System.getenv("RUNNER_TEMP")
@ -52,7 +65,7 @@ abstract class BuildResultsRecorder implements BuildService<BuildResultsRecorder
}
try {
def buildResultsDir = new File(runnerTempDir, ".build-results")
def buildResultsDir = new File(runnerTempDir, ".gradle-actions/build-results")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, githubActionStep + getParameters().getInvocationId().get() + ".json")
if (!buildResultsFile.exists()) {

View file

@ -13,6 +13,7 @@ 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")
@ -21,59 +22,77 @@ if (isTopLevelBuild) {
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 ->
// By default, use standard mechanisms to capture build results
if (useBuildService) {
captureUsingBuildService(settings, invocationId)
} else {
captureUsingBuildFinished(gradle, invocationId)
}
settings.pluginManager.withPlugin(GE_PLUGIN_ID) {
// Only execute if develocity plugin isn't applied.
if (!settings.extensions.findByName(DEVELOCITY_EXTENSION)) {
captureUsingBuildScanPublished(settings.extensions[GE_EXTENSION].buildScan, settings.rootProject, invocationId)
captureUsingBuildScanPublished(settings.extensions[GE_EXTENSION].buildScan, invocationId, resultsWriter)
}
}
settings.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
captureUsingBuildScanPublished(settings.extensions[DEVELOCITY_EXTENSION].buildScan, settings.rootProject, invocationId)
captureUsingBuildScanPublished(settings.extensions[DEVELOCITY_EXTENSION].buildScan, invocationId, resultsWriter)
}
}
} else if (atLeastGradle3) {
projectsEvaluated { gradle ->
// By default, use 'buildFinished' to capture build results
captureUsingBuildFinished(gradle, invocationId)
captureUsingBuildFinished(gradle, invocationId, resultsWriter)
gradle.rootProject.pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
// Only execute if develocity plugin isn't applied.
if (!gradle.rootProject.extensions.findByName(DEVELOCITY_EXTENSION)) {
captureUsingBuildScanPublished(gradle.rootProject.extensions[BUILD_SCAN_EXTENSION], gradle.rootProject, invocationId)
captureUsingBuildScanPublished(gradle.rootProject.extensions[BUILD_SCAN_EXTENSION], invocationId, resultsWriter)
}
}
gradle.rootProject.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
captureUsingBuildScanPublished(gradle.rootProject.extensions[DEVELOCITY_EXTENSION].buildScan, gradle.rootProject, invocationId)
captureUsingBuildScanPublished(gradle.rootProject.extensions[DEVELOCITY_EXTENSION].buildScan, invocationId, resultsWriter)
}
}
}
}
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'.
def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId) {
void captureUsingBuildScanPublished(buildScanExtension, String invocationId, ResultsWriter resultsWriter) {
buildScanExtension.with {
def buildResults = new BuildResults(invocationId, gradle, rootProject)
buildFinished { result ->
buildResults.setBuildResult(result)
}
buildScanPublished { buildScan ->
buildResults.setBuildScanUri(buildScan.buildScanUri.toASCIIString())
buildResults.writeToResultsFile(true)
def scanResults = [
buildScanUri: buildScan.buildScanUri.toASCIIString(),
buildScanFailed: false
]
resultsWriter.writeToResultsFile("build-scans", invocationId, scanResults)
def githubOutput = System.getenv("GITHUB_OUTPUT")
if (githubOutput) {
@ -85,63 +104,17 @@ def captureUsingBuildScanPublished(buildScanExtension, rootProject, invocationId
}
onError { error ->
buildResults.setBuildScanFailed()
buildResults.writeToResultsFile(true)
def scanResults = [
buildScanUri: null,
buildScanFailed: true
]
resultsWriter.writeToResultsFile("build-scans", invocationId, scanResults)
}
}
}
def captureUsingBuildFinished(gradle, invocationId) {
gradle.buildFinished { result ->
println "Got buildFinished: ${result}"
def buildResults = new BuildResults(invocationId, gradle, gradle.rootProject)
buildResults.setBuildResult(result)
buildResults.writeToResultsFile(false)
}
}
def captureUsingBuildService(settings, invocationId) {
gradle.ext.invocationId = invocationId
apply from: 'gradle-actions.build-result-capture-service.plugin.groovy'
}
class BuildResults {
def invocationId
def buildResults
BuildResults(String invocationId, def gradle, def rootProject) {
this.invocationId = invocationId
buildResults = [
rootProjectName: rootProject.name,
rootProjectDir: rootProject.projectDir.absolutePath,
requestedTasks: gradle.startParameter.taskNames.join(" "),
gradleVersion: GradleVersion.current().version,
gradleHomeDir: gradle.gradleHomeDir.absolutePath,
buildFailed: false,
buildScanUri: null,
buildScanFailed: false
]
}
def setBuildResult(def result) {
try {
// Gradle and old Build Scan/Gradle Enterprise plugins report a single optional failure in the build result
buildResults['buildFailed'] = result.failure != null
} catch (Exception e) {
// Develocity plugin unwraps all build failures and reports them as a mandatory array
buildResults['buildFailed'] = !result.failures.empty
}
}
def setBuildScanUri(def buildScanUrl) {
buildResults['buildScanUri'] = buildScanUrl
}
def setBuildScanFailed() {
buildResults['buildScanFailed'] = true
}
def writeToResultsFile(boolean overwrite) {
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) {
@ -149,19 +122,12 @@ class BuildResults {
}
try {
def buildResultsDir = new File(runnerTempDir, ".build-results")
def buildResultsDir = new File(runnerTempDir, ".gradle-actions/${subDir}")
buildResultsDir.mkdirs()
def buildResultsFile = new File(buildResultsDir, githubActionStep + invocationId + ".json")
// Overwrite any contents written by buildFinished or build service, since this result is a superset.
if (buildResultsFile.exists()) {
if (overwrite) {
buildResultsFile.text = groovy.json.JsonOutput.toJson(buildResults)
}
} else {
buildResultsFile << groovy.json.JsonOutput.toJson(buildResults)
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()}"
}

View file

@ -1,7 +1,6 @@
package com.gradle.gradlebuildaction
import groovy.json.JsonSlurper
import org.gradle.util.GradleVersion
import static org.junit.Assume.assumeTrue
@ -15,7 +14,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, false)
assertResults('help', testGradleVersion, false)
where:
testGradleVersion << ALL_VERSIONS
@ -29,7 +28,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
runAndFail(testGradleVersion.gradleVersion)
then:
assertResults('expectFailure', testGradleVersion, true, false)
assertResults('expectFailure', testGradleVersion, true)
where:
testGradleVersion << ALL_VERSIONS
@ -49,7 +48,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(['help', '--configuration-cache'], testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, false)
assertResults('help', testGradleVersion, false, true)
where:
testGradleVersion << CONFIGURATION_CACHE_VERSIONS
@ -63,7 +62,8 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
assertResults('help', testGradleVersion, false)
assertScanResults()
where:
testGradleVersion << ALL_VERSIONS
@ -77,7 +77,8 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
assertResults('help', testGradleVersion, false)
assertScanResults()
where:
testGradleVersion << ALL_VERSIONS
@ -91,7 +92,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(['help', '--no-scan'], testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, false)
assertResults('help', testGradleVersion, false)
where:
testGradleVersion << ALL_VERSIONS
@ -106,7 +107,8 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
runAndFail(testGradleVersion.gradleVersion)
then:
assertResults('expectFailure', testGradleVersion, true, true)
assertResults('expectFailure', testGradleVersion, true)
assertScanResults()
where:
testGradleVersion << ALL_VERSIONS
@ -120,14 +122,17 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(['help', '--configuration-cache'], testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
assertResults('help', testGradleVersion, false, false)
assertScanResults()
assert buildResultFile.delete()
assert scanResultFile.delete()
when:
run(['help', '--configuration-cache'], testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
assertScanResults()
where:
testGradleVersion << CONFIGURATION_CACHE_VERSIONS
@ -143,7 +148,8 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
runAndFail(testGradleVersion.gradleVersion)
then:
assertResults('expectFailure', testGradleVersion, true, false, true)
assertResults('expectFailure', testGradleVersion, true)
assertScanResults(true)
where:
testGradleVersion << ALL_VERSIONS
@ -204,7 +210,8 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
run(testGradleVersion.gradleVersion)
then:
assertResults('help', testGradleVersion, false, true)
assertResults('help', testGradleVersion, false)
assertScanResults()
where:
testGradleVersion << SETTINGS_PLUGIN_VERSIONS
@ -232,7 +239,7 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
]
}
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean hasBuildScan, boolean scanUploadFailed = false) {
void assertResults(String task, TestGradleVersion testGradleVersion, boolean hasFailure, boolean configCacheHit = false) {
def results = new JsonSlurper().parse(buildResultFile)
assert results['rootProjectName'] == ROOT_PROJECT_NAME
assert results['rootProjectDir'] == testProjectDir.canonicalPath
@ -240,12 +247,17 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assert results['gradleVersion'] == testGradleVersion.gradleVersion.version
assert results['gradleHomeDir'] != null
assert results['buildFailed'] == hasFailure
assert results['buildScanUri'] == (hasBuildScan ? "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}" : null)
assert results['buildScanFailed'] == scanUploadFailed
assert results['configCacheHit'] == configCacheHit
}
void assertScanResults(boolean scanUploadFailed = false) {
def scanResults = new JsonSlurper().parse(scanResultFile)
assert scanResults['buildScanUri'] == (scanUploadFailed ? null : "${mockScansServer.address}s/${PUBLIC_BUILD_SCAN_ID}")
assert scanResults['buildScanFailed'] == scanUploadFailed
}
private File getBuildResultFile() {
def buildResultsDir = new File(testProjectDir, '.build-results')
def buildResultsDir = new File(testProjectDir, '.gradle-actions/build-results')
assert buildResultsDir.directory
assert buildResultsDir.listFiles().size() == 1
def resultsFile = buildResultsDir.listFiles()[0]
@ -253,4 +265,14 @@ class TestBuildResultRecorder extends BaseInitScriptTest {
assert resultsFile.text.count('rootProjectName') == 1
return resultsFile
}
private File getScanResultFile() {
def buildResultsDir = new File(testProjectDir, '.gradle-actions/build-scans')
assert buildResultsDir.directory
assert buildResultsDir.listFiles().size() == 1
def resultsFile = buildResultsDir.listFiles()[0]
assert resultsFile.name.startsWith('github-step-id')
assert resultsFile.text.count('buildScanUri') == 1
return resultsFile
}
}

View file

@ -10,6 +10,7 @@ const successfulHelpBuild: BuildResult = {
gradleVersion: '8.0',
gradleHomeDir: '/opt/gradle',
buildFailed: false,
configCacheHit: false,
buildScanUri: 'https://scans.gradle.com/s/abc123',
buildScanFailed: false
}