Skip to content

Commit

Permalink
Enable build-scan link capture
Browse files Browse the repository at this point in the history
If a consumer adds a `captureBuildScanLink` method implementation to the init-script,
this method will be notified with links for all build scans published by the build.
  • Loading branch information
bigdaz committed May 16, 2024
1 parent fcbe09a commit c7067ff
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 17 deletions.
41 changes: 41 additions & 0 deletions src/main/resources/develocity-injection.init.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ if (develocityInjectionEnabled) {
enableDevelocityInjection()
}

def buildScanCaptureEnabled = this.metaClass.respondsTo(this, 'captureBuildScanLink', String)
if (buildScanCaptureEnabled) {
enableBuildScanLinkCapture()
}

void enableDevelocityInjection() {
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin'
Expand Down Expand Up @@ -369,3 +374,39 @@ static boolean isAtLeast(String versionUnderTest, String referenceVersion) {
static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) {
!isAtLeast(versionUnderTest, referenceVersion)
}

void enableBuildScanLinkCapture() {
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'

// Conditionally apply and configure the Develocity plugin
if (GradleVersion.current() < GradleVersion.version('6.0')) {
rootProject {
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
// Only execute if develocity plugin isn't applied.
if (gradle.rootProject.extensions.findByName("develocity")) return
buildScanPublishedAction(buildScan)
}

pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
buildScanPublishedAction(develocity.buildScan)
}
}
} else {
gradle.settingsEvaluated { settings ->
eachDevelocitySettingsExtension(settings) { ext ->
buildScanPublishedAction(ext.buildScan)
}
}
}
}

// Action will only be called if a `captureBuildScanUrl(String)` method is present in this file.
// Add a `void captureBuildScanLink(String) {}` method to respond to buildScanPublished events
void buildScanPublishedAction(def buildScanExtension) {
if (buildScanExtension.metaClass.respondsTo(buildScanExtension, 'buildScanPublished', Action)) {
buildScanExtension.buildScanPublished { scan ->
captureBuildScanLink(scan.buildScanUri.toString())
}
}
}
11 changes: 6 additions & 5 deletions src/test/groovy/com/gradle/BaseInitScriptTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ abstract class BaseInitScriptTest extends Specification {
static final String PUBLIC_BUILD_SCAN_ID = 'i2wepy2gr7ovw'
static final String DEFAULT_SCAN_UPLOAD_TOKEN = 'scan-upload-token'
static final String ROOT_PROJECT_NAME = 'test-init-script'
static final String INIT_SCRIPT_SOURCE = 'src/main/resources/develocity-injection.init.gradle'
boolean failScanUpload = false

File settingsFile
File buildFile

def initScript = 'src/main/resources/develocity-injection.init.gradle'
File initScriptFile

boolean allowDevelocityDeprecationWarning = false

Expand Down Expand Up @@ -115,6 +115,9 @@ abstract class BaseInitScriptTest extends Specification {
}

def setup() {
initScriptFile = new File(testProjectDir, 'develocity-injection.init.gradle')
initScriptFile.text = new File(INIT_SCRIPT_SOURCE).text

settingsFile = new File(testProjectDir, 'settings.gradle')
buildFile = new File(testProjectDir, 'build.gradle')

Expand Down Expand Up @@ -188,7 +191,7 @@ abstract class BaseInitScriptTest extends Specification {
}

GradleRunner createRunner(List<String> args, GradleVersion gradleVersion = GradleVersion.current(), Map<String, String> envVars = [:]) {
args << '-I' << new File(initScript).absolutePath
args << '-I' << initScriptFile.absolutePath

def runner = ((DefaultGradleRunner) GradleRunner.create())
.withGradleVersion(gradleVersion.version)
Expand Down Expand Up @@ -277,7 +280,5 @@ abstract class BaseInitScriptTest extends Specification {
String toString() {
return "Gradle " + gradleVersion.version
}

}

}
84 changes: 84 additions & 0 deletions src/test/groovy/com/gradle/TestBuildScanCapture.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.gradle

import org.gradle.testkit.runner.BuildResult
import spock.lang.Requires

class TestBuildScanCapture extends BaseInitScriptTest {

@Requires({data.testGradleVersion.compatibleWithCurrentJvm})
def "does not capture build scan url when init-script not enabled"() {
given:
captureBuildScanUrls()

when:
def result = run(['help'], testGradleVersion.gradleVersion, [:])

then:
buildScanUrlIsNotCaptured(result)

where:
testGradleVersion << ALL_VERSIONS
}

@Requires({data.testGradleVersion.compatibleWithCurrentJvm})
def "can capture build scan url with develocity injection"() {
given:
captureBuildScanUrls()

when:
def config = TestDevelocityInjection.createTestConfig(mockScansServer.address, DEVELOCITY_PLUGIN_VERSION)
def result = run(['help'], testGradleVersion.gradleVersion, config.envVars)

then:
buildScanUrlIsCaptured(result)

where:
testGradleVersion << ALL_VERSIONS
}

@Requires({data.testGradleVersion.compatibleWithCurrentJvm})
def "can capture build scan url without develocity injection"() {
given:
captureBuildScanUrls()
declareDevelocityPluginApplication(testGradleVersion.gradleVersion)

when:
def config = new MinimalTestConfig()
def result = run(['help'], testGradleVersion.gradleVersion, config.envVars)

then:
buildScanUrlIsCaptured(result)

where:
testGradleVersion << ALL_VERSIONS
}

void buildScanUrlIsCaptured(BuildResult result) {
def message = "BUILD_SCAN_URL='${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID'"
assert result.output.contains(message)
assert 1 == result.output.count(message)
}

void buildScanUrlIsNotCaptured(BuildResult result) {
def message = "BUILD_SCAN_URL='${mockScansServer.address}s/$PUBLIC_BUILD_SCAN_ID'"
assert !result.output.contains(message)
}

void captureBuildScanUrls() {
initScriptFile << '''
def captureBuildScanUrl(String buildScanUrl) {
println "BUILD_SCAN_URL='${buildScanUrl}'"
}
'''
}

static class MinimalTestConfig {
Map<String, String> getEnvVars() {
Map<String, String> envVars = [
DEVELOCITY_INJECTION_INIT_SCRIPT_NAME : "develocity-injection.init.gradle",
]
return envVars
}
}

}
29 changes: 17 additions & 12 deletions src/test/groovy/com/gradle/TestDevelocityInjection.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -407,16 +407,20 @@ class TestDevelocityInjection extends BaseInitScriptTest {
assert 1 == result.output.count(enforceUrl)
}

private BuildResult run(TestGradleVersion testGradleVersion, TestConfig config, List<String> args = ["help"]) {
private BuildResult run(TestGradleVersion testGradleVersion, DvInjectionTestConfig config, List<String> args = ["help"]) {
return run(args, testGradleVersion.gradleVersion, config.envVars)
}

private TestConfig testConfig(String develocityPluginVersion = DEVELOCITY_PLUGIN_VERSION) {
new TestConfig(develocityPluginVersion)
DvInjectionTestConfig testConfig(String develocityPluginVersion = DEVELOCITY_PLUGIN_VERSION) {
createTestConfig(mockScansServer.address, develocityPluginVersion)
}

class TestConfig {
String serverUrl = mockScansServer.address.toString()
static DvInjectionTestConfig createTestConfig(URI serverAddress, String develocityPluginVersion = DEVELOCITY_PLUGIN_VERSION) {
new DvInjectionTestConfig(serverAddress, develocityPluginVersion.toString())
}

static class DvInjectionTestConfig {
String serverUrl
boolean enforceUrl = false
String ccudPluginVersion = null
String pluginRepositoryUrl = null
Expand All @@ -425,38 +429,39 @@ class TestDevelocityInjection extends BaseInitScriptTest {
boolean captureFileFingerprints = false
String develocityPluginVersion

TestConfig(String develocityPluginVersion) {
DvInjectionTestConfig(URI serverAddress, String develocityPluginVersion) {
this.serverUrl = serverAddress.toString()
this.develocityPluginVersion = develocityPluginVersion
}

TestConfig withCCUDPlugin(String version = CCUD_PLUGIN_VERSION) {
DvInjectionTestConfig withCCUDPlugin(String version = CCUD_PLUGIN_VERSION) {
ccudPluginVersion = version
return this
}

TestConfig withServer(URI url, boolean enforceUrl = false) {
DvInjectionTestConfig withServer(URI url, boolean enforceUrl = false) {
serverUrl = url.toASCIIString()
this.enforceUrl = enforceUrl
return this
}

TestConfig withPluginRepository(URI pluginRepositoryUrl) {
DvInjectionTestConfig withPluginRepository(URI pluginRepositoryUrl) {
this.pluginRepositoryUrl = pluginRepositoryUrl
return this
}

TestConfig withCaptureFileFingerprints() {
DvInjectionTestConfig withCaptureFileFingerprints() {
this.captureFileFingerprints = true
return this
}

TestConfig withPluginRepositoryCredentials(String pluginRepoUsername, String pluginRepoPassword) {
DvInjectionTestConfig withPluginRepositoryCredentials(String pluginRepoUsername, String pluginRepoPassword) {
this.pluginRepositoryUsername = pluginRepoUsername
this.pluginRepositoryPassword = pluginRepoPassword
return this
}

def getEnvVars() {
Map<String, String> getEnvVars() {
Map<String, String> envVars = [
DEVELOCITY_INJECTION_INIT_SCRIPT_NAME : "develocity-injection.init.gradle",
DEVELOCITY_INJECTION_ENABLED : "true",
Expand Down

0 comments on commit c7067ff

Please sign in to comment.