Skip to content

Commit 4c0abb9

Browse files
committed
Use common Develocity injection script for Gradle experiments
1 parent 683d18d commit 4c0abb9

7 files changed

+248
-339
lines changed

Diff for: build.gradle.kts

+25
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ repositories {
2929
includeModule("argbash", "argbash")
3030
}
3131
}
32+
exclusiveContent {
33+
forRepository {
34+
ivy {
35+
url = uri("https://raw.githubusercontent.com/gradle/develocity-ci-injection/")
36+
patternLayout {
37+
artifact("refs/tags/v[revision]/reference/develocity-injection.init.gradle")
38+
}
39+
metadataSources {
40+
artifact()
41+
}
42+
}
43+
}
44+
filter {
45+
includeModule("com.gradle", "develocity-injection")
46+
}
47+
}
3248
exclusiveContent {
3349
forRepository {
3450
maven("https://repo.gradle.org/artifactory/solutions")
@@ -52,6 +68,10 @@ allprojects {
5268
}
5369

5470
val argbash by configurations.creating
71+
val develocityInjection = configurations.dependencyScope("develocityInjection").get()
72+
val develocityInjectionResolvable = configurations.resolvable("${develocityInjection.name}Resolvable") {
73+
extendsFrom(develocityInjection)
74+
}
5575
val develocityComponents by configurations.creating {
5676
attributes.attribute(
5777
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
@@ -64,6 +84,7 @@ val develocityMavenComponents by configurations.creating
6484

6585
dependencies {
6686
argbash("argbash:argbash:2.10.0@zip")
87+
develocityInjection("com.gradle:develocity-injection:1.0")
6788
develocityComponents("com.gradle:build-scan-summary:$buildScanSummaryVersion")
6889
develocityMavenComponents("com.gradle:gradle-enterprise-maven-extension:1.18.4")
6990
mavenComponents(project(path = ":configure-gradle-enterprise-maven-extension", configuration = "shadow"))
@@ -143,6 +164,10 @@ val copyGradleScripts by tasks.registering(Sync::class) {
143164
include("gradle-init-scripts/**")
144165
into("lib/scripts/")
145166
}
167+
from(develocityInjectionResolvable) {
168+
rename { "develocity-injection.gradle" }
169+
into("lib/scripts/gradle-init-scripts")
170+
}
146171
from(layout.projectDirectory.dir("components/scripts")) {
147172
include("README.md")
148173
include("mapping.example")

Diff for: components/scripts/gradle/05-validate-remote-build-caching-ci-local.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ execute_build() {
197197
local args
198198
args=(--build-cache --init-script "${INIT_SCRIPTS_DIR}/configure-remote-build-caching.gradle")
199199
if [ -n "${remote_build_cache_url}" ]; then
200-
args+=("-Dcom.gradle.enterprise.build-validation.remoteBuildCacheUrl=${remote_build_cache_url}")
200+
args+=("-Ddevelocity.build-validation.remoteBuildCacheUrl=${remote_build_cache_url}")
201201
fi
202202

203203
# shellcheck disable=SC2206 # we want tasks to expand with word splitting in this case
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import org.gradle.util.GradleVersion
2+
import java.nio.charset.StandardCharsets
3+
4+
static getInputParam(String name) {
5+
def ENV_VAR_PREFIX = ''
6+
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
7+
return System.getProperty(name) ?: System.getenv(envVarName)
8+
}
9+
10+
def isTopLevelBuild = !gradle.parent
11+
if (!isTopLevelBuild) {
12+
return
13+
}
14+
15+
def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan'
16+
def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise'
17+
def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity'
18+
def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin'
19+
20+
def develocityUrl = getInputParam('develocity.url')
21+
22+
def expDir = getInputParam('develocity.build-validation.expDir')
23+
def expId = getInputParam('develocity.build-validation.expId')
24+
def runId = getInputParam('develocity.build-validation.runId')
25+
def scriptsVersion = getInputParam('develocity.build-validation.scriptsVersion')
26+
27+
def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0')
28+
29+
// register build scan listeners to capture build scan URL/id and to track publishing errors
30+
def registerBuildScanActions = { def buildScan, def rootProjectName ->
31+
buildScan.buildScanPublished { publishedBuildScan ->
32+
// defer reading the runNum system property until execution time since it does not affect
33+
// the configuration of the build, and given its value changes between consecutive build invocations
34+
// it would always invalidate the configuration cache model from the first build invocation
35+
// in the second build invocation
36+
def runNum = getInputParam('develocity.build-validation.runNum')
37+
def buildScanUri = publishedBuildScan.buildScanUri
38+
def buildScanId = publishedBuildScan.buildScanId
39+
def port = (buildScanUri.port != -1) ? ':' + buildScanUri.port : ''
40+
def baseUrl = "${buildScanUri.scheme}://${buildScanUri.host}${port}"
41+
42+
def scanFile = new File(expDir, 'build-scans.csv')
43+
scanFile.append("${runNum},${rootProjectName},${baseUrl},${buildScanUri},${buildScanId}\n")
44+
}
45+
46+
buildScan.onError { error ->
47+
def errorFile = new File(expDir, 'errors.txt')
48+
errorFile.text = 'Build Scan publishing failed.'
49+
}
50+
}
51+
52+
// add custom data identifying the experiment
53+
def addBuildScanCustomData = { def buildScan, def server ->
54+
addCustomValueAndSearchLink(buildScan, server, "Experiment id", expId)
55+
buildScan.tag(expId)
56+
57+
addCustomValueAndSearchLink(buildScan, server, "Experiment run id", runId)
58+
59+
buildScan.value("Build validation scripts", scriptsVersion)
60+
}
61+
62+
// fail if no server is configured
63+
def failMissingDevelocityServerURL = { def docs ->
64+
def errorFile = new File(expDir, 'errors.txt')
65+
errorFile.text = 'The Develocity server URL has not been configured in the project or on the command line.'
66+
throw new IllegalStateException("The Develocity server URL is not configured.\n"
67+
+ "Either configure it directly (see $docs) in the project,\n"
68+
+ "or use --gradle-enterprise-server when running the build validation script.")
69+
}
70+
71+
// fail if a plugin is not applied
72+
def failMissingPlugin = { def plugin, docs ->
73+
def errorFile = new File(expDir, 'errors.txt')
74+
errorFile.text = "The $plugin plugin is missing from the project."
75+
throw new IllegalStateException("The $plugin plugin is missing from the project.\n" +
76+
"Either apply it directly (see $docs),\n" +
77+
"or use --enable-gradle-enterprise when running the build validation script.")
78+
}
79+
80+
// do not fail if the CCUD plugin is not applied but surface a warning
81+
def warnMissingCommonCustomUserDataGradlePlugin = {
82+
def warningFile = new File(expDir, 'warnings.txt')
83+
warningFile.append("The com.gradle.common-custom-user-data-gradle-plugin plugin is missing from " +
84+
"the project (see https://github.com/gradle/common-custom-user-data-gradle-plugin).\n")
85+
}
86+
87+
if (GradleVersion.current() < GradleVersion.version('6.0')) {
88+
//noinspection GroovyAssignabilityCheck
89+
rootProject {
90+
afterEvaluate {
91+
if (!pluginManager.hasPlugin(BUILD_SCAN_PLUGIN_ID) && !pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
92+
if (atLeastGradle5) {
93+
failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_5_x')
94+
} else {
95+
failMissingPlugin(BUILD_SCAN_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_2_1_4_10_3')
96+
}
97+
}
98+
99+
if (!pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
100+
warnMissingCommonCustomUserDataGradlePlugin()
101+
}
102+
103+
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
104+
// only execute if Develocity plugin isn't applied
105+
if (pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return
106+
107+
if (develocityUrl) {
108+
buildScan.server = develocityUrl
109+
}
110+
111+
if (!buildScan.server) {
112+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy#gradle_5_x_2')
113+
}
114+
115+
buildScan.publishAlways()
116+
registerBuildScanActions(buildScan, rootProject.name)
117+
addBuildScanCustomData(buildScan, buildScan.server)
118+
}
119+
120+
pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
121+
if (develocityUrl) {
122+
develocity.server = develocityUrl
123+
}
124+
125+
if (!develocity.server.present) {
126+
develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com
127+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity')
128+
}
129+
130+
registerBuildScanActions(develocity.buildScan, rootProject.name)
131+
addBuildScanCustomData(develocity.buildScan, develocity.server.get())
132+
}
133+
}
134+
}
135+
} else {
136+
gradle.settingsEvaluated { settings ->
137+
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
138+
failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_6_x_and_later')
139+
}
140+
141+
if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
142+
warnMissingCommonCustomUserDataGradlePlugin()
143+
}
144+
145+
settings.pluginManager.withPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) {
146+
// only execute if Develocity plugin isn't applied
147+
if (settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return
148+
149+
if (develocityUrl) {
150+
settings.gradleEnterprise.server = develocityUrl
151+
}
152+
153+
if (!settings.gradleEnterprise.server) {
154+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_6_x_and_later_2')
155+
}
156+
157+
settings.gradleEnterprise.buildScan.publishAlways()
158+
registerBuildScanActions(settings.gradleEnterprise.buildScan, settings.rootProject.name)
159+
addBuildScanCustomData(settings.gradleEnterprise.buildScan, settings.gradleEnterprise.server)
160+
}
161+
162+
settings.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
163+
if (develocityUrl) {
164+
settings.develocity.server = develocityUrl
165+
}
166+
167+
if (!settings.develocity.server.present) {
168+
settings.develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com
169+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity')
170+
}
171+
172+
registerBuildScanActions(settings.develocity.buildScan, settings.rootProject.name)
173+
addBuildScanCustomData(settings.develocity.buildScan, settings.develocity.server.get())
174+
}
175+
}
176+
}
177+
178+
static void addCustomValueAndSearchLink(buildScan, String server, label, String value) {
179+
buildScan.value(label, value)
180+
String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value)
181+
String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}")
182+
buildScan.link(label + " build scans", url)
183+
}
184+
185+
static String appendIfMissing(String str, String suffix) {
186+
return str.endsWith(suffix) ? str : str + suffix
187+
}
188+
189+
static String urlEncode(String str) {
190+
return URLEncoder.encode(str, StandardCharsets.UTF_8.name())
191+
}

0 commit comments

Comments
 (0)