From 12f7587200bd23a658190a1080c3336eb9221ee5 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:15:08 +0200 Subject: [PATCH 1/9] test(build): cover native smoke app inputs Exercise the two inputs the native smoke apps rely on: a provider-backed environment variable and a provider-backed file forwarded as a Gradle property. This locks in the Gradle 9 migration support that now replaces the old Exec wiring. --- .../smoketest/SmokeTestAppEndToEndTest.kt | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index a0966107f44..04b56f86522 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -235,6 +235,63 @@ class SmokeTestAppEndToEndTest { assertThat(File(gradleUserHomeDir)).doesNotExist() } + @Test + fun `nested build receives native app environment and provider backed file inputs`() { + writeOuterSettings() + File(projectDir.toFile(), "agent.jar").writeText("agent") + outerBuild.writeText( + """ + plugins { + java + id("dd-trace-java.smoke-test-app") + } + + smokeTestApp { + javaLauncher.set( + javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } + ) + application { + taskName.set("recordNativeInputs") + artifactPath.set("native-inputs.txt") + sysProperty.set("native.inputs.path") + buildArguments.add("-Dnative.enabled=true") + environment.put("GRAALVM_HOME", providers.provider { "test-graalvm" }) + } + projectJar("agentPath", providers.provider { layout.projectDirectory.file("agent.jar") }) + } + """.trimIndent(), + ) + writeInnerSettings() + writeInnerBuild( + """ + tasks.register("recordNativeInputs") { + val out = layout.buildDirectory.file("native-inputs.txt") + outputs.file(out) + doLast { + out.get().asFile.writeText( + listOf( + "graalvm=" + System.getenv("GRAALVM_HOME"), + "agentPath=" + project.findProperty("agentPath"), + "nativeEnabled=" + System.getProperty("native.enabled"), + ).joinToString(System.lineSeparator()) + ) + } + } + """.trimIndent(), + ) + + val result = runner("recordNativeInputs").build() + + assertThat(result.task(":recordNativeInputs")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val inputsFile = File(projectDir.toFile(), "build/application/native-inputs.txt") + assertThat(inputsFile).exists() + assertThat(inputsFile.readLines()).contains( + "graalvm=test-graalvm", + "agentPath=${projectDir.resolve("agent.jar").toFile().absolutePath}", + "nativeEnabled=true", + ) + } + /** * `buildCacheEnabled` defaults to `false` and is plumbed through to the nested daemon as * an explicit `--no-build-cache` / `--build-cache` argument. The inner build records From 0de13d6beab274cf753bd297f09d685aa3cb86d8 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:15:39 +0200 Subject: [PATCH 2/9] docs(smoke): explain OpenLiberty Maven builds Leave the OpenLiberty smoke apps on the Maven wrapper for now. They are the only Maven nested application builds, so a dedicated NestedMavenBuild task would add API surface before there is a pattern to share. --- dd-smoke-tests/springboot-openliberty-20/build.gradle | 3 +++ dd-smoke-tests/springboot-openliberty-23/build.gradle | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dd-smoke-tests/springboot-openliberty-20/build.gradle b/dd-smoke-tests/springboot-openliberty-20/build.gradle index b8a4f0c8c5f..0215eb17761 100644 --- a/dd-smoke-tests/springboot-openliberty-20/build.gradle +++ b/dd-smoke-tests/springboot-openliberty-20/build.gradle @@ -11,6 +11,9 @@ def jarPath = "$buildDir/application/target/${jarName}" def isWindows = System.getProperty("os.name").toLowerCase().contains("win") def mvnwCommand = isWindows ? 'mvnw.cmd' : 'mvnw' +// Keep the Maven wrapper here until more Maven smoke-test applications need nested builds. +// The smoke-test-app plugin is Gradle-focused, and a Maven sibling task is not worth the +// extra API surface for only the two OpenLiberty applications. // compile the Open liberty spring boot server tasks.register('mvnStage', Exec) { workingDir("$appDir") diff --git a/dd-smoke-tests/springboot-openliberty-23/build.gradle b/dd-smoke-tests/springboot-openliberty-23/build.gradle index 68dc1ec98c7..43c7f8a193a 100644 --- a/dd-smoke-tests/springboot-openliberty-23/build.gradle +++ b/dd-smoke-tests/springboot-openliberty-23/build.gradle @@ -11,6 +11,9 @@ def jarPath = "$buildDir/application/target/${jarName}" def isWindows = System.getProperty("os.name").toLowerCase().contains("win") def mvnwCommand = isWindows ? 'mvnw.cmd' : 'mvnw' +// Keep the Maven wrapper here until more Maven smoke-test applications need nested builds. +// The smoke-test-app plugin is Gradle-focused, and a Maven sibling task is not worth the +// extra API surface for only the two OpenLiberty applications. // compile the Open liberty spring boot server tasks.register('mvnStage', Exec) { workingDir("$appDir") From aae5a2078663107ac31bb91bf8fff6f42b4f91d7 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:17:20 +0200 Subject: [PATCH 3/9] feat(build): inject smoke app proxy repos Move nested smoke-test repository policy into the plugin. Nested Gradle builds now pass root proxy properties and load one init script, so individual application settings files no longer need to repeat the same repository blocks. --- .../buildlogic/smoketest/NestedGradleBuild.kt | 36 ++++++++++ .../smoketest/proxy-repositories.init.gradle | 40 +++++++++++ .../smoketest/SmokeTestAppEndToEndTest.kt | 67 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt index 7500e8dfdf2..ef830dbd026 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt @@ -54,6 +54,9 @@ abstract class NestedGradleBuild @Inject constructor( gradleDistributionBaseUrl.convention( project.providers.environmentVariable(MASS_READ_URL_ENV), ) + gradlePluginProxy.convention(project.providers.gradleProperty("gradlePluginProxy")) + mavenRepositoryProxy.convention(project.providers.gradleProperty("mavenRepositoryProxy")) + proxyInitScript.convention(PROXY_INIT_SCRIPT) javaLauncher.convention( javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(DEFAULT_NESTED_JAVA_VERSION)) @@ -84,6 +87,17 @@ abstract class NestedGradleBuild @Inject constructor( @get:Optional abstract val gradleDistributionBaseUrl: Property + @get:Input + @get:Optional + abstract val gradlePluginProxy: Property + + @get:Input + @get:Optional + abstract val mavenRepositoryProxy: Property + + @get:Input + abstract val proxyInitScript: Property + @get:Nested abstract val javaLauncher: Property @@ -143,10 +157,15 @@ abstract class NestedGradleBuild @Inject constructor( val appBuildDirFile = applicationBuildDir.get().asFile val daemonJavaHome = javaLauncher.get().metadata.installationPath.asFile val gradleUserHomeDir = createGradleUserHome() + val proxyInitScriptFile = writeProxyInitScript() val args = buildList { + add("--init-script") + add(proxyInitScriptFile.absolutePath) add(if (buildCacheEnabled.get()) "--build-cache" else "--no-build-cache") add("-PappBuildDir=${appBuildDirFile.absolutePath}") + addGradleProperty("gradlePluginProxy", gradlePluginProxy.orNull) + addGradleProperty("mavenRepositoryProxy", mavenRepositoryProxy.orNull) projectJars.get().forEach { entry -> add("-P${entry.propertyName.get()}=${entry.file.get().asFile.absolutePath}") } @@ -240,6 +259,12 @@ abstract class NestedGradleBuild @Inject constructor( } } + private fun writeProxyInitScript(): File { + val initScript = temporaryDir.resolve("proxy-repositories.init.gradle") + initScript.writeText(proxyInitScript.get()) + return initScript + } + private fun findGradleExecutable(gradleUserHomeDir: File): File? = gradleUserHomeDir.walkTopDown().firstOrNull { file -> file.isFile && @@ -275,3 +300,14 @@ abstract class NestedGradleBuild @Inject constructor( const val GRADLE_STOP_TIMEOUT_SECONDS = 30L } } + +private fun MutableList.addGradleProperty(name: String, value: String?) { + if (!value.isNullOrBlank()) { + add("-P$name=$value") + } +} + +private val PROXY_INIT_SCRIPT: String = + NestedGradleBuild::class.java.getResource("proxy-repositories.init.gradle") + ?.readText() + ?: error("Missing proxy-repositories.init.gradle resource") diff --git a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle new file mode 100644 index 00000000000..6e4cad11565 --- /dev/null +++ b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle @@ -0,0 +1,40 @@ +import org.gradle.api.initialization.resolve.RepositoriesMode + +beforeSettings { settings -> + def gradlePluginProxy = settings.findProperty("gradlePluginProxy") + def mavenRepositoryProxy = settings.findProperty("mavenRepositoryProxy") + + settings.pluginManagement { + repositories { + mavenLocal() + if (gradlePluginProxy) { + maven { + url = settings.uri(gradlePluginProxy) + allowInsecureProtocol = true + } + } + if (mavenRepositoryProxy) { + maven { + url = settings.uri(mavenRepositoryProxy) + allowInsecureProtocol = true + } + } + gradlePluginPortal() + mavenCentral() + } + } + + settings.dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + mavenLocal() + if (mavenRepositoryProxy) { + maven { + url = settings.uri(mavenRepositoryProxy) + allowInsecureProtocol = true + } + } + mavenCentral() + } + } +} diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index 04b56f86522..b89f9f506ca 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -292,6 +292,73 @@ class SmokeTestAppEndToEndTest { ) } + @Test + fun `init script injects Maven repository proxy into nested settings`() { + writeOuterSettings() + val repository = projectDir.resolve("maven-repo").toFile() + val artifactDir = File(repository, "com/example/demo/1.0") + artifactDir.mkdirs() + File(artifactDir, "demo-1.0.pom").writeText( + """ + + 4.0.0 + com.example + demo + 1.0 + + """.trimIndent(), + ) + File(artifactDir, "demo-1.0.jar").writeText("demo") + outerBuild.writeText( + """ + plugins { + java + id("dd-trace-java.smoke-test-app") + } + + smokeTestApp { + javaLauncher.set( + javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } + ) + application { + taskName.set("resolveDependency") + artifactPath.set("resolved-dependency.txt") + sysProperty.set("resolved.dependency.path") + } + } + """.trimIndent(), + ) + writeInnerSettings() + writeInnerBuild( + """ + dependencies { + implementation("com.example:demo:1.0") + } + + tasks.register("resolveDependency") { + val resolved = layout.buildDirectory.file("resolved-dependency.txt") + inputs.files(configurations.compileClasspath) + outputs.file(resolved) + doLast { + resolved.get().asFile.writeText( + configurations.compileClasspath.get().singleFile.name + ) + } + } + """.trimIndent(), + ) + + val result = runner( + "resolveDependency", + "-PmavenRepositoryProxy=${repository.toURI()}", + ).build() + + assertThat(result.task(":resolveDependency")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val resolvedFile = File(projectDir.toFile(), "build/application/resolved-dependency.txt") + assertThat(resolvedFile).exists() + assertThat(resolvedFile.readText()).isEqualTo("demo-1.0.jar") + } + /** * `buildCacheEnabled` defaults to `false` and is plumbed through to the nested daemon as * an explicit `--no-build-cache` / `--build-cache` argument. The inner build records From 1966f8b44c0f690cf29b0ff31da65716a7c55610 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:20:25 +0200 Subject: [PATCH 4/9] refactor(smoke): drop nested proxy boilerplate Let the smoke-test-app init script own nested repository policy. Application settings files now keep only project-specific settings, with Quarkus retaining its plugin version declaration. --- .../application/settings.gradle | 24 ------------------- .../armeria-grpc/application/settings.gradle | 24 ------------------- .../kafka-2/application/settings.gradle | 24 ------------------- .../kafka-3/application/settings.gradle | 24 ------------------- .../openfeature/application/settings.gradle | 24 ------------------- .../application/settings.gradle | 17 ------------- .../quarkus/application/settings.gradle | 21 ---------------- .../rum/wildfly-15/rum-ear/settings.gradle | 20 ---------------- .../application/settings.gradle | 24 ------------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 24 ------------------- .../application/settings.gradle | 24 ------------------- .../application/settings.gradle | 24 ------------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../application/settings.gradle | 20 ---------------- .../wildfly/spring-ear/settings.gradle | 20 ---------------- 23 files changed, 494 deletions(-) diff --git a/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle b/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle index 1cd03bc7775..25124c0e4fa 100644 --- a/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/armeria-grpc/application/settings.gradle b/dd-smoke-tests/armeria-grpc/application/settings.gradle index 9ca0c8f80dd..5ebcec3df6f 100644 --- a/dd-smoke-tests/armeria-grpc/application/settings.gradle +++ b/dd-smoke-tests/armeria-grpc/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/kafka-2/application/settings.gradle b/dd-smoke-tests/kafka-2/application/settings.gradle index 52cb42bea22..3da3ede1eba 100644 --- a/dd-smoke-tests/kafka-2/application/settings.gradle +++ b/dd-smoke-tests/kafka-2/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/kafka-3/application/settings.gradle b/dd-smoke-tests/kafka-3/application/settings.gradle index b0697997e79..ef0a2404b15 100644 --- a/dd-smoke-tests/kafka-3/application/settings.gradle +++ b/dd-smoke-tests/kafka-3/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/openfeature/application/settings.gradle b/dd-smoke-tests/openfeature/application/settings.gradle index 6e990889506..718d8875152 100644 --- a/dd-smoke-tests/openfeature/application/settings.gradle +++ b/dd-smoke-tests/openfeature/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/quarkus-native/application/settings.gradle b/dd-smoke-tests/quarkus-native/application/settings.gradle index 0354c75957a..8046ba4dbf2 100644 --- a/dd-smoke-tests/quarkus-native/application/settings.gradle +++ b/dd-smoke-tests/quarkus-native/application/settings.gradle @@ -1,21 +1,4 @@ pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } plugins { id 'io.quarkus' version "${quarkusPluginVersion}" } diff --git a/dd-smoke-tests/quarkus/application/settings.gradle b/dd-smoke-tests/quarkus/application/settings.gradle index aaf3ed2bded..4bfe2f85712 100644 --- a/dd-smoke-tests/quarkus/application/settings.gradle +++ b/dd-smoke-tests/quarkus/application/settings.gradle @@ -1,27 +1,6 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. // The inner `plugins { id 'io.quarkus' ... }` block resolves the Quarkus version from a // `quarkusPluginVersion` Gradle property forwarded by the outer build. pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } plugins { id 'io.quarkus' version "${quarkusPluginVersion}" } diff --git a/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle b/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle index 3a73f18a9c6..a57159662af 100644 --- a/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle +++ b/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // Don't pollute the dependency cache with the build cache diff --git a/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle b/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle index 0a322538e21..1187c16d24e 100644 --- a/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle index 7fcf0cee762..96ec9a392b5 100644 --- a/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // Don't pollute the dependency cache with the build cache diff --git a/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle index a172759b60a..1f8966c8778 100644 --- a/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle index 96c76ec6c8b..587db58a490 100644 --- a/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle b/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle index 4f591488834..a58b3380b70 100644 --- a/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle @@ -1,27 +1,3 @@ -// The `gradlePluginProxy` / `mavenRepositoryProxy` properties point to internal Maven -// mirrors used by CI when the public repos are unreachable; they are forwarded from the -// outer build via the smoke-test plugin. `allowInsecureProtocol` is required because the -// mirrors are reached over plain HTTP inside the CI network. -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // On CI, point the local Gradle build cache to the shared workspace directory under the diff --git a/dd-smoke-tests/springboot-freemarker/application/settings.gradle b/dd-smoke-tests/springboot-freemarker/application/settings.gradle index c35041e5d73..12af0846b7e 100644 --- a/dd-smoke-tests/springboot-freemarker/application/settings.gradle +++ b/dd-smoke-tests/springboot-freemarker/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-java-11/application/settings.gradle b/dd-smoke-tests/springboot-java-11/application/settings.gradle index d2356e2b0b3..459d19a515f 100644 --- a/dd-smoke-tests/springboot-java-11/application/settings.gradle +++ b/dd-smoke-tests/springboot-java-11/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-java-17/application/settings.gradle b/dd-smoke-tests/springboot-java-17/application/settings.gradle index 83e3c7f2135..979436a2a47 100644 --- a/dd-smoke-tests/springboot-java-17/application/settings.gradle +++ b/dd-smoke-tests/springboot-java-17/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle b/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle index dad60537f79..abc215ba298 100644 --- a/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle +++ b/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-jpa/application/settings.gradle b/dd-smoke-tests/springboot-jpa/application/settings.gradle index ff156736e67..a86e33e0dda 100644 --- a/dd-smoke-tests/springboot-jpa/application/settings.gradle +++ b/dd-smoke-tests/springboot-jpa/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle b/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle index 0dbff5f340e..739b6bdefd4 100644 --- a/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle +++ b/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle b/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle index 1c31089a007..81d92ac5271 100644 --- a/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-tomcat/application/settings.gradle b/dd-smoke-tests/springboot-tomcat/application/settings.gradle index c526fe40384..814c6ef9e01 100644 --- a/dd-smoke-tests/springboot-tomcat/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/springboot-velocity/application/settings.gradle b/dd-smoke-tests/springboot-velocity/application/settings.gradle index 0d5e7d082bc..85abf19acf8 100644 --- a/dd-smoke-tests/springboot-velocity/application/settings.gradle +++ b/dd-smoke-tests/springboot-velocity/application/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() if (isCI) { diff --git a/dd-smoke-tests/wildfly/spring-ear/settings.gradle b/dd-smoke-tests/wildfly/spring-ear/settings.gradle index b829474a50b..c19ab8a43bf 100644 --- a/dd-smoke-tests/wildfly/spring-ear/settings.gradle +++ b/dd-smoke-tests/wildfly/spring-ear/settings.gradle @@ -1,23 +1,3 @@ -pluginManagement { - repositories { - mavenLocal() - if (settings.hasProperty("gradlePluginProxy")) { - maven { - url settings["gradlePluginProxy"] - allowInsecureProtocol = true - } - } - if (settings.hasProperty("mavenRepositoryProxy")) { - maven { - url settings["mavenRepositoryProxy"] - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } -} - def isCI = providers.environmentVariable("CI").isPresent() // Don't pollute the dependency cache with the build cache From aad5d223d1df45bbbff7d91936a9d67528d06041 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:24:37 +0200 Subject: [PATCH 5/9] refactor(smoke): drop nested cache blocks Nested smoke-test builds already pass an explicit build-cache flag from the plugin. Removing the per-application CI cache redirects avoids dead settings and fixes the RUM EAR path that pointed outside the cached workspace. --- .../application/settings.gradle | 16 ---------------- .../armeria-grpc/application/settings.gradle | 17 ----------------- .../kafka-2/application/settings.gradle | 16 ---------------- .../kafka-3/application/settings.gradle | 17 ----------------- .../openfeature/application/settings.gradle | 16 ---------------- .../quarkus-native/application/settings.gradle | 13 ------------- .../quarkus/application/settings.gradle | 17 ----------------- .../rum/wildfly-15/rum-ear/settings.gradle | 13 ------------- .../application/settings.gradle | 17 ----------------- .../application/settings.gradle | 13 ------------- .../application/settings.gradle | 17 ----------------- .../application/settings.gradle | 17 ----------------- .../application/settings.gradle | 17 ----------------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../springboot-jpa/application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../application/settings.gradle | 11 ----------- .../wildfly/spring-ear/settings.gradle | 13 ------------- 23 files changed, 318 deletions(-) diff --git a/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle b/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle index 25124c0e4fa..bcaf7090afe 100644 --- a/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle +++ b/dd-smoke-tests/apm-tracing-disabled/application/settings.gradle @@ -1,17 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'apm-tracing-disabled-smoketest' diff --git a/dd-smoke-tests/armeria-grpc/application/settings.gradle b/dd-smoke-tests/armeria-grpc/application/settings.gradle index 5ebcec3df6f..d2e709db66c 100644 --- a/dd-smoke-tests/armeria-grpc/application/settings.gradle +++ b/dd-smoke-tests/armeria-grpc/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='armeria-smoketest' diff --git a/dd-smoke-tests/kafka-2/application/settings.gradle b/dd-smoke-tests/kafka-2/application/settings.gradle index 3da3ede1eba..c5c3c0a333d 100644 --- a/dd-smoke-tests/kafka-2/application/settings.gradle +++ b/dd-smoke-tests/kafka-2/application/settings.gradle @@ -1,17 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'kafka-2-smoketest' diff --git a/dd-smoke-tests/kafka-3/application/settings.gradle b/dd-smoke-tests/kafka-3/application/settings.gradle index ef0a2404b15..e1725dbf1b1 100644 --- a/dd-smoke-tests/kafka-3/application/settings.gradle +++ b/dd-smoke-tests/kafka-3/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='kafka-3-smoketest' diff --git a/dd-smoke-tests/openfeature/application/settings.gradle b/dd-smoke-tests/openfeature/application/settings.gradle index 718d8875152..467bf8a6e1a 100644 --- a/dd-smoke-tests/openfeature/application/settings.gradle +++ b/dd-smoke-tests/openfeature/application/settings.gradle @@ -1,17 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'openfeature-smoketest' diff --git a/dd-smoke-tests/quarkus-native/application/settings.gradle b/dd-smoke-tests/quarkus-native/application/settings.gradle index 8046ba4dbf2..b638bdb51d2 100644 --- a/dd-smoke-tests/quarkus-native/application/settings.gradle +++ b/dd-smoke-tests/quarkus-native/application/settings.gradle @@ -4,17 +4,4 @@ pluginManagement { } } -def isCI = providers.environmentVariable("CI").isPresent() - -// Don't pollute the dependency cache with the build cache -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - // This needs to line up with the code in the outer project settings.gradle - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='quarkus-native-smoketest' diff --git a/dd-smoke-tests/quarkus/application/settings.gradle b/dd-smoke-tests/quarkus/application/settings.gradle index 4bfe2f85712..ba43aae92d5 100644 --- a/dd-smoke-tests/quarkus/application/settings.gradle +++ b/dd-smoke-tests/quarkus/application/settings.gradle @@ -6,21 +6,4 @@ pluginManagement { } } -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='quarkus-smoketest' diff --git a/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle b/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle index a57159662af..6ed979cd530 100644 --- a/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle +++ b/dd-smoke-tests/rum/wildfly-15/rum-ear/settings.gradle @@ -1,16 +1,3 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// Don't pollute the dependency cache with the build cache -if (isCI) { - def sharedRootDir = "$rootDir/../../../../" - buildCache { - local { - // This needs to line up with the code in the outer project settings.gradle - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='wildfly-rum-ear-smoketest' include 'war' diff --git a/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle b/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle index 1187c16d24e..9b9ee52f7cb 100644 --- a/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-2.7-webflux/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='webflux-2.7-smoketest' diff --git a/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle index 96ec9a392b5..6a385f675d4 100644 --- a/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-native/application/settings.gradle @@ -1,14 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// Don't pollute the dependency cache with the build cache -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - // This needs to line up with the code in the outer project settings.gradle - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='native-3.0-smoketest' diff --git a/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle index 1f8966c8778..eaaebc83945 100644 --- a/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webflux/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='webflux-3.0-smoketest' diff --git a/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle b/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle index 587db58a490..000c60beac4 100644 --- a/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.0-webmvc/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='webmvc-3.0-smoketest' diff --git a/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle b/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle index a58b3380b70..865944fcf62 100644 --- a/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle +++ b/dd-smoke-tests/spring-boot-3.3-webmvc/application/settings.gradle @@ -1,18 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// On CI, point the local Gradle build cache to the shared workspace directory under the -// repository root, so cache entries are reused across the many smoke-test nested builds -// (and across CI jobs that mount the same workspace). See f6ec1f5cc8 / #982 for the -// root-level cache, and b34ccbc048 for the `isCI` gating — locally we keep the default -// per-user cache to avoid leaking entries into the repo tree. -// The directory must line up with the outer project's settings.gradle. -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='webmvc-3.3-smoketest' diff --git a/dd-smoke-tests/springboot-freemarker/application/settings.gradle b/dd-smoke-tests/springboot-freemarker/application/settings.gradle index 12af0846b7e..8754dec7bbe 100644 --- a/dd-smoke-tests/springboot-freemarker/application/settings.gradle +++ b/dd-smoke-tests/springboot-freemarker/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-freemarker-smoketest' diff --git a/dd-smoke-tests/springboot-java-11/application/settings.gradle b/dd-smoke-tests/springboot-java-11/application/settings.gradle index 459d19a515f..42e7096d2fb 100644 --- a/dd-smoke-tests/springboot-java-11/application/settings.gradle +++ b/dd-smoke-tests/springboot-java-11/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-java-11-smoketest' diff --git a/dd-smoke-tests/springboot-java-17/application/settings.gradle b/dd-smoke-tests/springboot-java-17/application/settings.gradle index 979436a2a47..6821d57be3a 100644 --- a/dd-smoke-tests/springboot-java-17/application/settings.gradle +++ b/dd-smoke-tests/springboot-java-17/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-java-17-smoketest' diff --git a/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle b/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle index abc215ba298..4f91064eb73 100644 --- a/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle +++ b/dd-smoke-tests/springboot-jetty-jsp/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-jetty-jsp-smoketest' diff --git a/dd-smoke-tests/springboot-jpa/application/settings.gradle b/dd-smoke-tests/springboot-jpa/application/settings.gradle index a86e33e0dda..f3bbc9915fc 100644 --- a/dd-smoke-tests/springboot-jpa/application/settings.gradle +++ b/dd-smoke-tests/springboot-jpa/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-jpa-smoketest' diff --git a/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle b/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle index 739b6bdefd4..995da126473 100644 --- a/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle +++ b/dd-smoke-tests/springboot-thymeleaf/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-thymeleaf-smoketest' diff --git a/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle b/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle index 81d92ac5271..1861e72bcc6 100644 --- a/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat-jsp/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-tomcat-jsp-smoketest' diff --git a/dd-smoke-tests/springboot-tomcat/application/settings.gradle b/dd-smoke-tests/springboot-tomcat/application/settings.gradle index 814c6ef9e01..20dc3c0222b 100644 --- a/dd-smoke-tests/springboot-tomcat/application/settings.gradle +++ b/dd-smoke-tests/springboot-tomcat/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-tomcat-smoketest' diff --git a/dd-smoke-tests/springboot-velocity/application/settings.gradle b/dd-smoke-tests/springboot-velocity/application/settings.gradle index 85abf19acf8..9a60bc37ec2 100644 --- a/dd-smoke-tests/springboot-velocity/application/settings.gradle +++ b/dd-smoke-tests/springboot-velocity/application/settings.gradle @@ -1,12 +1 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name = 'springboot-velocity-smoketest' diff --git a/dd-smoke-tests/wildfly/spring-ear/settings.gradle b/dd-smoke-tests/wildfly/spring-ear/settings.gradle index c19ab8a43bf..23e16079c29 100644 --- a/dd-smoke-tests/wildfly/spring-ear/settings.gradle +++ b/dd-smoke-tests/wildfly/spring-ear/settings.gradle @@ -1,16 +1,3 @@ -def isCI = providers.environmentVariable("CI").isPresent() - -// Don't pollute the dependency cache with the build cache -if (isCI) { - def sharedRootDir = "$rootDir/../../../" - buildCache { - local { - // This needs to line up with the code in the outer project settings.gradle - directory = "$sharedRootDir/workspace/build-cache" - } - } -} - rootProject.name='wildfly-spring-ear-smoketest' include 'war' From 9e57ec8e7d09cfb656528a159d7841a182b0b6be Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 21:50:03 +0200 Subject: [PATCH 6/9] fix(build): gate smoke init scripts in CI Keep repository proxy init scripts as a smoke app convention so NestedGradleBuild only passes --init-script when callers provide scripts. Enable that convention only when CI=true and forward proxy properties from the outer build in that mode. --- .../buildlogic/smoketest/NestedGradleBuild.kt | 40 +++++++-------- .../smoketest/SmokeTestAppExtension.kt | 40 +++++++++++++++ .../smoketest/SmokeTestAppPlugin.kt | 7 ++- .../smoketest/proxy-repositories.init.gradle | 4 +- .../smoketest/SmokeTestAppEndToEndTest.kt | 50 ++++++++++++++++++- 5 files changed, 116 insertions(+), 25 deletions(-) diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt index ef830dbd026..97aa607a73a 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt @@ -54,9 +54,8 @@ abstract class NestedGradleBuild @Inject constructor( gradleDistributionBaseUrl.convention( project.providers.environmentVariable(MASS_READ_URL_ENV), ) - gradlePluginProxy.convention(project.providers.gradleProperty("gradlePluginProxy")) - mavenRepositoryProxy.convention(project.providers.gradleProperty("mavenRepositoryProxy")) - proxyInitScript.convention(PROXY_INIT_SCRIPT) + initScripts.convention(emptyList()) + gradleProperties.convention(emptyMap()) javaLauncher.convention( javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(DEFAULT_NESTED_JAVA_VERSION)) @@ -88,15 +87,10 @@ abstract class NestedGradleBuild @Inject constructor( abstract val gradleDistributionBaseUrl: Property @get:Input - @get:Optional - abstract val gradlePluginProxy: Property + abstract val initScripts: ListProperty @get:Input - @get:Optional - abstract val mavenRepositoryProxy: Property - - @get:Input - abstract val proxyInitScript: Property + abstract val gradleProperties: MapProperty @get:Nested abstract val javaLauncher: Property @@ -157,15 +151,18 @@ abstract class NestedGradleBuild @Inject constructor( val appBuildDirFile = applicationBuildDir.get().asFile val daemonJavaHome = javaLauncher.get().metadata.installationPath.asFile val gradleUserHomeDir = createGradleUserHome() - val proxyInitScriptFile = writeProxyInitScript() + val initScriptFiles = writeInitScripts() val args = buildList { - add("--init-script") - add(proxyInitScriptFile.absolutePath) + initScriptFiles.forEach { script -> + add("--init-script") + add(script.absolutePath) + } add(if (buildCacheEnabled.get()) "--build-cache" else "--no-build-cache") add("-PappBuildDir=${appBuildDirFile.absolutePath}") - addGradleProperty("gradlePluginProxy", gradlePluginProxy.orNull) - addGradleProperty("mavenRepositoryProxy", mavenRepositoryProxy.orNull) + gradleProperties.get().forEach { (name, value) -> + addGradleProperty(name, value) + } projectJars.get().forEach { entry -> add("-P${entry.propertyName.get()}=${entry.file.get().asFile.absolutePath}") } @@ -259,11 +256,12 @@ abstract class NestedGradleBuild @Inject constructor( } } - private fun writeProxyInitScript(): File { - val initScript = temporaryDir.resolve("proxy-repositories.init.gradle") - initScript.writeText(proxyInitScript.get()) - return initScript - } + private fun writeInitScripts(): List = + initScripts.get().mapIndexed { index, script -> + temporaryDir.resolve("init-$index.gradle").also { file -> + file.writeText(script) + } + } private fun findGradleExecutable(gradleUserHomeDir: File): File? = gradleUserHomeDir.walkTopDown().firstOrNull { file -> @@ -307,7 +305,7 @@ private fun MutableList.addGradleProperty(name: String, value: String?) } } -private val PROXY_INIT_SCRIPT: String = +internal val PROXY_REPOSITORIES_INIT_SCRIPT: String = NestedGradleBuild::class.java.getResource("proxy-repositories.init.gradle") ?.readText() ?: error("Missing proxy-repositories.init.gradle resource") diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt index e999d1020ad..231816c547a 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppExtension.kt @@ -65,6 +65,10 @@ abstract class SmokeTestAppExtension @Inject constructor( internal abstract val projectJars: ListProperty + internal abstract val initScripts: ListProperty + + internal abstract val gradleProperties: MapProperty + init { applicationDir.convention(project.layout.projectDirectory.dir("application")) applicationBuildDir.convention(project.layout.buildDirectory.dir("application")) @@ -77,6 +81,28 @@ abstract class SmokeTestAppExtension @Inject constructor( languageVersion.set(JavaLanguageVersion.of(DEFAULT_NESTED_JAVA_VERSION)) }, ) + + val isCi = project.providers.environmentVariable("CI") + .map { it.equals("true", ignoreCase = true) } + .orElse(false) + initScripts.convention( + isCi.map { + if (it) { + listOf(PROXY_REPOSITORIES_INIT_SCRIPT) + } else { + emptyList() + } + }, + ) + gradleProperties.convention( + isCi.map { + if (it) { + proxyGradleProperties() + } else { + emptyMap() + } + }, + ) } /** @@ -189,6 +215,20 @@ abstract class SmokeTestAppExtension @Inject constructor( }, ) } + + private fun proxyGradleProperties(): Map { + val properties = mutableMapOf() + addGradleProperty(properties, "gradlePluginProxy") + addGradleProperty(properties, "mavenRepositoryProxy") + return properties + } + + private fun addGradleProperty(properties: MutableMap, name: String) { + val value = project.providers.gradleProperty(name).orNull + if (!value.isNullOrBlank()) { + properties[name] = value + } + } } /** DSL describing the nested-build invocation for one smoke-test application. */ diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPlugin.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPlugin.kt index b6d6fe6b7ba..06c97503202 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPlugin.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPlugin.kt @@ -3,6 +3,7 @@ package datadog.buildlogic.smoketest import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.withType /** * Exposes the [NestedGradleBuild] task type plus a `smokeTestApp` extension that wires the @@ -16,6 +17,10 @@ import org.gradle.kotlin.dsl.create */ class SmokeTestAppPlugin : Plugin { override fun apply(project: Project) { - project.extensions.create("smokeTestApp") + val extension = project.extensions.create("smokeTestApp") + project.tasks.withType().configureEach { + initScripts.convention(extension.initScripts) + gradleProperties.convention(extension.gradleProperties) + } } } diff --git a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle index 6e4cad11565..ff7399a8483 100644 --- a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle +++ b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle @@ -1,8 +1,8 @@ import org.gradle.api.initialization.resolve.RepositoriesMode beforeSettings { settings -> - def gradlePluginProxy = settings.findProperty("gradlePluginProxy") - def mavenRepositoryProxy = settings.findProperty("mavenRepositoryProxy") + def gradlePluginProxy = settings.providers.gradleProperty("gradlePluginProxy").orNull + def mavenRepositoryProxy = settings.providers.gradleProperty("mavenRepositoryProxy").orNull settings.pluginManagement { repositories { diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index b89f9f506ca..443b031b6b3 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -287,11 +287,58 @@ class SmokeTestAppEndToEndTest { assertThat(inputsFile).exists() assertThat(inputsFile.readLines()).contains( "graalvm=test-graalvm", - "agentPath=${projectDir.resolve("agent.jar").toFile().absolutePath}", + "agentPath=${projectDir.resolve("agent.jar").toFile().canonicalPath}", "nativeEnabled=true", ) } + @Test + fun `init scripts are not added outside CI`() { + writeOuterSettings() + outerBuild.writeText( + """ + plugins { + java + id("dd-trace-java.smoke-test-app") + } + + smokeTestApp { + javaLauncher.set( + javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } + ) + application { + taskName.set("recordInitScripts") + artifactPath.set("init-script-count.txt") + sysProperty.set("init.script.count.path") + } + } + """.trimIndent(), + ) + writeInnerSettings() + writeInnerBuild( + """ + tasks.register("recordInitScripts") { + val out = layout.buildDirectory.file("init-script-count.txt") + outputs.file(out) + val initScriptCount = gradle.startParameter.initScripts.size + doLast { + out.get().asFile.writeText(initScriptCount.toString()) + } + } + """.trimIndent(), + ) + + val result = runner( + "recordInitScripts", + environment = mapOf("CI" to "false"), + ).build() + + assertThat(result.task(":recordInitScripts")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val countFile = File(projectDir.toFile(), "build/application/init-script-count.txt") + assertThat(countFile).exists() + assertThat(countFile.readText()).isEqualTo("0") + } + @Test fun `init script injects Maven repository proxy into nested settings`() { writeOuterSettings() @@ -351,6 +398,7 @@ class SmokeTestAppEndToEndTest { val result = runner( "resolveDependency", "-PmavenRepositoryProxy=${repository.toURI()}", + environment = mapOf("CI" to "true"), ).build() assertThat(result.task(":resolveDependency")?.outcome).isEqualTo(TaskOutcome.SUCCESS) From aef7532cb68642532534d177dddbf6ce843fe268 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 22:28:40 +0200 Subject: [PATCH 7/9] fix(build): prepend smoke Maven proxies Use a Kotlin init script that configures plugin repositories in beforeSettings and registers a beforeProject hook to add Maven proxy repositories before project build scripts add their own repositories. This keeps project repositories available while making the CI proxy repositories first in nested smoke-test builds. --- .../buildlogic/smoketest/NestedGradleBuild.kt | 6 +- .../smoketest/proxy-repositories.init.gradle | 40 ------- .../proxy-repositories.init.gradle.kts | 41 +++++++ .../smoketest/SmokeTestAppEndToEndTest.kt | 105 ++++++++++++++++-- 4 files changed, 137 insertions(+), 55 deletions(-) delete mode 100644 build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle create mode 100644 build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts diff --git a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt index 97aa607a73a..2e7f06c93ab 100644 --- a/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt +++ b/build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt @@ -258,7 +258,7 @@ abstract class NestedGradleBuild @Inject constructor( private fun writeInitScripts(): List = initScripts.get().mapIndexed { index, script -> - temporaryDir.resolve("init-$index.gradle").also { file -> + temporaryDir.resolve("init-$index.init.gradle.kts").also { file -> file.writeText(script) } } @@ -306,6 +306,6 @@ private fun MutableList.addGradleProperty(name: String, value: String?) } internal val PROXY_REPOSITORIES_INIT_SCRIPT: String = - NestedGradleBuild::class.java.getResource("proxy-repositories.init.gradle") + NestedGradleBuild::class.java.getResource("proxy-repositories.init.gradle.kts") ?.readText() - ?: error("Missing proxy-repositories.init.gradle resource") + ?: error("Missing proxy-repositories.init.gradle.kts resource") diff --git a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle deleted file mode 100644 index ff7399a8483..00000000000 --- a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle +++ /dev/null @@ -1,40 +0,0 @@ -import org.gradle.api.initialization.resolve.RepositoriesMode - -beforeSettings { settings -> - def gradlePluginProxy = settings.providers.gradleProperty("gradlePluginProxy").orNull - def mavenRepositoryProxy = settings.providers.gradleProperty("mavenRepositoryProxy").orNull - - settings.pluginManagement { - repositories { - mavenLocal() - if (gradlePluginProxy) { - maven { - url = settings.uri(gradlePluginProxy) - allowInsecureProtocol = true - } - } - if (mavenRepositoryProxy) { - maven { - url = settings.uri(mavenRepositoryProxy) - allowInsecureProtocol = true - } - } - gradlePluginPortal() - mavenCentral() - } - } - - settings.dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) - repositories { - mavenLocal() - if (mavenRepositoryProxy) { - maven { - url = settings.uri(mavenRepositoryProxy) - allowInsecureProtocol = true - } - } - mavenCentral() - } - } -} diff --git a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts new file mode 100644 index 00000000000..fa19da6489b --- /dev/null +++ b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts @@ -0,0 +1,41 @@ +import org.gradle.api.Project +import org.gradle.api.initialization.Settings +import org.gradle.kotlin.dsl.closureOf + +beforeSettings(closureOf { + val gradlePluginProxy = providers.gradleProperty("gradlePluginProxy").orNull + val mavenRepositoryProxy = providers.gradleProperty("mavenRepositoryProxy").orNull + + pluginManagement { + repositories { + mavenLocal() + gradlePluginProxy?.takeIf { it.isNotBlank() }?.let { proxy -> + maven { + url = java.net.URI(proxy) + isAllowInsecureProtocol = true + } + } + mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.let { proxy -> + maven { + url = java.net.URI(proxy) + isAllowInsecureProtocol = true + } + } + gradlePluginPortal() + mavenCentral() + } + } + + gradle.beforeProject(closureOf { + repositories { + mavenLocal() + mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.let { proxy -> + maven { + url = java.net.URI(proxy) + isAllowInsecureProtocol = true + } + } + mavenCentral() + } + }) +}) diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index 443b031b6b3..2596574262c 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -340,22 +340,81 @@ class SmokeTestAppEndToEndTest { } @Test - fun `init script injects Maven repository proxy into nested settings`() { + fun `init script prepends Maven proxy repositories without overriding project repositories`() { writeOuterSettings() - val repository = projectDir.resolve("maven-repo").toFile() - val artifactDir = File(repository, "com/example/demo/1.0") - artifactDir.mkdirs() - File(artifactDir, "demo-1.0.pom").writeText( + val proxyRepository = projectDir.resolve("proxy-maven-repo").toFile() + val projectRepository = projectDir.resolve("project-maven-repo").toFile() + writeMavenArtifact(proxyRepository, "com.example", "shared", "1.0", "proxy") + writeMavenArtifact(projectRepository, "com.example", "shared", "1.0", "project") + writeMavenArtifact(projectRepository, "com.example", "project-only", "1.0", "project-only") + outerBuild.writeText( """ - - 4.0.0 - com.example - demo - 1.0 - + plugins { + java + id("dd-trace-java.smoke-test-app") + } + + smokeTestApp { + javaLauncher.set( + javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } + ) + application { + taskName.set("resolveRepositories") + artifactPath.set("resolved-repositories.txt") + sysProperty.set("resolved.repositories.path") + } + } + """.trimIndent(), + ) + writeInnerSettings() + writeInnerBuild( + """ + repositories { + maven { + url = uri("${projectRepository.toURI()}") + } + } + + dependencies { + implementation("com.example:shared:1.0") + implementation("com.example:project-only:1.0") + } + + tasks.register("resolveRepositories") { + val resolved = layout.buildDirectory.file("resolved-repositories.txt") + inputs.files(configurations.compileClasspath) + outputs.file(resolved) + doLast { + resolved.get().asFile.writeText( + configurations.compileClasspath.get() + .sortedBy { it.name } + .joinToString(System.lineSeparator()) { it.name + "=" + it.readText() } + ) + } + } """.trimIndent(), ) - File(artifactDir, "demo-1.0.jar").writeText("demo") + + val result = runner( + "resolveRepositories", + "-PmavenRepositoryProxy=${proxyRepository.toURI()}", + environment = mapOf("CI" to "true"), + ).build() + + assertThat(result.task(":resolveRepositories")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + val resolvedFile = File(projectDir.toFile(), "build/application/resolved-repositories.txt") + assertThat(resolvedFile).exists() + assertThat(resolvedFile.readLines()).containsExactly( + "project-only-1.0.jar=project-only", + "shared-1.0.jar=proxy", + ) + } + + @Test + fun `init script injects Maven repository proxy into nested build`() { + writeOuterSettings() + val repository = projectDir.resolve("maven-repo").toFile() + writeMavenArtifact(repository, "com.example", "demo", "1.0", "demo") outerBuild.writeText( """ plugins { @@ -580,6 +639,28 @@ class SmokeTestAppEndToEndTest { ) } + private fun writeMavenArtifact( + repository: File, + groupId: String, + artifactId: String, + version: String, + jarContent: String, + ) { + val artifactDir = File(repository, "${groupId.replace('.', '/')}/$artifactId/$version") + artifactDir.mkdirs() + File(artifactDir, "$artifactId-$version.pom").writeText( + """ + + 4.0.0 + $groupId + $artifactId + $version + + """.trimIndent(), + ) + File(artifactDir, "$artifactId-$version.jar").writeText(jarContent) + } + private fun runner( vararg args: String, environment: Map? = null, From 465ed56aedc7457e2433efe9d2fca389fe3b02bd Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Thu, 4 Jun 2026 22:42:04 +0200 Subject: [PATCH 8/9] fix(build): use Action hooks in smoke init script Use Gradle Action callbacks in the Kotlin init script instead of Kotlin DSL closure helpers. This keeps the script on non-Groovy hook overloads while still running early enough to prepend plugin and project Maven proxy repositories. --- .../buildlogic/smoketest/proxy-repositories.init.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts index fa19da6489b..70fe8054b90 100644 --- a/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts +++ b/build-logic/smoke-test/src/main/resources/datadog/buildlogic/smoketest/proxy-repositories.init.gradle.kts @@ -1,8 +1,8 @@ +import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.initialization.Settings -import org.gradle.kotlin.dsl.closureOf -beforeSettings(closureOf { +gradle.beforeSettings(Action { val gradlePluginProxy = providers.gradleProperty("gradlePluginProxy").orNull val mavenRepositoryProxy = providers.gradleProperty("mavenRepositoryProxy").orNull @@ -26,7 +26,7 @@ beforeSettings(closureOf { } } - gradle.beforeProject(closureOf { + gradle.beforeProject(Action { repositories { mavenLocal() mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.let { proxy -> From 75f9beebff7b92a8dcb69f4bd9087bba003fd3b6 Mon Sep 17 00:00:00 2001 From: Brice Dutheil Date: Fri, 5 Jun 2026 10:43:43 +0200 Subject: [PATCH 9/9] ci(smoke-tests): review comments --- .../smoketest/SmokeTestAppEndToEndTest.kt | 408 ++++++------------ .../smoketest/SmokeTestAppPluginTest.kt | 39 +- 2 files changed, 161 insertions(+), 286 deletions(-) diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt index 2596574262c..b8e8cd757f1 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppEndToEndTest.kt @@ -30,61 +30,22 @@ class SmokeTestAppEndToEndTest { private val outerSettings get() = projectDir.resolve("settings.gradle.kts").toFile() private val outerBuild get() = projectDir.resolve("build.gradle.kts").toFile() private val applicationDir get() = projectDir.resolve("application").toFile() + private val applicationBuildDir get() = projectDir.resolve("build/application").toFile() @BeforeEach fun setUp() { applicationDir.mkdirs() } - @Test - fun `application block registers a NestedGradleBuild task with the configured name`() { - writeOuterSettings() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("packageApp") - artifactPath.set("libs/test.jar") - sysProperty.set("test.path") - } - } - """.trimIndent(), - ) - - val result = runner("tasks", "--all").build() - - assertThat(result.output).contains("packageApp") - } - @Test fun `nested build produces the configured artifact`() { writeOuterSettings() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("buildJar") - artifactPath.set("libs/sample.jar") - sysProperty.set("sample.path") - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "buildJar", + artifactPath = "libs/sample.jar", + sysProperty = "sample.path", + ), ) writeInnerSettings() writeInnerBuild( @@ -101,68 +62,7 @@ class SmokeTestAppEndToEndTest { val result = runner("buildJar").build() assertThat(result.task(":buildJar")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - assertThat(File(projectDir.toFile(), "build/application/libs/sample.jar")).exists() - } - - @Test - fun `plugin is a no-op when the application block is never called`() { - writeOuterSettings() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - // No application block, no javaLauncher — should not blow up. - } - """.trimIndent(), - ) - - val result = runner("help").build() - - assertThat(result.output).contains("BUILD SUCCESSFUL") - } - - @Test - fun `manual NestedGradleBuild task registration works without the application block`() { - writeOuterSettings() - outerBuild.writeText( - """ - import datadog.buildlogic.smoketest.NestedGradleBuild - - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - tasks.register("customBuild") { - applicationDir.set(layout.projectDirectory.dir("application")) - applicationBuildDir.set(layout.buildDirectory.dir("application")) - gradleVersion.set(gradle.gradleVersion) - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - tasksToRun.set(listOf("buildJar")) - } - """.trimIndent(), - ) - writeInnerSettings() - writeInnerBuild( - """ - tasks.register("buildJar") { - archiveFileName.set("custom.jar") - from(file("src")) - } - """.trimIndent(), - ) - File(applicationDir, "src").mkdir() - File(applicationDir, "src/hello.txt").writeText("hi") - - val result = runner("customBuild").build() - - assertThat(result.task(":customBuild")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + assertThat(applicationOutput("libs/sample.jar")).exists() } @Test @@ -170,24 +70,12 @@ class SmokeTestAppEndToEndTest { writeOuterSettings() val inheritedGradleUserHome = projectDir.resolve("inherited-gradle-user-home").toFile() inheritedGradleUserHome.mkdirs() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("recordGradleEnvironment") - artifactPath.set("gradle-env.txt") - sysProperty.set("gradle.env.path") - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "recordGradleEnvironment", + artifactPath = "gradle-env.txt", + sysProperty = "gradle.env.path", + ), ) writeInnerSettings() writeInnerBuild( @@ -219,7 +107,7 @@ class SmokeTestAppEndToEndTest { ).build() assertThat(result.task(":recordGradleEnvironment")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val envFile = File(projectDir.toFile(), "build/application/gradle-env.txt") + val envFile = applicationOutput("gradle-env.txt") assertThat(envFile).exists() val lines = envFile.readLines() assertThat(lines).contains( @@ -239,27 +127,19 @@ class SmokeTestAppEndToEndTest { fun `nested build receives native app environment and provider backed file inputs`() { writeOuterSettings() File(projectDir.toFile(), "agent.jar").writeText("agent") - outerBuild.writeText( + writeSmokeTestAppBuild( """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("recordNativeInputs") - artifactPath.set("native-inputs.txt") - sysProperty.set("native.inputs.path") - buildArguments.add("-Dnative.enabled=true") - environment.put("GRAALVM_HOME", providers.provider { "test-graalvm" }) - } - projectJar("agentPath", providers.provider { layout.projectDirectory.file("agent.jar") }) - } - """.trimIndent(), + ${smokeTestApplication( + taskName = "recordNativeInputs", + artifactPath = "native-inputs.txt", + sysProperty = "native.inputs.path", + additionalConfig = """ + buildArguments.add("-Dnative.enabled=true") + environment.put("GRAALVM_HOME", providers.provider { "test-graalvm" }) + """, + )} + projectJar("agentPath", providers.provider { layout.projectDirectory.file("agent.jar") }) + """, ) writeInnerSettings() writeInnerBuild( @@ -283,7 +163,7 @@ class SmokeTestAppEndToEndTest { val result = runner("recordNativeInputs").build() assertThat(result.task(":recordNativeInputs")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val inputsFile = File(projectDir.toFile(), "build/application/native-inputs.txt") + val inputsFile = applicationOutput("native-inputs.txt") assertThat(inputsFile).exists() assertThat(inputsFile.readLines()).contains( "graalvm=test-graalvm", @@ -295,24 +175,12 @@ class SmokeTestAppEndToEndTest { @Test fun `init scripts are not added outside CI`() { writeOuterSettings() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("recordInitScripts") - artifactPath.set("init-script-count.txt") - sysProperty.set("init.script.count.path") - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "recordInitScripts", + artifactPath = "init-script-count.txt", + sysProperty = "init.script.count.path", + ), ) writeInnerSettings() writeInnerBuild( @@ -334,7 +202,7 @@ class SmokeTestAppEndToEndTest { ).build() assertThat(result.task(":recordInitScripts")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val countFile = File(projectDir.toFile(), "build/application/init-script-count.txt") + val countFile = applicationOutput("init-script-count.txt") assertThat(countFile).exists() assertThat(countFile.readText()).isEqualTo("0") } @@ -347,24 +215,12 @@ class SmokeTestAppEndToEndTest { writeMavenArtifact(proxyRepository, "com.example", "shared", "1.0", "proxy") writeMavenArtifact(projectRepository, "com.example", "shared", "1.0", "project") writeMavenArtifact(projectRepository, "com.example", "project-only", "1.0", "project-only") - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("resolveRepositories") - artifactPath.set("resolved-repositories.txt") - sysProperty.set("resolved.repositories.path") - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "resolveRepositories", + artifactPath = "resolved-repositories.txt", + sysProperty = "resolved.repositories.path", + ), ) writeInnerSettings() writeInnerBuild( @@ -402,7 +258,7 @@ class SmokeTestAppEndToEndTest { ).build() assertThat(result.task(":resolveRepositories")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val resolvedFile = File(projectDir.toFile(), "build/application/resolved-repositories.txt") + val resolvedFile = applicationOutput("resolved-repositories.txt") assertThat(resolvedFile).exists() assertThat(resolvedFile.readLines()).containsExactly( "project-only-1.0.jar=project-only", @@ -410,62 +266,6 @@ class SmokeTestAppEndToEndTest { ) } - @Test - fun `init script injects Maven repository proxy into nested build`() { - writeOuterSettings() - val repository = projectDir.resolve("maven-repo").toFile() - writeMavenArtifact(repository, "com.example", "demo", "1.0", "demo") - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("resolveDependency") - artifactPath.set("resolved-dependency.txt") - sysProperty.set("resolved.dependency.path") - } - } - """.trimIndent(), - ) - writeInnerSettings() - writeInnerBuild( - """ - dependencies { - implementation("com.example:demo:1.0") - } - - tasks.register("resolveDependency") { - val resolved = layout.buildDirectory.file("resolved-dependency.txt") - inputs.files(configurations.compileClasspath) - outputs.file(resolved) - doLast { - resolved.get().asFile.writeText( - configurations.compileClasspath.get().singleFile.name - ) - } - } - """.trimIndent(), - ) - - val result = runner( - "resolveDependency", - "-PmavenRepositoryProxy=${repository.toURI()}", - environment = mapOf("CI" to "true"), - ).build() - - assertThat(result.task(":resolveDependency")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val resolvedFile = File(projectDir.toFile(), "build/application/resolved-dependency.txt") - assertThat(resolvedFile).exists() - assertThat(resolvedFile.readText()).isEqualTo("demo-1.0.jar") - } - /** * `buildCacheEnabled` defaults to `false` and is plumbed through to the nested daemon as * an explicit `--no-build-cache` / `--build-cache` argument. The inner build records @@ -480,25 +280,13 @@ class SmokeTestAppEndToEndTest { expectedFlag: String, ) { writeOuterSettings() - outerBuild.writeText( - """ - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("recordCacheFlag") - artifactPath.set("cache-flag.txt") - sysProperty.set("cache.flag.path") - $dslLine - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "recordCacheFlag", + artifactPath = "cache-flag.txt", + sysProperty = "cache.flag.path", + additionalConfig = dslLine, + ), ) writeInnerSettings() writeInnerBuild( @@ -517,7 +305,7 @@ class SmokeTestAppEndToEndTest { val result = runner("recordCacheFlag").build() assertThat(result.task(":recordCacheFlag")?.outcome).isEqualTo(TaskOutcome.SUCCESS) - val flagFile = File(projectDir.toFile(), "build/application/cache-flag.txt") + val flagFile = applicationOutput("cache-flag.txt") assertThat(flagFile).exists() assertThat(flagFile.readText().trim()).isEqualTo(expectedFlag) } @@ -542,28 +330,15 @@ class SmokeTestAppEndToEndTest { expectedSecondOutcome: TaskOutcome, ) { writeOuterSettings(withLocalBuildCache = true) - outerBuild.writeText( - """ - $extraOuterImports - plugins { - java - id("dd-trace-java.smoke-test-app") - } - - $extraOuterPreamble - - smokeTestApp { - javaLauncher.set( - javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()})) } - ) - application { - taskName.set("buildJar") - artifactPath.set("libs/sample.jar") - sysProperty.set("sample.path") - $envDslLine - } - } - """.trimIndent(), + writeSmokeTestAppBuild( + smokeTestApplication( + taskName = "buildJar", + artifactPath = "libs/sample.jar", + sysProperty = "sample.path", + additionalConfig = envDslLine, + ), + extraImports = extraOuterImports, + extraPreamble = extraOuterPreamble, ) writeInnerSettings() writeInnerBuild( @@ -586,7 +361,7 @@ class SmokeTestAppEndToEndTest { assertThat(first.task(":buildJar")?.outcome).isEqualTo(TaskOutcome.SUCCESS) // Wipe the output dir so the cache must serve it on the next run. - File(projectDir.toFile(), "build/application").deleteRecursively() + applicationBuildDir.deleteRecursively() val secondArgs = listOfNotNull( "buildJar", @@ -617,6 +392,66 @@ class SmokeTestAppEndToEndTest { ) } + private fun writeOuterBuild(buildScript: String) { + outerBuild.writeText(buildScript.trimIndent()) + } + + private fun writeSmokeTestAppBuild( + smokeTestAppBody: String, + extraImports: String = "", + extraPreamble: String = "", + ) { + val imports = extraImports.trimIndent() + val preamble = extraPreamble.trimIndent() + val body = smokeTestAppBody.trimIndent() + writeOuterBuild( + buildString { + if (imports.isNotBlank()) { + appendLine(imports) + appendLine() + } + appendLine("plugins {") + appendLine(" java") + appendLine(" id(\"dd-trace-java.smoke-test-app\")") + appendLine("}") + appendLine() + if (preamble.isNotBlank()) { + appendLine(preamble) + appendLine() + } + appendLine("smokeTestApp {") + appendLine(" javaLauncher.set(") + appendLine(" javaToolchains.launcherFor {") + appendLine(" languageVersion.set(JavaLanguageVersion.of(${currentMajorJdk()}))") + appendLine(" }") + appendLine(" )") + if (body.isNotBlank()) { + appendLine(body.prependIndent(" ")) + } + appendLine("}") + }, + ) + } + + private fun smokeTestApplication( + taskName: String, + artifactPath: String, + sysProperty: String, + additionalConfig: String = "", + ): String { + val config = additionalConfig.trimIndent() + return buildString { + appendLine("application {") + appendLine(" taskName.set(\"$taskName\")") + appendLine(" artifactPath.set(\"$artifactPath\")") + appendLine(" sysProperty.set(\"$sysProperty\")") + if (config.isNotBlank()) { + appendLine(config.prependIndent(" ")) + } + appendLine("}") + } + } + private fun writeInnerSettings() { File(applicationDir, "settings.gradle.kts").writeText( """ @@ -639,6 +474,9 @@ class SmokeTestAppEndToEndTest { ) } + private fun applicationOutput(relativePath: String): File = + applicationBuildDir.resolve(relativePath) + private fun writeMavenArtifact( repository: File, groupId: String, diff --git a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPluginTest.kt b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPluginTest.kt index 7fa9d7c09f9..9df643a976c 100644 --- a/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPluginTest.kt +++ b/build-logic/smoke-test/src/test/kotlin/datadog/buildlogic/smoketest/SmokeTestAppPluginTest.kt @@ -68,22 +68,59 @@ class SmokeTestAppPluginTest { } @Test - fun `application task receives configured Gradle distribution base URL`() { + fun `application block registers NestedGradleBuild task with configured inputs`() { val project = ProjectBuilder.builder().build() project.apply() project.plugins.apply("dd-trace-java.smoke-test-app") val extension = project.extensions.getByType() + extension.gradleVersion.set("8.14.5") extension.gradleDistributionBaseUrl.set("https://mass.example") extension.application { taskName.set("packageApp") artifactPath.set("libs/test.jar") sysProperty.set("test.path") + nestedTasks.set(listOf("assemble", "check")) + buildArguments.add("-Ddemo=true") + environment.put("DEMO_ENV", "true") + buildCacheEnabled.set(true) } val task = project.tasks.getByName("packageApp") as NestedGradleBuild + assertThat(task.applicationDir.get().asFile) + .isEqualTo(project.layout.projectDirectory.dir("application").asFile) + assertThat(task.applicationBuildDir.get().asFile) + .isEqualTo(project.layout.buildDirectory.dir("application").get().asFile) + assertThat(task.gradleVersion.get()).isEqualTo("8.14.5") assertThat(task.gradleDistributionBaseUrl.get()).isEqualTo("https://mass.example") + assertThat(task.tasksToRun.get()).containsExactly("assemble", "check") + assertThat(task.buildArguments.get()).containsExactly("-Ddemo=true") + assertThat(task.environment.get()).containsEntry("DEMO_ENV", "true") + assertThat(task.buildCacheEnabled.get()).isTrue() + } + + @Test + fun `manual NestedGradleBuild task receives smokeTestApp conventions`() { + val project = ProjectBuilder.builder().build() + project.apply() + project.plugins.apply("dd-trace-java.smoke-test-app") + + val extension = project.extensions.getByType() + extension.initScripts.set(listOf("init-script")) + extension.gradleProperties.set( + mapOf("mavenRepositoryProxy" to "https://repo.example"), + ) + + val task = project.tasks.register("customBuild", NestedGradleBuild::class.java) { + applicationDir.set(project.layout.projectDirectory.dir("application")) + applicationBuildDir.set(project.layout.buildDirectory.dir("application")) + tasksToRun.set(listOf("buildJar")) + }.get() + + assertThat(task.initScripts.get()).containsExactly("init-script") + assertThat(task.gradleProperties.get()) + .containsEntry("mavenRepositoryProxy", "https://repo.example") } @Test