Skip to content

Commit 707e4e2

Browse files
authored
Merge branch 'master' into dougqh/collection-benchmarks
2 parents cf3b9cb + c04d61b commit 707e4e2

204 files changed

Lines changed: 3663 additions & 1332 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.

.claude/skills/migrate-groovy-to-java/SKILL.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ description: migrate test groovy files to java
55

66
Migrate test Groovy files to Java using JUnit 5
77

8-
1. List all groovy files of the current gradle module
9-
2. convert groovy files to Java using Junit 5
10-
3. make sure the tests are still passing after migration
11-
4. remove groovy files
8+
1. List all Groovy files of the current Gradle module
9+
2. Convert Groovy files to Java using JUnit 5
10+
3. Make sure the tests are still passing after migration and that the test count has not changed
11+
4. Remove Groovy files
12+
5. Add the migrated module path(s) to `.github/g2j-migrated-modules.txt`
1213

13-
When converting groovy code to java code make sure that:
14-
- the Java code generated is compatible with JDK 8
15-
- when translating Spock test, favor using `@CsvSource` with `|` delimiters
16-
- when using a `@MethodSource`, use the test method name, and suffix it with `_arguments`
17-
- when converting tuples, create light dedicated structure instead to keep the typing system
14+
When converting Groovy code to Java code, make sure that:
15+
- The Java code generated is compatible with JDK 8
16+
- When translating Spock tests, favor using `@CsvSource` with `|` delimiters
17+
- When using `@MethodSource`, name the arguments method by appending `Arguments` using camelCase to the test method name (e.g. `testMethodArguments`) and return a `Stream` of arguments using `Stream.of(...)` and `arguments(...)` with static import.
18+
- Ensure parameterized test names are human-readable (i.e. no hashcodes); instead add a description string as the first `Arguments.arguments(...)` value or index the test case
19+
- When converting tuples, create a light dedicated structure instead to keep the typing system
1820
- Instead of checking a state and throwing an exception, use JUnit asserts
19-
- Do not wrap checked exception and throwing a Runtime exception, prefer adding a throws clause at method declaration
21+
- Do not wrap checked exceptions and throw a Runtime exception; prefer adding a throws clause at method declaration
2022
- Do not mark local variables `final`
23+
- Ensure variables are human-readable; avoid single-letter names and pre-define variables that are referenced multiple times

.github/chainguard/self.pin-system-tests.create-pr.sts.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ subject_pattern: repo:DataDog/dd-trace-java:ref:refs/(heads/master|tags/v\d+\.\d
55
claim_pattern:
66
event_name: (workflow_dispatch|push)
77
ref: refs/(heads/master|tags/v\d+\.\d+\.0)
8-
job_workflow_ref: DataDog/dd-trace-java/\.github/workflows/create-release-branch\.yaml@refs/heads/master
8+
job_workflow_ref: DataDog/dd-trace-java/\.github/workflows/create-release-branch\.yaml@refs/(heads/master|tags/v\d+\.\d+\.0)
99

1010
permissions:
1111
contents: write

.github/g2j-migrated-modules.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# This file lists modules that have been migrated from Groovy to Java / JUnit 5.
2+
# New *.groovy files under any src/<*test*>/groovy/ path
3+
# in these modules will fail the 'enforce-groovy-migration' PR check.
4+
#
5+
# After a module is migrated, add it on a new line here.
6+
# Use the filesystem path prefix as seen below.
7+
8+
buildSrc/call-site-instrumentation-plugin
9+
components/json

.github/workflows/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@ _Action:_
123123

124124
_Recovery:_ Check at the milestone for the related issues and update them manually.
125125

126+
### enforce-groovy-migration [🔗](enforce-groovy-migration.yaml)
127+
128+
_Trigger:_ When creating or updating a pull request targeting `master`, or when labels are updated.
129+
130+
_Actions:_
131+
132+
* Fail the PR if a new Groovy test file is added to a module listed in [`.github/g2j-migrated-modules.txt`](../g2j-migrated-modules.txt) (hard enforcement),
133+
* Post a warning comment on the PR if a new Groovy test file is added to any other non-exempt module (soft warning). Instrumentation (`dd-java-agent/instrumentation/`) and smoke-test (`dd-smoke-tests/`) modules are exempt from this warning.
134+
135+
_Recovery:_ Re-write the Groovy test files in Java / JUnit 5. To override this check entirely, add the `tag: override-groovy-enforcement` label to the PR. Remove the label to re-enable enforcement.
136+
137+
_Notes:_ The migrated modules list is always read from `master`. Add a new entry to `.github/g2j-migrated-modules.txt` each time a module is migrated to Java / JUnit 5.
138+
126139
## Code Quality and Security
127140

128141
### analyze-changes [🔗](analyze-changes.yaml)

.github/workflows/analyze-changes.yaml

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
${{ runner.os }}-gradle-
3131
3232
- name: Initialize CodeQL
33-
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
33+
uses: github/codeql-action/init@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5
3434
with:
3535
languages: 'java'
3636
build-mode: 'manual'
@@ -39,17 +39,11 @@ jobs:
3939
env:
4040
ORG_GRADLE_PROJECT_akkaRepositoryToken: ${{ secrets.AKKA_REPO_TOKEN }}
4141
run: |
42-
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx3G -Xms2G'" \
43-
JAVA_HOME=$JAVA_HOME_8_X64 \
44-
JAVA_8_HOME=$JAVA_HOME_8_X64 \
45-
JAVA_11_HOME=$JAVA_HOME_11_X64 \
46-
JAVA_17_HOME=$JAVA_HOME_17_X64 \
47-
JAVA_21_HOME=$JAVA_HOME_21_X64 \
48-
./gradlew clean :dd-java-agent:shadowJar \
49-
--build-cache --parallel --stacktrace --no-daemon --max-workers=4
42+
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xms2G -Xmx3G'" \
43+
./gradlew clean :dd-java-agent:shadowJar --build-cache --parallel --stacktrace --no-daemon --max-workers=4
5044
5145
- name: Perform CodeQL Analysis and upload results to GitHub Security tab
52-
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
46+
uses: github/codeql-action/analyze@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5
5347

5448
trivy:
5549
name: Analyze changes with Trivy
@@ -85,14 +79,8 @@ jobs:
8579
env:
8680
ORG_GRADLE_PROJECT_akkaRepositoryToken: ${{ secrets.AKKA_REPO_TOKEN }}
8781
run: |
88-
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx3G -Xms2G'" \
89-
JAVA_HOME=$JAVA_HOME_8_X64 \
90-
JAVA_8_HOME=$JAVA_HOME_8_X64 \
91-
JAVA_11_HOME=$JAVA_HOME_11_X64 \
92-
JAVA_17_HOME=$JAVA_HOME_17_X64 \
93-
JAVA_21_HOME=$JAVA_HOME_21_X64 \
94-
./gradlew clean publishToMavenLocal \
95-
--build-cache --parallel --stacktrace --no-daemon --max-workers=4
82+
GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xms2G -Xmx3G'" \
83+
./gradlew clean publishToMavenLocal --build-cache --parallel --stacktrace --no-daemon --max-workers=4
9684
9785
- name: Copy published artifacts
9886
run: |
@@ -101,7 +89,7 @@ jobs:
10189
ls -laR "./workspace/.trivy"
10290
10391
- name: Run Trivy security scanner
104-
uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # v0.34.1
92+
uses: aquasecurity/trivy-action@97e0b3872f55f89b95b2f65b3dbab56962816478 # v0.34.2
10593
with:
10694
scan-type: rootfs
10795
scan-ref: './workspace/.trivy/'
@@ -114,7 +102,7 @@ jobs:
114102
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db
115103

116104
- name: Upload Trivy scan results to GitHub Security tab
117-
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
105+
uses: github/codeql-action/upload-sarif@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5
118106
if: always()
119107
with:
120108
sarif_file: 'trivy-results.sarif'
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
name: Enforce Groovy Migration
2+
on:
3+
pull_request:
4+
types: [opened, edited, ready_for_review, labeled, unlabeled, synchronize]
5+
branches:
6+
- master
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
enforce_groovy_migration:
14+
name: Enforce Groovy migration
15+
permissions:
16+
issues: write # Required to create a comment on the pull request
17+
pull-requests: write # Required to create a comment on the pull request
18+
contents: read # Required to read migrated modules file
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Check for Groovy regressions
22+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # 8.0.0
23+
with:
24+
github-token: ${{ secrets.GITHUB_TOKEN }}
25+
script: |
26+
// Skip draft pull requests
27+
if (context.payload.pull_request.draft) {
28+
return
29+
}
30+
31+
// Check for override label — skip all checks if label present
32+
const labels = context.payload.pull_request.labels.map(l => l.name)
33+
if (labels.includes('tag: override-groovy-enforcement')) {
34+
console.log('tag: override-groovy-enforcement label detected — skipping all checks.')
35+
return
36+
}
37+
38+
// Read migrated modules list from master
39+
const migratedMods = await github.rest.repos.getContent({
40+
owner: context.repo.owner,
41+
repo: context.repo.repo,
42+
path: '.github/g2j-migrated-modules.txt',
43+
ref: 'master'
44+
})
45+
const migratedPrefixes = Buffer.from(migratedMods.data.content, 'base64')
46+
.toString()
47+
.split('\n')
48+
.map(l => l.trim())
49+
.filter(l => l && !l.startsWith('#'))
50+
51+
// Get all files changed in this PR
52+
const allFiles = await github.paginate(github.rest.pulls.listFiles, {
53+
owner: context.repo.owner,
54+
repo: context.repo.repo,
55+
pull_number: context.payload.pull_request.number
56+
})
57+
58+
// Filter these changed files to newly added Groovy files in any test source set
59+
const addedGroovy = allFiles.filter(f =>
60+
f.status === 'added' &&
61+
/\/src\/[^/]*[tT]est[^/]*\/groovy\/.*\.groovy$/.test(f.filename)
62+
)
63+
64+
// Extract module prefix from file path (everything before /src/(test|testFixtures)/groovy/)
65+
const moduleOf = path => {
66+
const m = path.match(/^(.*?)\/src\/(test|testFixtures)\/groovy\//)
67+
return m ? m[1] : null
68+
}
69+
70+
// Classify each added Groovy file
71+
const regressions = []
72+
const warnings = []
73+
for (const file of addedGroovy) {
74+
const path = file.filename
75+
const mod = moduleOf(path)
76+
if (migratedPrefixes.some(prefix => path.startsWith(prefix + '/'))) {
77+
regressions.push({ path, mod })
78+
} else if (
79+
path.startsWith('dd-java-agent/instrumentation/') ||
80+
path.startsWith('dd-smoke-tests/')
81+
) {
82+
// ignore Groovy file additions to instrumentations and smoke-tests for now
83+
} else {
84+
warnings.push({ path, mod })
85+
}
86+
}
87+
88+
// Fetch existing comments once
89+
const comments = await github.rest.issues.listComments({
90+
issue_number: context.payload.pull_request.number,
91+
owner: context.repo.owner,
92+
repo: context.repo.repo
93+
})
94+
95+
const regressionMarker = '<!-- dd-trace-java-groovy-regression -->'
96+
const warningMarker = '<!-- dd-trace-java-groovy-warning -->'
97+
const existingRegressionComment = comments.data.find(c => c.body.includes(regressionMarker))
98+
const existingWarningComment = comments.data.find(c => c.body.includes(warningMarker))
99+
100+
// Handle regression comment
101+
if (regressions.length > 0) {
102+
const fileList = regressions
103+
.map(({ path, mod }) => `- \`${path}\` (module: \`${mod}\`)`)
104+
.join('\n')
105+
const body = `**❌ Groovy Test Regression Detected**\n\n` +
106+
`The following files add Groovy tests to modules that have been fully migrated to Java / JUnit 5:\n\n` +
107+
`${fileList}\n\n` +
108+
`These modules no longer accept Groovy test files. Please rewrite the test in Java / JUnit 5 instead.\n\n` +
109+
regressionMarker
110+
if (existingRegressionComment) {
111+
await github.rest.issues.updateComment({
112+
comment_id: existingRegressionComment.id,
113+
owner: context.repo.owner,
114+
repo: context.repo.repo,
115+
body
116+
})
117+
} else {
118+
await github.rest.issues.createComment({
119+
issue_number: context.payload.pull_request.number,
120+
owner: context.repo.owner,
121+
repo: context.repo.repo,
122+
body
123+
})
124+
}
125+
} else if (existingRegressionComment) {
126+
await github.rest.issues.deleteComment({
127+
comment_id: existingRegressionComment.id,
128+
owner: context.repo.owner,
129+
repo: context.repo.repo
130+
})
131+
}
132+
133+
// Handle warning comment
134+
if (warnings.length > 0) {
135+
const fileList = warnings
136+
.map(({ path, mod }) => `- \`${path}\` (module: \`${mod}\`)`)
137+
.join('\n')
138+
const body = `**⚠️ New Groovy Test Files Added**\n\n` +
139+
`The following files add Groovy tests to modules that are candidates for migration to Java / JUnit 5:\n\n` +
140+
`${fileList}\n\n` +
141+
`Consider writing these tests in Java / JUnit 5 instead to help with the ongoing migration effort.\n\n` +
142+
warningMarker
143+
if (existingWarningComment) {
144+
await github.rest.issues.updateComment({
145+
comment_id: existingWarningComment.id,
146+
owner: context.repo.owner,
147+
repo: context.repo.repo,
148+
body
149+
})
150+
} else {
151+
await github.rest.issues.createComment({
152+
issue_number: context.payload.pull_request.number,
153+
owner: context.repo.owner,
154+
repo: context.repo.repo,
155+
body
156+
})
157+
}
158+
} else if (existingWarningComment) {
159+
await github.rest.issues.deleteComment({
160+
comment_id: existingWarningComment.id,
161+
owner: context.repo.owner,
162+
repo: context.repo.repo
163+
})
164+
}
165+
166+
// Fail the check if there are regressions
167+
if (regressions.length > 0) {
168+
core.setFailed(`${regressions.length} Groovy regression(s) detected in migrated module(s). See PR comment for details. To skip this check entirely, add the 'tag: override-groovy-enforcement' label.`)
169+
}

.github/workflows/run-system-tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
--build-cache --parallel --stacktrace --no-daemon --max-workers=4
5454
5555
- name: Upload artifact
56-
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
56+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
5757
with:
5858
name: binaries
5959
path: workspace/dd-java-agent/build/libs/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ out/
6060

6161
# Others #
6262
##########
63+
/dumps
6364
/logs/*
6465
/bin
6566
/out

.gitlab/ci_visibility_generate_job.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,19 @@ if [ -z "$pr_number" ]; then
4242
exit 0
4343
fi
4444

45-
echo "PR #${pr_number} found, checking labels..."
45+
echo "PR #${pr_number} found, checking target branch..."
46+
set +e
47+
base_branch=$(gh pr view "$pr_number" --repo DataDog/dd-trace-java --json baseRefName --jq '.baseRefName' 2>&1)
48+
base_branch_status=$?
49+
set -e
50+
51+
if [ $base_branch_status -eq 0 ] && [[ "$base_branch" == release/* ]]; then
52+
echo "PR #$pr_number targets release branch '$base_branch' - skipping trigger"
53+
add_dummy_job
54+
exit 0
55+
fi
56+
57+
echo "Checking labels..."
4658
set +e
4759
labels=$(gh pr view "$pr_number" --repo DataDog/dd-trace-java --json labels --jq '.labels[].name' 2>&1)
4860
labels_status=$?

0 commit comments

Comments
 (0)