Skip to content

fix(auto-install): Pass install state via rule params (GRADLE-112) - #1352

Open
runningcode wants to merge 1 commit into
mainfrom
no/gradle-112-autoinstall-state-service
Open

fix(auto-install): Pass install state via rule params (GRADLE-112)#1352
runningcode wants to merge 1 commit into
mainfrom
no/gradle-112-autoinstall-state-service

Conversation

@runningcode

Copy link
Copy Markdown
Contributor

Fixes GRADLE-112.

Problem

The auto-install ComponentMetadataRules (AbstractInstallStrategy, WarnOnOverrideStrategy) read the resolved Sentry version and the enabled flag from AutoInstallState — a process-global mutable singleton. Each project that applied the plugin wrote its own values into that shared instance during configuration:

with(AutoInstallState.getInstance(gradle)) {
  this.sentryVersion = installSentrySdk(...)
  this.enabled = true
}

Mutating build-wide shared state from per-project configuration breaks project isolation, and could let one project's rules observe another project's auto-install version. The singleton also required a BuildFinishedListenerService-based reset and a per-build cleanupAutoInstallState task in tests to avoid leaking across builds in the Gradle daemon.

Fix

Resolve the enabled flag and Sentry version inside the implementation configuration's withDependencies hook (where they're already computed) and pass them to each rule as ComponentMetadataRule params(...). The rules now read the two values from their constructor instead of a global, so there's no shared mutable state across projects.

  • AbstractInstallStrategy / WarnOnOverrideStrategy take autoInstallEnabled + sentryVersion via constructor.
  • InstallStrategyRegistrar.register(...) forwards them into withModule { params(...) }.
  • AutoInstallState and the cleanupAutoInstallState test task are deleted.

Testing

  • ./gradlew -p plugin-build test --tests "io.sentry.android.gradle.autoinstall.*" — all auto-install unit tests pass.
  • ./gradlew -p plugin-build integrationTest --tests "io.sentry.android.gradle.integration.SentryPluginAutoInstallNonAndroidTest" — full non-Android auto-install integration suite passes, exercising the withDependencies + params() wiring end-to-end (including the delayed Spring strategies, the disabled case, and version-override behavior). The Android variant uses the identical code path and runs in CI.

@linear-code

linear-code Bot commented Jul 2, 2026

Copy link
Copy Markdown

GRADLE-112

The auto-install component metadata rules read the resolved Sentry
version and enabled flag from AutoInstallState, a process-global
mutable singleton. Each project that applied the plugin wrote its own
values into that shared instance during configuration, which breaks
project isolation and could let one project observe another project's
auto-install version.

Resolve the version and enabled flag inside the implementation
configuration's withDependencies hook and pass them to each rule as
ComponentMetadataRule params, so the rules no longer depend on shared
mutable state. Delete AutoInstallState and the per-build cleanup task
the singleton required.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@runningcode
runningcode force-pushed the no/gradle-112-autoinstall-state-service branch from 387d415 to 6d505df Compare July 2, 2026 12:45
@0xadam-brown

Copy link
Copy Markdown
Member

Are you still looking for reviewers on this, @runningcode?

@0xadam-brown 0xadam-brown left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the idea of bringing back project independence + avoiding global shared state 💯!

My LLM tells me the current approach fixes the shared-state problem (yea!), but that it also changes version-resolution behavior in AutoInstall so that a BOM is now treated as if the core SDK were already installed, rather than just as a version source. In BOM-only builds that can skip auto-installing the actual core artifact.

Fwiw, it suggests the following fix (click to open):
Details Keep the PR's main change, but restore the distinction between:
  • a Sentry version source being present
  • the core SDK already being directly installed

Suggested shape in AutoInstall.kt:

private data class ResolvedSentryVersion(
    val version: String?,
    val isCoreSdkInstalled: Boolean,
)

Then update the lookup so it returns both pieces of information:

  • Direct core SDK dependencies should set:

    • version = detected version
    • isCoreSdkInstalled = true
  • BOM-only dependencies should set:

    • version = BOM version
    • isCoreSdkInstalled = false

This is the important distinction:

  • A BOM provides a version to align to.
  • A BOM does not install sentry or sentry-android by itself.

installSentrySdk() should branch on isCoreSdkInstalled, not on version != null.

Expected behavior:

  1. If only a BOM is present:

    • use the BOM version
    • still auto-install the core SDK
  2. If the core SDK is already directly present:

    • reuse that version
    • do not add another core SDK dependency

Also restore sentry-opentelemetry-bom as a recognized non-Android version source.

Minimal intent:

  • preserve the new rule-parameter wiring
  • keep the singleton removal
  • fix the version-resolution regression by modeling version source and SDK presence separately

Suggested tests:

  • Android: BOM-only + trigger dependency installs sentry-android at the BOM version
  • JVM: sentry-opentelemetry-bom + trigger dependency installs sentry and related integrations at the BOM version

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants