Skip to content

Commit 70b2ed0

Browse files
authored
Fallback to old muzzle resolution when pinned versions file is missing (#18834)
1 parent 3f86ad6 commit 70b2ed0

3 files changed

Lines changed: 45 additions & 15 deletions

File tree

.github/workflows/build-common.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,10 @@ jobs:
547547
run: ./gradlew assemble ${{ inputs.no-build-cache && ' --no-build-cache' || '' }}
548548
working-directory: benchmark-overhead
549549

550+
- name: Run muzzle check against distro
551+
run: ./gradlew :instrumentation:servlet-3:muzzle --init-script ../../.github/scripts/local.init.gradle.kts
552+
working-directory: examples/distro
553+
550554
- name: Run muzzle check against extension
551555
run: ./gradlew muzzle --init-script ../../.github/scripts/local.init.gradle.kts
552556
working-directory: examples/extension

examples/distro/instrumentation/servlet-3/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies {
2323
compileOnly(project(":bootstrap"))
2424
compileOnly("javax.servlet:javax.servlet-api:3.0.1")
2525

26+
add("muzzleBootstrap", project(":bootstrap"))
2627
add("codegen", "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:$opentelemetryJavaagentAlphaVersion")
2728
add("muzzleBootstrap", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-support:$opentelemetryJavaagentAlphaVersion")
2829
add("muzzleTooling", "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:$opentelemetryJavaagentAlphaVersion")

gradle-plugins/src/main/kotlin/io.opentelemetry.instrumentation.muzzle-check.gradle.kts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import org.eclipse.aether.spi.connector.transport.TransporterFactory
2323
import org.eclipse.aether.transport.http.HttpTransporterFactory
2424
import org.eclipse.aether.util.version.GenericVersionScheme
2525
import org.eclipse.aether.version.Version
26+
import java.io.File
2627
import java.net.URL
2728
import java.net.URLClassLoader
2829
import java.util.stream.StreamSupport
@@ -37,13 +38,30 @@ val RANGE_COUNT_LIMIT = Integer.getInteger("otel.javaagent.muzzle.versions.limit
3738

3839
// Read pinned latest-dep versions to cap muzzle's open-ended version ranges,
3940
// preventing failures when new library versions are released to Maven Central.
40-
val muzzlePinnedVersions: Map<String, String> by lazy {
41-
val file = rootProject.file(".github/config/latest-dep-versions.json")
42-
if (!file.exists()) {
43-
throw GradleException("Pinned latest-dep versions file is missing: ${file}.")
41+
//
42+
// External users of the muzzle plugin may not have this pinned versions file in their project
43+
// layout. In that case, fall back to the old behavior and resolve versions directly from
44+
// configured repositories.
45+
val muzzlePinnedVersions: Map<String, String>? by lazy {
46+
val file = generateSequence(rootProject.projectDir) { it.parentFile }
47+
.flatMap {
48+
sequenceOf(
49+
File(it, ".github/config/latest-dep-versions.json"),
50+
File(it, "config/latest-dep-versions.json")
51+
)
52+
}
53+
.firstOrNull { it.exists() }
54+
if (file == null) {
55+
logger.info(
56+
"Pinned latest-dep versions file is missing under ${rootProject.projectDir}; falling back to repository " +
57+
"version resolution for muzzle checks."
58+
)
59+
null
60+
} else {
61+
logger.info("Using pinned latest-dep versions file: ${file}")
62+
@Suppress("UNCHECKED_CAST")
63+
groovy.json.JsonSlurper().parse(file) as Map<String, String>
4464
}
45-
@Suppress("UNCHECKED_CAST")
46-
groovy.json.JsonSlurper().parse(file) as Map<String, String>
4765
}
4866

4967
/**
@@ -58,16 +76,19 @@ val muzzlePinnedVersions: Map<String, String> by lazy {
5876
* the agent uses shaded/in-repo classes rather than the external library). With "0.0" as the
5977
* upper bound, {@code filterVersions} rejects all real versions (none are <= 0.0), so no
6078
* muzzle tasks are created and the directive is silently skipped. To add a sentinel entry,
61-
* manually add {@code "group:module#+": "0.0"} to
62-
* {@code .github/config/latest-dep-versions.json}.
79+
* manually add {@code "group:module#+": "0.0"} to the pinned latest-dep versions file.
80+
*
81+
* <p>Returns {@code null} when the pinned versions file is not present, which preserves the old
82+
* behavior of resolving the full version range from configured repositories.
6383
*/
64-
fun resolveUpperBound(group: String, module: String): Version {
84+
fun resolveUpperBound(group: String, module: String): Version? {
85+
val pinnedVersions = muzzlePinnedVersions ?: return null
6586
val key = "$group:$module#+"
66-
val pinnedVersion = muzzlePinnedVersions[key]
87+
val pinnedVersion = pinnedVersions[key]
6788
?: throw GradleException(
6889
"Pinned version missing for muzzle artifact \"$key\". " +
6990
"Run ./gradlew resolveLatestDepVersions -PtestLatestDeps=true -PresolveLatestDeps=true " +
70-
"to regenerate .github/config/latest-dep-versions.json"
91+
"to regenerate the pinned latest-dep versions file"
7192
)
7293
return GenericVersionScheme().parseVersion(pinnedVersion)
7394
}
@@ -198,9 +219,12 @@ tasks.register("printMuzzleReferences") {
198219
val hasRelevantTask = gradle.startParameter.taskNames.any {
199220
// removing leading ':' if present
200221
val taskName = it.removePrefix(":")
201-
val projectPath = project.path.substring(1)
222+
val projectPath = project.path.removePrefix(":")
223+
val muzzleTaskName = if (projectPath.isEmpty()) "muzzle" else "$projectPath:muzzle"
202224
// Either the specific muzzle task in this project or a top level muzzle task.
203-
taskName == "${projectPath}:muzzle" || taskName.startsWith("instrumentation:muzzle") ||
225+
taskName == muzzleTaskName ||
226+
taskName.startsWith("instrumentation:muzzle") ||
227+
taskName.startsWith("muzzle-Assert") ||
204228
taskName.contains(":muzzle-Assert")
205229
}
206230

@@ -442,9 +466,10 @@ fun inverseOf(muzzleDirective: MuzzleDirective, system: RepositorySystem, sessio
442466
return inverseDirectives
443467
}
444468

445-
fun filterVersions(range: VersionRangeResult, skipVersions: Set<String>, upperBound: Version) = sequence {
469+
fun filterVersions(range: VersionRangeResult, skipVersions: Set<String>, upperBound: Version?) = sequence {
446470
val predicate = AcceptableVersions(skipVersions)
447-
fun accept(version: Version?): Boolean = version != null && predicate.test(version) && version <= upperBound
471+
fun accept(version: Version?): Boolean =
472+
version != null && predicate.test(version) && (upperBound == null || version <= upperBound)
448473
if (accept(range.lowestVersion)) {
449474
yield(range.lowestVersion.toString())
450475
}

0 commit comments

Comments
 (0)