Skip to content

Commit bd4f6ca

Browse files
Merged with master.
2 parents 7b04572 + e500e6a commit bd4f6ca

771 files changed

Lines changed: 3755 additions & 1729 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
issuer: https://gitlab.ddbuild.io
22

3-
subject_pattern: "project_path:DataDog/apm-reliability/dd-trace-java:ref_type:tag:ref:v.*"
3+
subject_pattern: 'project_path:DataDog/apm-reliability/dd-trace-java:ref_type:tag:ref:v\d+\.\d+\.\d+'
44

55
claim_pattern:
66
project_path: "DataDog/apm-reliability/dd-trace-java"
77
ref_type: "tag"
8-
ref: "v.*"
8+
ref: 'v\d+\.\d+\.\d+'
99

1010
permissions:
1111
contents: "write"

.github/scripts/dependency_age.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ def build_validation_summary(
551551
blocks.append(
552552
"### :warning: Cannot verify age, reverted\n\n"
553553
"The age of these dependencies could not be verified, so the lockfiles were reverted. "
554+
"This likely means that the following dependencies are published to a repo not yet configured in the workflow. "
555+
"If this is the case, add the missing repository as a `--repo-url` in the `Validate changed lock files` step of `.github/workflows/update-gradle-dependencies.yaml`. "
554556
"**This needs to be resolved manually.**\n\n"
555557
+ "\n".join(sorted(unverified))
556558
)

.github/workflows/update-gradle-dependencies.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ jobs:
6868
--min-age-hours "${MIN_DEPENDENCY_AGE_HOURS}" \
6969
--repo-url "https://repo1.maven.org/maven2" \
7070
--repo-url "https://repo.akka.io/${AKKA_REPO_TOKEN}/secure" \
71+
--repo-url "https://packages.confluent.io/maven" \
72+
--repo-url "https://repository.mulesoft.org/releases" \
73+
--repo-url "https://repository.mulesoft.org/nexus/content/repositories/public" \
7174
--github-output "$GITHUB_OUTPUT"
7275
7376
- name: Save instrumentation lock files

.gitlab-ci.yml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,9 @@ default:
242242
EOF
243243
- mkdir -p .gradle
244244
- export GRADLE_USER_HOME=$(pwd)/.gradle
245-
# replace maven central part by MAVEN_REPOSITORY_PROXY in .mvn/wrapper/maven-wrapper.properties
246-
- sed -i "s|https://repo.maven.apache.org/maven2/|$MAVEN_REPOSITORY_PROXY|g" .mvn/wrapper/maven-wrapper.properties
245+
# Apache Maven Wrapper supports MVNW_REPOURL for repository-manager downloads:
246+
# https://maven.apache.org/tools/wrapper/#Using_a_Maven_Repository_Manager
247+
- export MVNW_REPOURL=${MAVEN_REPOSITORY_PROXY%/}
247248
# Route Gradle distribution download through MASS pull-through cache
248249
- |
249250
mass_read_host="${MASS_READ_URL#https://}"
@@ -784,7 +785,14 @@ muzzle-dep-report:
784785
# and Gradle does `chmod 700 .gradle` on startup which requires user ownership.
785786
- sudo chown -R 1001:1001 .gradle
786787
- export GRADLE_USER_HOME=$(pwd)/.gradle
787-
- sed -i "s|https://repo.maven.apache.org/maven2/|$MAVEN_REPOSITORY_PROXY|g" .mvn/wrapper/maven-wrapper.properties
788+
# Apache Maven Wrapper supports MVNW_REPOURL for repository-manager downloads:
789+
# https://maven.apache.org/tools/wrapper/#Using_a_Maven_Repository_Manager
790+
- export MVNW_REPOURL=${MAVEN_REPOSITORY_PROXY%/}
791+
# Route Gradle distribution download through MASS pull-through cache
792+
- |
793+
mass_read_host="${MASS_READ_URL#https://}"
794+
mass_read_host="${mass_read_host%/}"
795+
sed -i "/^distributionUrl=/ s|services.gradle.org|${mass_read_host}/internal/artifact/services.gradle.org|" gradle/wrapper/gradle-wrapper.properties
788796
- *normalize_node_index
789797
- *prepare_test_env
790798
# Disable CDS in forked JVMs to avoid SIGSEGVs on Linux arm64.
@@ -1107,6 +1115,7 @@ test_smoke_graalvm:
11071115
needs: *needs_build_tests_smoke
11081116
tags: [ "arch:amd64" ]
11091117
variables:
1118+
<<: *tier_l_variables
11101119
GRADLE_TARGET: "stageMainDist :dd-smoke-test:spring-boot-3.0-native:test :dd-smoke-test:quarkus-native:test"
11111120
CACHE_TYPE: "smoke"
11121121
CI_NO_SPLIT: "true"
@@ -1119,6 +1128,7 @@ test_smoke_graalvm_arm64:
11191128
extends: .test_job_arm64
11201129
tags: [ "arch:arm64" ]
11211130
variables:
1131+
<<: *tier_l_variables
11221132
GRADLE_TARGET: "stageMainDist :dd-smoke-test:spring-boot-3.0-native:test :dd-smoke-test:quarkus-native:test"
11231133
CACHE_TYPE: "smoke"
11241134
CI_NO_SPLIT: "true"

.gitlab/java-benchmark-configs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ linux-java-spring-petclinic-load-parallel:
5050
needs: ["publish-artifacts-to-s3"]
5151
rules: *parallel_benchmark_rules
5252

53+
linux-java-spring-petclinic-sca-load-parallel:
54+
needs: ["publish-artifacts-to-s3"]
55+
rules: *parallel_benchmark_rules
56+
5357
linux-java-insecure-bank-startup-parallel:
5458
needs: ["publish-artifacts-to-s3"]
5559
rules: *parallel_startup_benchmark_rules

build-logic/smoke-test/src/main/kotlin/datadog/buildlogic/smoketest/NestedGradleBuild.kt

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ abstract class NestedGradleBuild @Inject constructor(
113113
@get:Input
114114
abstract val buildCacheEnabled: Property<Boolean>
115115

116+
/** Timeout, in seconds, for stopping the nested Gradle daemon after the build. */
117+
@get:Input
118+
@get:Optional
119+
abstract val stopTimeoutSeconds: Property<Long>
120+
116121
/**
117122
* Extra environment variables for the nested Gradle daemon. Merged on top of the outer process
118123
* environment; Gradle launcher variables are reserved by this task so nested builds do not
@@ -236,9 +241,17 @@ abstract class NestedGradleBuild @Inject constructor(
236241
}
237242

238243
val process = processBuilder.start()
239-
if (!process.waitFor(GRADLE_STOP_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
244+
val timeoutSeconds = stopTimeoutSeconds.orNull
245+
val completed =
246+
if (timeoutSeconds == null) {
247+
process.waitFor()
248+
true
249+
} else {
250+
process.waitFor(timeoutSeconds, TimeUnit.SECONDS)
251+
}
252+
if (!completed) {
240253
process.destroyForcibly()
241-
logger.warn("Timed out while stopping nested Gradle daemon")
254+
logger.warn("Timed out after {} seconds while stopping nested Gradle daemon", timeoutSeconds)
242255
return
243256
}
244257
val exitCode = process.exitValue()
@@ -270,13 +283,6 @@ abstract class NestedGradleBuild @Inject constructor(
270283
file.parentFile?.name == "bin"
271284
}
272285

273-
private fun gradleExecutableName(): String =
274-
if (System.getProperty("os.name").lowercase().contains("windows")) {
275-
"gradle.bat"
276-
} else {
277-
"gradle"
278-
}
279-
280286
private fun createGradleUserHome(): File {
281287
val directory = temporaryDir.resolve("gradle-user-home")
282288
deleteGradleUserHome(directory)
@@ -294,8 +300,13 @@ abstract class NestedGradleBuild @Inject constructor(
294300
}
295301
}
296302

297-
private companion object {
298-
const val GRADLE_STOP_TIMEOUT_SECONDS = 30L
303+
companion object {
304+
internal fun gradleExecutableName(osName: String = System.getProperty("os.name")): String =
305+
if (isWindows(osName)) {
306+
"gradle.bat"
307+
} else {
308+
"gradle"
309+
}
299310
}
300311
}
301312

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package datadog.buildlogic.smoketest
2+
3+
import org.gradle.api.DefaultTask
4+
import org.gradle.api.GradleException
5+
import org.gradle.api.file.DirectoryProperty
6+
import org.gradle.api.file.FileTree
7+
import org.gradle.api.file.RegularFileProperty
8+
import org.gradle.api.model.ObjectFactory
9+
import org.gradle.api.provider.ListProperty
10+
import org.gradle.api.provider.MapProperty
11+
import org.gradle.api.provider.Property
12+
import org.gradle.api.tasks.CacheableTask
13+
import org.gradle.api.tasks.IgnoreEmptyDirectories
14+
import org.gradle.api.tasks.Input
15+
import org.gradle.api.tasks.InputFile
16+
import org.gradle.api.tasks.InputFiles
17+
import org.gradle.api.tasks.Internal
18+
import org.gradle.api.tasks.Nested
19+
import org.gradle.api.tasks.Optional
20+
import org.gradle.api.tasks.OutputDirectory
21+
import org.gradle.api.tasks.PathSensitive
22+
import org.gradle.api.tasks.PathSensitivity
23+
import org.gradle.api.tasks.TaskAction
24+
import org.gradle.jvm.toolchain.JavaLanguageVersion
25+
import org.gradle.jvm.toolchain.JavaLauncher
26+
import org.gradle.jvm.toolchain.JavaToolchainService
27+
import java.io.File
28+
import java.util.concurrent.TimeUnit
29+
import javax.inject.Inject
30+
31+
/**
32+
* Runs a nested Maven build inside [applicationDir] via the root Maven wrapper.
33+
*
34+
* The nested build is expected to honour `-Dtarget.dir=<path>` and write outputs under that
35+
* directory so Gradle can track the artifact under [applicationBuildDir].
36+
*/
37+
@CacheableTask
38+
abstract class NestedMavenBuild @Inject constructor(
39+
private val objects: ObjectFactory,
40+
javaToolchains: JavaToolchainService,
41+
) : DefaultTask() {
42+
43+
init {
44+
javaLauncher.convention(
45+
javaToolchains.launcherFor {
46+
languageVersion.set(JavaLanguageVersion.of(DEFAULT_NESTED_JAVA_VERSION))
47+
},
48+
)
49+
goals.convention(listOf("package"))
50+
arguments.convention(emptyList())
51+
environment.convention(emptyMap())
52+
mavenOpts.convention("")
53+
useMavenLocalRepository.convention(false)
54+
}
55+
56+
@get:Internal
57+
abstract val applicationDir: DirectoryProperty
58+
59+
@get:InputFiles
60+
@get:IgnoreEmptyDirectories
61+
@get:PathSensitive(PathSensitivity.RELATIVE)
62+
val applicationSources: FileTree =
63+
objects.fileTree().from(applicationDir).matching {
64+
exclude("target/**")
65+
}
66+
67+
@get:OutputDirectory
68+
abstract val applicationBuildDir: DirectoryProperty
69+
70+
@get:InputFile
71+
@get:PathSensitive(PathSensitivity.RELATIVE)
72+
abstract val mavenExecutable: RegularFileProperty
73+
74+
@get:InputFiles
75+
@get:IgnoreEmptyDirectories
76+
@get:PathSensitive(PathSensitivity.RELATIVE)
77+
val mavenWrapperFiles: FileTree =
78+
objects.fileTree().from(project.rootProject.layout.projectDirectory.dir(".mvn/wrapper")).matching {
79+
include("maven-wrapper.properties", "maven-wrapper.jar")
80+
}
81+
82+
@get:Nested
83+
abstract val javaLauncher: Property<JavaLauncher>
84+
85+
@get:Input
86+
abstract val goals: ListProperty<String>
87+
88+
@get:Input
89+
abstract val arguments: ListProperty<String>
90+
91+
@get:Input
92+
abstract val environment: MapProperty<String, String>
93+
94+
@get:Input
95+
@get:Optional
96+
abstract val mavenOpts: Property<String>
97+
98+
@get:Input
99+
@get:Optional
100+
abstract val mavenRepositoryProxy: Property<String>
101+
102+
@get:Input
103+
abstract val useMavenLocalRepository: Property<Boolean>
104+
105+
/** Timeout, in seconds, for the nested Maven build process. */
106+
@get:Input
107+
@get:Optional
108+
abstract val buildTimeoutSeconds: Property<Long>
109+
110+
@get:Internal
111+
abstract val mavenLocalRepository: DirectoryProperty
112+
113+
@TaskAction
114+
fun runNestedBuild() {
115+
val appDir = applicationDir.get().asFile
116+
val appBuildDirFile = applicationBuildDir.get().asFile
117+
val targetDir = appBuildDirFile.resolve("target")
118+
val daemonJavaHome = javaLauncher.get().metadata.installationPath.asFile
119+
val command = mavenCommand(mavenExecutable.get().asFile).apply {
120+
add("-Dtarget.dir=${targetDir.absolutePath}")
121+
if (useMavenLocalRepository.get()) {
122+
add("-Dmaven.repo.local=${mavenLocalRepository.get().asFile.absolutePath}")
123+
}
124+
addAll(arguments.get())
125+
addAll(goals.get())
126+
}
127+
128+
val process = ProcessBuilder(command)
129+
.directory(appDir)
130+
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
131+
.redirectError(ProcessBuilder.Redirect.INHERIT)
132+
.apply {
133+
environment().apply {
134+
clear()
135+
putAll(nestedEnvironment(daemonJavaHome))
136+
}
137+
}
138+
.start()
139+
140+
try {
141+
val timeoutSeconds = buildTimeoutSeconds.orNull
142+
val completed =
143+
if (timeoutSeconds == null) {
144+
process.waitFor()
145+
true
146+
} else {
147+
process.waitFor(timeoutSeconds, TimeUnit.SECONDS)
148+
}
149+
if (!completed) {
150+
process.destroyForcibly()
151+
throw GradleException(
152+
"Nested Maven build timed out after $timeoutSeconds seconds: " +
153+
command.joinToString(" "),
154+
)
155+
}
156+
} catch (e: InterruptedException) {
157+
process.destroyForcibly()
158+
Thread.currentThread().interrupt()
159+
throw GradleException("Interrupted while running nested Maven build", e)
160+
}
161+
val exitCode = process.exitValue()
162+
if (exitCode != 0) {
163+
throw GradleException(
164+
"Nested Maven build failed with exit code $exitCode: ${command.joinToString(" ")}",
165+
)
166+
}
167+
}
168+
169+
private fun nestedEnvironment(daemonJavaHome: File): Map<String, String> {
170+
val env = System.getenv().toMutableMap()
171+
val repositoryProxy = mavenRepositoryProxy.orNull?.takeIf { it.isNotBlank() }
172+
if (repositoryProxy != null) {
173+
env["MAVEN_REPOSITORY_PROXY"] = repositoryProxy
174+
env.putIfAbsent("MVNW_REPOURL", repositoryProxy.trimEnd('/'))
175+
}
176+
val opts = mavenOpts.orNull
177+
if (!opts.isNullOrBlank()) {
178+
env["MAVEN_OPTS"] = opts
179+
}
180+
env["JAVA_HOME"] = daemonJavaHome.absolutePath
181+
env.putAll(environment.get())
182+
return env
183+
}
184+
185+
private fun mavenCommand(executable: File): MutableList<String> =
186+
if (isWindows()) {
187+
mutableListOf("cmd", "/c", executable.absolutePath)
188+
} else {
189+
mutableListOf(executable.absolutePath)
190+
}
191+
192+
companion object {
193+
internal fun mavenWrapperName(osName: String = System.getProperty("os.name")): String =
194+
if (isWindows(osName)) {
195+
"mvnw.cmd"
196+
} else {
197+
"mvnw"
198+
}
199+
200+
}
201+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package datadog.buildlogic.smoketest
2+
3+
import java.util.Locale
4+
5+
internal fun isWindows(osName: String = System.getProperty("os.name")): Boolean =
6+
osName.lowercase(Locale.ROOT).contains("windows")
7+

0 commit comments

Comments
 (0)