Add smoke-test plugin for nested Gradle builds#11405
Add smoke-test plugin for nested Gradle builds#11405gh-worker-dd-mergequeue-cf854d[bot] merged 4 commits into
Conversation
Adds a new included build `build-logic/` hosting a single subproject
`smoke-test` that exposes the `dd-trace-java.smoke-test-app` plugin.
The plugin contributes:
- `NestedGradleBuild` task type that runs a nested Gradle build via the
Gradle Tooling API. It pins the nested Gradle version (no committed
per-application wrappers), uses the configured Java toolchain for the
nested daemon, forwards artifact paths from the root build as
`-P<name>=<path>`, and redirects the nested `buildDir` via
`-PappBuildDir=<path>` so outputs land under the outer project's build
directory.
- `smokeTestApp` project extension with an `application { ... }` block
that registers the `NestedGradleBuild` task, wires it into every `Test`
task via `dependsOn` + a `jvmArgumentProvider` for the produced
artifact's system property. Consumers can also register
`NestedGradleBuild` directly when they need more control; the plugin
is a no-op until `application` or a manual registration is done.
- `projectJar(name, project)` helper that forwards a sibling project's
jar to the nested build through a resolvable `Configuration` (avoids
`evaluationDependsOn` and the cross-project access ordering issues).
The plugin is verified with JUnit 5 unit tests (`ProjectBuilder`) and
end-to-end tests that drive the Tooling API path through the Gradle Test
Kit with a temporary Kotlin-DSL test project.
`build-logic/settings.gradle.kts` references the existing
`gradle/libs.versions.toml` catalog (mirroring `buildSrc/`) so the
plugin can use the same library coordinates as the rest of the repo.
The Gradle libs Maven repository (`https://repo.gradle.org/gradle/libs-releases`,
scoped to `org.gradle:`) is added to the root build's `pluginManagement`
and to `gradle/repositories.gradle` so the Tooling API jar resolves.
Smoke-test modules with Spring Boot plugin versions incompatible with
Gradle 9 will use this plugin in follow-up PRs instead of a committed
Gradle 8 wrapper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5824d8024
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…14.5
Set conventions on `smokeTestApp`:
- `gradleVersion` defaults to `"8.14.5"` (Gradle 8 last release; pinned because
Spring Boot plugin pre-3.5 calls `Configuration.getUploadTaskName()`, removed
in Gradle 9).
- `javaLauncher` defaults to a JDK 21 toolchain (the version the root build
requires for its own Gradle 9 migration; standardising the nested daemon on
the same JDK avoids requiring an extra toolchain on dev machines and CI
runners).
Consumers that need a different JDK or Gradle version still override
explicitly. The inner build script is responsible for pinning the produced
bytecode level (`java { sourceCompatibility = JavaVersion.VERSION_1_8 }` or
similar) — Gradle adds `--release N` automatically when source/target differs
from the daemon JVM.
`JavaToolchainService` is now injected into the extension; this works in any
project where a `java*` (or related) plugin is applied. Smoke-test modules
already apply `gradle/java.gradle`, which applies `java`, so the convention
resolves on first read.
Public defaults exposed as `DEFAULT_NESTED_GRADLE_VERSION` and
`DEFAULT_NESTED_JAVA_VERSION` constants so the values are discoverable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c6d9744 to
1562192
Compare
This comment has been minimized.
This comment has been minimized.
…ugin
Switch the plugin sources and unit tests over to the typed
`org.gradle.kotlin.dsl` extension functions where they replace
`::class.java` boilerplate:
- `tasks.register(name, Type::class.java) { … }` → `tasks.register<Type>(name) { … }`
- `tasks.withType(Type::class.java).configureEach { … }` → `tasks.withType<Type>().configureEach { … }`
- `extensions.create("name", Type::class.java)` → `extensions.create<Type>("name")`
- `extensions.getByType(Type::class.java)` → `extensions.getByType<Type>()`
- `extensions.findByName("name")` (followed by `isInstanceOf`) → `extensions.findByType<Type>()`
- `project.plugins.apply(Plugin::class.java)` → `project.apply<Plugin>()` (PluginAware)
- `objects.newInstance(Type::class.java)` → `objects.newInstance<Type>()`
Also drop the six `captured*` local variables in `SmokeTestAppExtension.application` —
inside `tasks.register<NestedGradleBuild>(taskName) { … }` the outer extension's
properties are now reached via `this@SmokeTestAppExtension.<prop>` directly.
No behavioural change; the 9 plugin tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
/merge |
|
View all feedbacks in Devflow UI.
This pull request is not mergeable according to GitHub. Common reasons include pending required checks, missing approvals, or merge conflicts — but it could also be blocked by other repository rules or settings.
The expected merge time in
|
…test plugin Drop-in conversion of ten more nested-build smoke tests to the `dd-trace-java.smoke-test-app` plugin (added in #11405). All ten previously used an `Exec` task that shelled out to a `gradlew` — either the root build's (now Gradle 9, incompatible with their plugin chain) or a committed inner wrapper. Spring Boot 3 / Gradle nested build, root-gradlew Exec: - `spring-boot-3.0-webflux` - `spring-boot-3.0-webmvc` - `spring-boot-3.3-webmvc` - `kafka-3` Non-Spring Gradle nested build, root-gradlew Exec: - `quarkus` (Quarkus 1.9.2 platform, Java 8) - `armeria-grpc` Inner Gradle wrapper (committed) → Tooling API: - `vertx-3.4`, `vertx-3.9`, `vertx-3.9-resteasy`, `vertx-4.2` The committed inner `gradlew` / `gradlew.bat` / `gradle/wrapper/` files are removed — the Tooling API pins the same Gradle 8.14.5 distribution the wrappers used. Each module's outer `build.gradle` collapses to a small `smokeTestApp { application { taskName / nestedTasks / artifactPath / sysProperty } projectJar(...) }` block. The daemon Gradle version + JDK 21 toolchain come from the plugin's conventions. Each inner `application/build.gradle` pins `sourceCompatibility` explicitly so JDK 21's javac cross-compiles to the right bytecode level (`--release`): Java 8 for `quarkus` and the vertx modules, Java 17 for the rest. `kafka-3` swaps its `toolchain.languageVersion` for `sourceCompatibility` to avoid pulling a separate JDK 17 toolchain on top of the daemon's JDK 21. Verified locally on Gradle 9.5.1: all ten nested builds produce their expected artifact; representative smoke tests (`spring-boot-3.0-webmvc`, `kafka-3`, `vertx-3.9`) pass with `-PskipFlakyTests=true`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
What Does This Do
Adds an included build
build-logic/with a single subprojectsmoke-testexposing thedd-trace-java.smoke-test-appplugin.The plugin contributes a
NestedGradleBuildtask type that runs a nested Gradle build via the Gradle Tooling API, plus asmokeTestApp { application { … } }project extension that registers and wires the task. The nested build pins its own Gradle version and Java toolchain — no committed per-applicationgradlewwrappers, noExec-style invocation of an externalgradlewscript.The plugin is a strict no-op unless the consumer configures
smokeTestApp.application { … }or registers aNestedGradleBuildtask manually. Consumers that need more control over task wiring can use the lower-level form.Public surface, in one outer
build.gradle:plugins { id 'dd-trace-java.smoke-test-app' } smokeTestApp { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(8) } application { taskName = 'bootJar' artifactPath = 'libs/foo-smoketest.jar' sysProperty = 'datadog.smoketest.springboot.shadowJar.path' } // Optional: forward a sibling project's jar to the nested build as -P<name>=<path>. projectJar('iastUtilJar', project(':dd-smoke-tests:iast-util')) }Follow-up PRs
earBuildtasks to the smoke-test plugin #11417Motivation
The Spring Boot Gradle plugin pre-3.5.0 calls
Configuration.getUploadTaskName(), removed in Gradle 9. ~14 smoke-test modules depend on Spring Boot plugin versions 2.5–2.7 and so block the root build's Gradle 9 migration.PR #11379 explored solving this by extracting each affected module's app source into a self-contained
application/Gradle subproject with a committed Gradle 8.14.5 wrapper (jar + properties +gradlew/gradlew.bat). That branch grew from 4 to 22 committed wrappers and inlined theExecboilerplate in every outerbuild.gradle. Review feedback flagged the wrapper surface and the missing inputs/outputs wiring as concerns.This PR adds the infrastructure for an alternative approach: keep the nested
application/subproject shape, but use the Gradle Tooling API to run the nested build — no committed wrappers, distributions are downloaded/cached once by the host Gradle, and the per-app boilerplate collapses into a single typed task type or a small DSL block.The follow-up PRs (Pattern B/C/D) actually convert the affected modules; this PR only ships the plugin and its tests.
Additional Notes
There's a new included build
build-logic/with one subproject (smoke-test) for a single plugin id (dd-trace-java.smoke-test-app). The reason for this aredd-trace-java.smoke-test-appwas inbuildSrcit would add its dependencies in anything that consumes buildSrc plugins. Given this is very specific to some smoke tests, it is preferable to isolate it.buildSrc/will be. They are some issue with the (legacy)buildSrc/way, more details here, in Gradle best practices. Initiating this project now makes sense.Also
build-logic/settings.gradle.ktsreferences the existinggradle/libs.versions.tomlcatalog (mirroringbuildSrc/), so the plugin uses the same library coordinates as the rest of the repo.https://repo.gradle.org/gradle/libs-releases, scoped toorg.gradle:) is added to the root build'spluginManagementand togradle/repositories.gradle— the Tooling API jar isn't on Maven Central.SmokeTestAppPluginTestusesProjectBuilderfor fast in-process checks of extension wiring and defaults.SmokeTestAppEndToEndTestuses Gradle Test Kit + a temporary Kotlin-DSL test project to exercise the Tooling API path end-to-end (registers the task, runs a nested Jar build, verifies the artifact appears under the outer build dir).TODO-included-build.md(in this repo, not yet merged) describes the longer-term plan to movebuildSrc/to an included build; this PR opens that door but does not migrate any existing build logic. The smoke-test plugin lives as its own subproject so the eventualbuildSrc/migration can land independently without dragging in unrelated dependencies.Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issue🤖 Generated with Claude Code