Skip to content

Commit 8aecdd0

Browse files
authored
Merge pull request #671 from gradle/erichaagdev/common-dv-init-script
Common Develocity injection script is used for Gradle experiments
2 parents 5a1cbc2 + 850b179 commit 8aecdd0

7 files changed

+253
-339
lines changed

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")

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,196 @@
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 getInputParam = { String name ->
37+
def ENV_VAR_PREFIX = ''
38+
def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_')
39+
return System.getProperty(name) ?: System.getenv(envVarName)
40+
}
41+
def runNum = getInputParam('develocity.build-validation.runNum')
42+
def buildScanUri = publishedBuildScan.buildScanUri
43+
def buildScanId = publishedBuildScan.buildScanId
44+
def port = (buildScanUri.port != -1) ? ':' + buildScanUri.port : ''
45+
def baseUrl = "${buildScanUri.scheme}://${buildScanUri.host}${port}"
46+
47+
def scanFile = new File(expDir, 'build-scans.csv')
48+
scanFile.append("${runNum},${rootProjectName},${baseUrl},${buildScanUri},${buildScanId}\n")
49+
}
50+
51+
buildScan.onError { error ->
52+
def errorFile = new File(expDir, 'errors.txt')
53+
errorFile.text = 'Build Scan publishing failed.'
54+
}
55+
}
56+
57+
// add custom data identifying the experiment
58+
def addBuildScanCustomData = { def buildScan, def server ->
59+
addCustomValueAndSearchLink(buildScan, server, "Experiment id", expId)
60+
buildScan.tag(expId)
61+
62+
addCustomValueAndSearchLink(buildScan, server, "Experiment run id", runId)
63+
64+
buildScan.value("Build validation scripts", scriptsVersion)
65+
}
66+
67+
// fail if no server is configured
68+
def failMissingDevelocityServerURL = { def docs ->
69+
def errorFile = new File(expDir, 'errors.txt')
70+
errorFile.text = 'The Develocity server URL has not been configured in the project or on the command line.'
71+
throw new IllegalStateException("The Develocity server URL is not configured.\n"
72+
+ "Either configure it directly (see $docs) in the project,\n"
73+
+ "or use --gradle-enterprise-server when running the build validation script.")
74+
}
75+
76+
// fail if a plugin is not applied
77+
def failMissingPlugin = { def plugin, docs ->
78+
def errorFile = new File(expDir, 'errors.txt')
79+
errorFile.text = "The $plugin plugin is missing from the project."
80+
throw new IllegalStateException("The $plugin plugin is missing from the project.\n" +
81+
"Either apply it directly (see $docs),\n" +
82+
"or use --enable-gradle-enterprise when running the build validation script.")
83+
}
84+
85+
// do not fail if the CCUD plugin is not applied but surface a warning
86+
def warnMissingCommonCustomUserDataGradlePlugin = {
87+
def warningFile = new File(expDir, 'warnings.txt')
88+
warningFile.append("The com.gradle.common-custom-user-data-gradle-plugin plugin is missing from " +
89+
"the project (see https://github.com/gradle/common-custom-user-data-gradle-plugin).\n")
90+
}
91+
92+
if (GradleVersion.current() < GradleVersion.version('6.0')) {
93+
//noinspection GroovyAssignabilityCheck
94+
rootProject {
95+
afterEvaluate {
96+
if (!pluginManager.hasPlugin(BUILD_SCAN_PLUGIN_ID) && !pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
97+
if (atLeastGradle5) {
98+
failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_5_x')
99+
} else {
100+
failMissingPlugin(BUILD_SCAN_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_2_1_4_10_3')
101+
}
102+
}
103+
104+
if (!pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
105+
warnMissingCommonCustomUserDataGradlePlugin()
106+
}
107+
108+
pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) {
109+
// only execute if Develocity plugin isn't applied
110+
if (pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return
111+
112+
if (develocityUrl) {
113+
buildScan.server = develocityUrl
114+
}
115+
116+
if (!buildScan.server) {
117+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy#gradle_5_x_2')
118+
}
119+
120+
buildScan.publishAlways()
121+
registerBuildScanActions(buildScan, rootProject.name)
122+
addBuildScanCustomData(buildScan, buildScan.server)
123+
}
124+
125+
pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
126+
if (develocityUrl) {
127+
develocity.server = develocityUrl
128+
}
129+
130+
if (!develocity.server.present) {
131+
develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com
132+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity')
133+
}
134+
135+
registerBuildScanActions(develocity.buildScan, rootProject.name)
136+
addBuildScanCustomData(develocity.buildScan, develocity.server.get())
137+
}
138+
}
139+
}
140+
} else {
141+
gradle.settingsEvaluated { settings ->
142+
if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) {
143+
failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_6_x_and_later')
144+
}
145+
146+
if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) {
147+
warnMissingCommonCustomUserDataGradlePlugin()
148+
}
149+
150+
settings.pluginManager.withPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) {
151+
// only execute if Develocity plugin isn't applied
152+
if (settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return
153+
154+
if (develocityUrl) {
155+
settings.gradleEnterprise.server = develocityUrl
156+
}
157+
158+
if (!settings.gradleEnterprise.server) {
159+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_6_x_and_later_2')
160+
}
161+
162+
settings.gradleEnterprise.buildScan.publishAlways()
163+
registerBuildScanActions(settings.gradleEnterprise.buildScan, settings.rootProject.name)
164+
addBuildScanCustomData(settings.gradleEnterprise.buildScan, settings.gradleEnterprise.server)
165+
}
166+
167+
settings.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) {
168+
if (develocityUrl) {
169+
settings.develocity.server = develocityUrl
170+
}
171+
172+
if (!settings.develocity.server.present) {
173+
settings.develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com
174+
failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity')
175+
}
176+
177+
registerBuildScanActions(settings.develocity.buildScan, settings.rootProject.name)
178+
addBuildScanCustomData(settings.develocity.buildScan, settings.develocity.server.get())
179+
}
180+
}
181+
}
182+
183+
static void addCustomValueAndSearchLink(buildScan, String server, label, String value) {
184+
buildScan.value(label, value)
185+
String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value)
186+
String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}")
187+
buildScan.link(label + " build scans", url)
188+
}
189+
190+
static String appendIfMissing(String str, String suffix) {
191+
return str.endsWith(suffix) ? str : str + suffix
192+
}
193+
194+
static String urlEncode(String str) {
195+
return URLEncoder.encode(str, StandardCharsets.UTF_8.name())
196+
}

0 commit comments

Comments
 (0)