From 850b17906709329f788334483e343ce70dfb01aa Mon Sep 17 00:00:00 2001 From: Eric Haag Date: Fri, 18 Oct 2024 13:17:10 -0500 Subject: [PATCH] Use common Develocity injection script for Gradle experiments --- build.gradle.kts | 25 ++ ...-validate-remote-build-caching-ci-local.sh | 2 +- .../configure-build-validation.gradle | 196 +++++++++++ .../configure-gradle-enterprise.gradle | 310 ------------------ .../configure-local-build-caching.gradle | 13 +- .../configure-remote-build-caching.gradle | 13 +- components/scripts/lib/gradle.sh | 33 +- 7 files changed, 253 insertions(+), 339 deletions(-) create mode 100644 components/scripts/gradle/gradle-init-scripts/configure-build-validation.gradle delete mode 100644 components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle diff --git a/build.gradle.kts b/build.gradle.kts index 5539be02..a8248bbd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,6 +29,22 @@ repositories { includeModule("argbash", "argbash") } } + exclusiveContent { + forRepository { + ivy { + url = uri("https://raw.githubusercontent.com/gradle/develocity-ci-injection/") + patternLayout { + artifact("refs/tags/v[revision]/reference/develocity-injection.init.gradle") + } + metadataSources { + artifact() + } + } + } + filter { + includeModule("com.gradle", "develocity-injection") + } + } exclusiveContent { forRepository { maven("https://repo.gradle.org/artifactory/solutions") @@ -52,6 +68,10 @@ allprojects { } val argbash by configurations.creating +val develocityInjection = configurations.dependencyScope("develocityInjection").get() +val develocityInjectionResolvable = configurations.resolvable("${develocityInjection.name}Resolvable") { + extendsFrom(develocityInjection) +} val develocityComponents by configurations.creating { attributes.attribute( TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, @@ -64,6 +84,7 @@ val develocityMavenComponents by configurations.creating dependencies { argbash("argbash:argbash:2.10.0@zip") + develocityInjection("com.gradle:develocity-injection:1.0") develocityComponents("com.gradle:build-scan-summary:$buildScanSummaryVersion") develocityMavenComponents("com.gradle:gradle-enterprise-maven-extension:1.18.4") mavenComponents(project(path = ":configure-gradle-enterprise-maven-extension", configuration = "shadow")) @@ -143,6 +164,10 @@ val copyGradleScripts by tasks.registering(Sync::class) { include("gradle-init-scripts/**") into("lib/scripts/") } + from(develocityInjectionResolvable) { + rename { "develocity-injection.gradle" } + into("lib/scripts/gradle-init-scripts") + } from(layout.projectDirectory.dir("components/scripts")) { include("README.md") include("mapping.example") diff --git a/components/scripts/gradle/05-validate-remote-build-caching-ci-local.sh b/components/scripts/gradle/05-validate-remote-build-caching-ci-local.sh index fd044e9b..9d021932 100755 --- a/components/scripts/gradle/05-validate-remote-build-caching-ci-local.sh +++ b/components/scripts/gradle/05-validate-remote-build-caching-ci-local.sh @@ -197,7 +197,7 @@ execute_build() { local args args=(--build-cache --init-script "${INIT_SCRIPTS_DIR}/configure-remote-build-caching.gradle") if [ -n "${remote_build_cache_url}" ]; then - args+=("-Dcom.gradle.enterprise.build-validation.remoteBuildCacheUrl=${remote_build_cache_url}") + args+=("-Ddevelocity.build-validation.remoteBuildCacheUrl=${remote_build_cache_url}") fi # shellcheck disable=SC2206 # we want tasks to expand with word splitting in this case diff --git a/components/scripts/gradle/gradle-init-scripts/configure-build-validation.gradle b/components/scripts/gradle/gradle-init-scripts/configure-build-validation.gradle new file mode 100644 index 00000000..edfd97d8 --- /dev/null +++ b/components/scripts/gradle/gradle-init-scripts/configure-build-validation.gradle @@ -0,0 +1,196 @@ +import org.gradle.util.GradleVersion +import java.nio.charset.StandardCharsets + +static getInputParam(String name) { + def ENV_VAR_PREFIX = '' + def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_') + return System.getProperty(name) ?: System.getenv(envVarName) +} + +def isTopLevelBuild = !gradle.parent +if (!isTopLevelBuild) { + return +} + +def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan' +def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise' +def DEVELOCITY_PLUGIN_ID = 'com.gradle.develocity' +def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin' + +def develocityUrl = getInputParam('develocity.url') + +def expDir = getInputParam('develocity.build-validation.expDir') +def expId = getInputParam('develocity.build-validation.expId') +def runId = getInputParam('develocity.build-validation.runId') +def scriptsVersion = getInputParam('develocity.build-validation.scriptsVersion') + +def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0') + +// register build scan listeners to capture build scan URL/id and to track publishing errors +def registerBuildScanActions = { def buildScan, def rootProjectName -> + buildScan.buildScanPublished { publishedBuildScan -> + // defer reading the runNum system property until execution time since it does not affect + // the configuration of the build, and given its value changes between consecutive build invocations + // it would always invalidate the configuration cache model from the first build invocation + // in the second build invocation + def getInputParam = { String name -> + def ENV_VAR_PREFIX = '' + def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_') + return System.getProperty(name) ?: System.getenv(envVarName) + } + def runNum = getInputParam('develocity.build-validation.runNum') + def buildScanUri = publishedBuildScan.buildScanUri + def buildScanId = publishedBuildScan.buildScanId + def port = (buildScanUri.port != -1) ? ':' + buildScanUri.port : '' + def baseUrl = "${buildScanUri.scheme}://${buildScanUri.host}${port}" + + def scanFile = new File(expDir, 'build-scans.csv') + scanFile.append("${runNum},${rootProjectName},${baseUrl},${buildScanUri},${buildScanId}\n") + } + + buildScan.onError { error -> + def errorFile = new File(expDir, 'errors.txt') + errorFile.text = 'Build Scan publishing failed.' + } +} + +// add custom data identifying the experiment +def addBuildScanCustomData = { def buildScan, def server -> + addCustomValueAndSearchLink(buildScan, server, "Experiment id", expId) + buildScan.tag(expId) + + addCustomValueAndSearchLink(buildScan, server, "Experiment run id", runId) + + buildScan.value("Build validation scripts", scriptsVersion) +} + +// fail if no server is configured +def failMissingDevelocityServerURL = { def docs -> + def errorFile = new File(expDir, 'errors.txt') + errorFile.text = 'The Develocity server URL has not been configured in the project or on the command line.' + throw new IllegalStateException("The Develocity server URL is not configured.\n" + + "Either configure it directly (see $docs) in the project,\n" + + "or use --gradle-enterprise-server when running the build validation script.") +} + +// fail if a plugin is not applied +def failMissingPlugin = { def plugin, docs -> + def errorFile = new File(expDir, 'errors.txt') + errorFile.text = "The $plugin plugin is missing from the project." + throw new IllegalStateException("The $plugin plugin is missing from the project.\n" + + "Either apply it directly (see $docs),\n" + + "or use --enable-gradle-enterprise when running the build validation script.") +} + +// do not fail if the CCUD plugin is not applied but surface a warning +def warnMissingCommonCustomUserDataGradlePlugin = { + def warningFile = new File(expDir, 'warnings.txt') + warningFile.append("The com.gradle.common-custom-user-data-gradle-plugin plugin is missing from " + + "the project (see https://github.com/gradle/common-custom-user-data-gradle-plugin).\n") +} + +if (GradleVersion.current() < GradleVersion.version('6.0')) { + //noinspection GroovyAssignabilityCheck + rootProject { + afterEvaluate { + if (!pluginManager.hasPlugin(BUILD_SCAN_PLUGIN_ID) && !pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) { + if (atLeastGradle5) { + failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_5_x') + } else { + failMissingPlugin(BUILD_SCAN_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_2_1_4_10_3') + } + } + + if (!pluginManager.hasPlugin(CCUD_PLUGIN_ID)) { + warnMissingCommonCustomUserDataGradlePlugin() + } + + pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) { + // only execute if Develocity plugin isn't applied + if (pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return + + if (develocityUrl) { + buildScan.server = develocityUrl + } + + if (!buildScan.server) { + failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy#gradle_5_x_2') + } + + buildScan.publishAlways() + registerBuildScanActions(buildScan, rootProject.name) + addBuildScanCustomData(buildScan, buildScan.server) + } + + pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) { + if (develocityUrl) { + develocity.server = develocityUrl + } + + if (!develocity.server.present) { + develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com + failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity') + } + + registerBuildScanActions(develocity.buildScan, rootProject.name) + addBuildScanCustomData(develocity.buildScan, develocity.server.get()) + } + } + } +} else { + gradle.settingsEvaluated { settings -> + if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) && !settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) { + failMissingPlugin(DEVELOCITY_PLUGIN_ID, 'https://docs.gradle.com/develocity/gradle-plugin/current/#gradle_6_x_and_later') + } + + if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) { + warnMissingCommonCustomUserDataGradlePlugin() + } + + settings.pluginManager.withPlugin(GRADLE_ENTERPRISE_PLUGIN_ID) { + // only execute if Develocity plugin isn't applied + if (settings.pluginManager.hasPlugin(DEVELOCITY_PLUGIN_ID)) return + + if (develocityUrl) { + settings.gradleEnterprise.server = develocityUrl + } + + if (!settings.gradleEnterprise.server) { + failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/legacy/#gradle_6_x_and_later_2') + } + + settings.gradleEnterprise.buildScan.publishAlways() + registerBuildScanActions(settings.gradleEnterprise.buildScan, settings.rootProject.name) + addBuildScanCustomData(settings.gradleEnterprise.buildScan, settings.gradleEnterprise.server) + } + + settings.pluginManager.withPlugin(DEVELOCITY_PLUGIN_ID) { + if (develocityUrl) { + settings.develocity.server = develocityUrl + } + + if (!settings.develocity.server.present) { + settings.develocity.buildScan.publishing.onlyIf { false } // prevent publishing to scans.gradle.com + failMissingDevelocityServerURL('https://docs.gradle.com/develocity/gradle-plugin/current/#connecting_to_develocity') + } + + registerBuildScanActions(settings.develocity.buildScan, settings.rootProject.name) + addBuildScanCustomData(settings.develocity.buildScan, settings.develocity.server.get()) + } + } +} + +static void addCustomValueAndSearchLink(buildScan, String server, label, String value) { + buildScan.value(label, value) + String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value) + String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}") + buildScan.link(label + " build scans", url) +} + +static String appendIfMissing(String str, String suffix) { + return str.endsWith(suffix) ? str : str + suffix +} + +static String urlEncode(String str) { + return URLEncoder.encode(str, StandardCharsets.UTF_8.name()) +} diff --git a/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle b/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle deleted file mode 100644 index ab1af9be..00000000 --- a/components/scripts/gradle/gradle-init-scripts/configure-gradle-enterprise.gradle +++ /dev/null @@ -1,310 +0,0 @@ -import org.gradle.util.GradleVersion -import java.nio.charset.StandardCharsets - -import static java.lang.Boolean.parseBoolean - -// note that there is no mechanism to share code between the initscript{} block and the main script, so some logic is duplicated - -// conditionally apply the GE / Build Scan plugin to the classpath so it can be applied to the build further down in this script -initscript { - def isTopLevelBuild = !gradle.parent - if (!isTopLevelBuild) { - return - } - - // the way this closure reads system properties means they are not tracked as inputs to the configuration cache model, - // the same is the case when reading environment variables with Gradle [6.5, 7.3] - def getInputParam = { String name -> - def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_') - return gradle.startParameter.systemPropertiesArgs[name] ?: System.getenv(envVarName) - } - - // the following local variables do not change between the build invocations of the same experiment run - // thus, reading their values in way that the configuration cache does not track them is acceptable - def pluginRepositoryUrl = getInputParam('com.gradle.enterprise.build-validation.gradle.plugin-repository.url') - def gePluginVersion = getInputParam('com.gradle.enterprise.build-validation.gradle-enterprise.plugin.version') - def ccudPluginVersion = getInputParam('com.gradle.enterprise.build-validation.ccud.plugin.version') - - def atLeastGradle5 = GradleVersion.current() >= GradleVersion.version('5.0') - def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0') - - if (gePluginVersion || ccudPluginVersion && atLeastGradle4) { - pluginRepositoryUrl = pluginRepositoryUrl ?: 'https://plugins.gradle.org/m2' - logger.quiet("Gradle Enterprise plugins resolution: $pluginRepositoryUrl") - - repositories { - maven { url pluginRepositoryUrl } - } - } - - dependencies { - if (gePluginVersion) { - classpath atLeastGradle5 ? - "com.gradle:gradle-enterprise-gradle-plugin:$gePluginVersion" : - "com.gradle:build-scan-plugin:1.16" - } - - if (ccudPluginVersion && atLeastGradle4) { - classpath "com.gradle:common-custom-user-data-gradle-plugin:$ccudPluginVersion" - } - } -} - -def BUILD_SCAN_PLUGIN_ID = 'com.gradle.build-scan' -def BUILD_SCAN_PLUGIN_CLASS = 'com.gradle.scan.plugin.BuildScanPlugin' - -def GRADLE_ENTERPRISE_PLUGIN_ID = 'com.gradle.enterprise' -def GRADLE_ENTERPRISE_PLUGIN_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterprisePlugin' -def GRADLE_ENTERPRISE_EXTENSION_CLASS = 'com.gradle.enterprise.gradleplugin.GradleEnterpriseExtension' - -def CCUD_PLUGIN_ID = 'com.gradle.common-custom-user-data-gradle-plugin' -def CCUD_PLUGIN_CLASS = 'com.gradle.CommonCustomUserDataGradlePlugin' - -def isTopLevelBuild = !gradle.parent -if (!isTopLevelBuild) { - return -} - -// the way this closure reads system properties means they are not tracked as inputs to the configuration cache model, -// the same is the case when reading environment variables with Gradle [6.5, 7.3] -def getInputParam = { String name -> - def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_') - return gradle.startParameter.systemPropertiesArgs[name] ?: System.getenv(envVarName) -} - -// the following local variables do not change between the build invocations of the same experiment run -// thus, reading their values in way that the configuration cache does not track them is acceptable -def geUrl = getInputParam('com.gradle.enterprise.build-validation.gradle-enterprise.url') -def geAllowUntrustedServer = getInputParam('com.gradle.enterprise.build-validation.gradle-enterprise.allow-untrusted-server') -def gePluginVersion = getInputParam('com.gradle.enterprise.build-validation.gradle-enterprise.plugin.version') -def ccudPluginVersion = getInputParam('com.gradle.enterprise.build-validation.ccud.plugin.version') - -def expDir = getInputParam('com.gradle.enterprise.build-validation.expDir') -def expId = getInputParam('com.gradle.enterprise.build-validation.expId') -def runId = getInputParam('com.gradle.enterprise.build-validation.runId') -def scriptsVersion = getInputParam('com.gradle.enterprise.build-validation.scriptsVersion') -def omitServerUrlValidation = parseBoolean(getInputParam('com.gradle.enterprise.build-validation.omitServerUrlValidation')) - -def atLeastGradle4 = GradleVersion.current() >= GradleVersion.version('4.0') - -// finish early if configuration parameters passed in via system properties are not valid/supported -if (ccudPluginVersion && isNotAtLeast(ccudPluginVersion, '1.7')) { - logger.warn("Common Custom User Data Gradle plugin must be at least 1.7. Configured version is $ccudPluginVersion.") - return -} - -// register build scan listeners to capture build scan URL/id and to track publishing errors -def registerBuildScanActions = { def buildScan, def rootProjectName -> - buildScan.buildScanPublished { publishedBuildScan -> - // defer reading the `runNum` system property until execution time since it does not affect - // the configuration of the build, and given its value changes between consecutive build invocations - // it would always invalidate the configuration cache model from the first build invocation - // in the second build invocation - def getRunNumInputParam = { String name -> - def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_') - return System.getProperty(name) ?: System.getenv(envVarName) - } - def runNum = getRunNumInputParam('com.gradle.enterprise.build-validation.runNum') - def buildScanUri = publishedBuildScan.buildScanUri - def buildScanId = publishedBuildScan.buildScanId - def port = (buildScanUri.port != -1) ? ':' + buildScanUri.port : '' - def baseUrl = "${buildScanUri.scheme}://${buildScanUri.host}${port}" - - def scanFile = new File(expDir, 'build-scans.csv') - scanFile.append("${runNum},${rootProjectName},${baseUrl},${buildScanUri},${buildScanId}\n") - } - - buildScan.onError { error -> - def errorFile = new File(expDir, 'errors.txt') - errorFile.text = 'Build Scan publishing failed.' - } -} - -// configure build scan publishing behavior -def configureBuildScanPublishing = { def buildScan -> - buildScan.publishAlways() - // buildScan.captureTaskInputFiles = true // too late to be set here for Gradle 5, set via sys prop - if (buildScan.metaClass.respondsTo(buildScan, 'setUploadInBackground', Boolean)) buildScan.uploadInBackground = false // uploadInBackground not available for build-scan-plugin 1.16 -} - -// add custom data identifying the experiment -def addBuildScanCustomData = { def buildScan -> - addCustomValueAndSearchLink(buildScan, "Experiment id", expId) - buildScan.tag(expId) - - addCustomValueAndSearchLink(buildScan, "Experiment run id", runId) - - buildScan.value("Build validation scripts", scriptsVersion) -} - -// fail if no GE server is configured -def logErrorMissingGradleEnterpriseServerURL = { - def errorFile = new File(expDir, 'errors.txt') - errorFile.text = 'The Gradle Enterprise server URL has not been configured in the project or on the command line.' -} - -// fail if the GE / Build Scan plugin is not applied -def logErrorMissingGradleEnterprisePlugin = { def plugin -> - def errorFile = new File(expDir, 'errors.txt') - errorFile.text = "The $plugin plugin is missing from the project." -} - -// do not fail if the CCUD plugin is not applied but surface a warning -def logWarningMissingCommonCustomUserDataGradlePlugin = { - def warningFile = new File(expDir, 'warnings.txt') - warningFile.append("The com.gradle.common-custom-user-data-gradle-plugin plugin is missing from " + - "the project (see https://github.com/gradle/common-custom-user-data-gradle-plugin).\n") -} - -// configure build scan behavior and optionally apply the GE / Build Scan / CCUD plugin -if (GradleVersion.current() < GradleVersion.version('6.0')) { - //noinspection GroovyAssignabilityCheck - rootProject { - buildscript.configurations.getByName("classpath").incoming.afterResolve { ResolvableDependencies incoming -> - def resolutionResult = incoming.resolutionResult - - def scanPluginComponent = resolutionResult.allComponents.find { - it.moduleVersion.with { group == "com.gradle" && (name == "build-scan-plugin" || name == "gradle-enterprise-gradle-plugin") } - } - - if (gePluginVersion) { - if (!scanPluginComponent) { - logger.quiet("Applying $BUILD_SCAN_PLUGIN_CLASS via init script") - logger.quiet("Connection to Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer") - applyPluginExternally(pluginManager, BUILD_SCAN_PLUGIN_CLASS) - if (geUrl) buildScan.server = geUrl - if (geAllowUntrustedServer) buildScan.allowUntrustedServer = parseBoolean(geAllowUntrustedServer) - } - } else { - if (!scanPluginComponent) { - logErrorMissingGradleEnterprisePlugin('com.gradle.build-scan') - throw new IllegalStateException("The com.gradle.build-scan plugin is missing from the project.\n" + - "Either apply it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_5_x) to the project,\n" + - "or use `--enable-gradle-enterprise` when running the build validation script.") - } - } - - def ccudPluginComponent = resolutionResult.allComponents.find { - it.moduleVersion.with { group == "com.gradle" && name == "common-custom-user-data-gradle-plugin" } - } - - if (ccudPluginVersion && atLeastGradle4) { - if (!ccudPluginComponent) { - logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script") - pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS)) - } - } else { - if (!ccudPluginComponent) { - logWarningMissingCommonCustomUserDataGradlePlugin() - } - } - } - - pluginManager.withPlugin(BUILD_SCAN_PLUGIN_ID) { - afterEvaluate { - if (geUrl) buildScan.server = geUrl - if (geAllowUntrustedServer) buildScan.allowUntrustedServer = parseBoolean(geAllowUntrustedServer) - - if (!buildScan.server && !omitServerUrlValidation) { - logErrorMissingGradleEnterpriseServerURL() - throw new IllegalStateException("The Gradle Enterprise server URL is not configured.\n" + - "Either configure it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_5_x_2) in the project,\n" + - "or use `--gradle-enterprise-server` when running the build validation script.") - } - - registerBuildScanActions(buildScan, rootProject.name) - configureBuildScanPublishing(buildScan) - addBuildScanCustomData(buildScan) - } - } - } -} else { - gradle.settingsEvaluated { settings -> - if (gePluginVersion) { - if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID)) { - logger.quiet("Applying $GRADLE_ENTERPRISE_PLUGIN_CLASS via init script") - logger.quiet("Connection to Gradle Enterprise: $geUrl, allowUntrustedServer: $geAllowUntrustedServer") - applyPluginExternally(settings.pluginManager, GRADLE_ENTERPRISE_PLUGIN_CLASS) - extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext -> - if (geUrl) ext.server = geUrl - if (geAllowUntrustedServer) ext.allowUntrustedServer = parseBoolean(geAllowUntrustedServer) - } - } - } else { - if (!settings.pluginManager.hasPlugin(GRADLE_ENTERPRISE_PLUGIN_ID)) { - logErrorMissingGradleEnterprisePlugin('com.gradle.enterprise') - throw new IllegalStateException("The com.gradle.enterprise plugin is missing from the project.\n" + - "Either apply it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_6_x_and_later),\n" + - "or use `--enable-gradle-enterprise` when running the build validation script.") - } - } - - if (ccudPluginVersion) { - if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) { - logger.quiet("Applying $CCUD_PLUGIN_CLASS via init script") - settings.pluginManager.apply(initscript.classLoader.loadClass(CCUD_PLUGIN_CLASS)) - } - } else { - if (!settings.pluginManager.hasPlugin(CCUD_PLUGIN_ID)) { - logWarningMissingCommonCustomUserDataGradlePlugin() - } - } - - extensionsWithPublicType(settings, GRADLE_ENTERPRISE_EXTENSION_CLASS).collect { settings[it.name] }.each { ext -> - if (geUrl) ext.server = geUrl - if (geAllowUntrustedServer) ext.allowUntrustedServer = parseBoolean(geAllowUntrustedServer) - - if (!ext.server && !omitServerUrlValidation) { - logErrorMissingGradleEnterpriseServerURL() - throw new IllegalStateException("The Gradle Enterprise server URL is not configured.\n" + - "Either configure it directly (see https://docs.gradle.com/enterprise/gradle-plugin/#gradle_6_x_and_later_2) in the project,\n" + - "or use `--gradle-enterprise-server` when running the build validation script.") - } - - registerBuildScanActions(ext.buildScan, settings.rootProject.name) - configureBuildScanPublishing(ext.buildScan) - addBuildScanCustomData(ext.buildScan) - } - } -} - -void applyPluginExternally(PluginManager pluginManager, String pluginClassName) { - def externallyApplied = 'gradle.enterprise.externally-applied' - def oldValue = System.getProperty(externallyApplied) - System.setProperty(externallyApplied, 'true') - try { - pluginManager.apply(initscript.classLoader.loadClass(pluginClassName)) - } finally { - if (oldValue == null) { - System.clearProperty(externallyApplied) - } else { - System.setProperty(externallyApplied, oldValue) - } - } -} - -static def extensionsWithPublicType(def container, String publicType) { - container.extensions.extensionsSchema.elements.findAll { it.publicType.concreteClass.name == publicType } -} - -static boolean isNotAtLeast(String versionUnderTest, String referenceVersion) { - GradleVersion.version(versionUnderTest) < GradleVersion.version(referenceVersion) -} - -static void addCustomValueAndSearchLink(buildScan, String label, String value) { - buildScan.value(label, value) - if (buildScan.metaClass.respondsTo(buildScan, 'getServer') && buildScan.server) { // required for Gradle 4.x / build-scan-plugin 1.16 - String server = buildScan.server - String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value) - String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}") - buildScan.link(label + " build scans", url) - } -} - -static String appendIfMissing(String str, String suffix) { - return str.endsWith(suffix) ? str : str + suffix -} - -static String urlEncode(String str) { - return URLEncoder.encode(str, StandardCharsets.UTF_8.name()) -} diff --git a/components/scripts/gradle/gradle-init-scripts/configure-local-build-caching.gradle b/components/scripts/gradle/gradle-init-scripts/configure-local-build-caching.gradle index b05532d6..e922e399 100644 --- a/components/scripts/gradle/gradle-init-scripts/configure-local-build-caching.gradle +++ b/components/scripts/gradle/gradle-init-scripts/configure-local-build-caching.gradle @@ -1,13 +1,10 @@ -// the way this closure reads system properties means they are not tracked as inputs to the configuration cache model, -// the same is the case when reading environment variables with Gradle [6.5, 7.3] -def getInputParam = { String name -> - def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_') - return gradle.startParameter.systemPropertiesArgs[name] ?: System.getenv(envVarName) +static getInputParam(String name) { + def ENV_VAR_PREFIX = '' + def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_') + return System.getProperty(name) ?: System.getenv(envVarName) } -// the following local variable does not change between the build invocations of the same experiment run -// thus, reading its value in way that the configuration cache does not track it is acceptable -def expDir = getInputParam('com.gradle.enterprise.build-validation.expDir') +def expDir = getInputParam('develocity.build-validation.expDir') settingsEvaluated { settings -> settings.buildCache { diff --git a/components/scripts/gradle/gradle-init-scripts/configure-remote-build-caching.gradle b/components/scripts/gradle/gradle-init-scripts/configure-remote-build-caching.gradle index 55a1f224..f32a14f4 100644 --- a/components/scripts/gradle/gradle-init-scripts/configure-remote-build-caching.gradle +++ b/components/scripts/gradle/gradle-init-scripts/configure-remote-build-caching.gradle @@ -1,13 +1,10 @@ -// the way this closure reads system properties means they are not tracked as inputs to the configuration cache model, -// the same is the case when reading environment variables with Gradle [6.5, 7.3] -def getInputParam = { String name -> - def envVarName = name.toUpperCase().replace('.', '_').replace('-', '_') - return gradle.startParameter.systemPropertiesArgs[name] ?: System.getenv(envVarName) +static getInputParam(String name) { + def ENV_VAR_PREFIX = '' + def envVarName = ENV_VAR_PREFIX + name.toUpperCase().replace('.', '_').replace('-', '_') + return System.getProperty(name) ?: System.getenv(envVarName) } -// the following local variable does not change between the build invocations of the same experiment run -// thus, reading its value in way that the configuration cache does not track it is acceptable -def remoteBuildCacheUrl = getInputParam('com.gradle.enterprise.build-validation.remoteBuildCacheUrl') +def remoteBuildCacheUrl = getInputParam('develocity.build-validation.remoteBuildCacheUrl') settingsEvaluated { settings -> settings.buildCache { diff --git a/components/scripts/lib/gradle.sh b/components/scripts/lib/gradle.sh index 69a32c5f..cebb64e6 100644 --- a/components/scripts/lib/gradle.sh +++ b/components/scripts/lib/gradle.sh @@ -12,26 +12,35 @@ invoke_gradle() { cd "${project_dir}" > /dev/null 2>&1 || die "ERROR: Subdirectory ${project_dir} (set with --project-dir) does not exist in ${project_name}" "${INVALID_INPUT}" fi - args+=(--init-script "${INIT_SCRIPTS_DIR}/configure-gradle-enterprise.gradle") + args+=( + --init-script "${INIT_SCRIPTS_DIR}/develocity-injection.gradle" + --init-script "${INIT_SCRIPTS_DIR}/configure-build-validation.gradle" + -Ddevelocity.injection.init-script-name=develocity-injection.gradle + -Ddevelocity.injection-enabled=true + ) if [ "$enable_ge" == "on" ]; then - args+=("-Dcom.gradle.enterprise.build-validation.gradle.plugin-repository.url=https://plugins.gradle.org/m2") - args+=("-Dcom.gradle.enterprise.build-validation.gradle-enterprise.plugin.version=3.14.1") - args+=("-Dcom.gradle.enterprise.build-validation.ccud.plugin.version=2.0.2") + args+=( + -Dgradle.plugin-repository.url=https://plugins.gradle.org/m2 + -Ddevelocity.plugin.version="3.14.1" + -Ddevelocity.ccud.plugin.version="2.0.2" + ) fi if [ -n "${ge_server}" ]; then - args+=("-Dcom.gradle.enterprise.build-validation.gradle-enterprise.url=${ge_server}") - args+=("-Dcom.gradle.enterprise.build-validation.gradle-enterprise.allow-untrusted-server=false") + args+=( + -Ddevelocity.url="${ge_server}" + -Ddevelocity.allow-untrusted-server=false + ) fi args+=( - -Dcom.gradle.enterprise.build-validation.expDir="${EXP_DIR}" - -Dcom.gradle.enterprise.build-validation.expId="${EXP_SCAN_TAG}" - -Dcom.gradle.enterprise.build-validation.runId="${RUN_ID}" - -Dcom.gradle.enterprise.build-validation.runNum="${run_num}" - -Dcom.gradle.enterprise.build-validation.scriptsVersion="${SCRIPT_VERSION}" - -Dscan.capture-task-input-files=true + -Ddevelocity.build-validation.expDir="${EXP_DIR}" + -Ddevelocity.build-validation.expId="${EXP_SCAN_TAG}" + -Ddevelocity.build-validation.runId="${RUN_ID}" + -Ddevelocity.build-validation.runNum="${run_num}" + -Ddevelocity.build-validation.scriptsVersion="${SCRIPT_VERSION}" + -Ddevelocity.capture-file-fingerprints=true -Dpts.enabled=false )