fix(android): make Sentry Gradle tasks Configuration Cache compatible#6469
fix(android): make Sentry Gradle tasks Configuration Cache compatible#6469fabiendem wants to merge 3 commits into
Conversation
`copySentryJsonConfiguration` and the `*_SentryUpload` tasks no longer read `project` state at execution time — `onlyIf` predicates resolving closures from `project.extra`, plus `project.rootDir`, `project.copy`, `project.logger`, and `Project.file` inside task actions. Environment reads are captured at configuration time, file copies use an injected `FileSystemOperations`, and task actions use the task's own `logger`. No behaviour change. This fixes the hard `Could not evaluate onlyIf predicate` failure when `org.gradle.configuration-cache=true` (Gradle 9 recommends it by default). Verified end-to-end on a React Native 0.83.9 app with Gradle 9.0.0: the equivalent Groovy `sentry.gradle` (shipped in 8.10.0) went from BUILD FAILED (`Could not evaluate onlyIf predicate for task ':app:copySentryJsonConfiguration'`) to BUILD SUCCESSFUL with config cache enabled after this change. See getsentry#6466. Interim step ahead of the SAGP migration (getsentry/sentry-android-gradle-plugin#796). Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Code <noreply@anthropic.com>
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
Addresses review feedback: capturing `SENTRY_DISABLE_AUTO_UPLOAD` via
`System.getenv` at apply-time ignored a `project.ext.shouldSentryAutoUploadGeneral`
override set right after `apply from` (e.g. the Expo `disableAutoUpload` config
plugin, which injects `project.ext.shouldSentryAutoUploadGeneral = { -> return false }`).
Uploads would then run even when the user disabled them.
Now capture `shouldSentryAutoUploadGeneral()` inside the `onVariants` callback,
which runs after the app `build.gradle` has evaluated, so the override is in
effect. Likewise capture `shouldCopySentryOptionsFile()` via the closure rather
than re-reading the env var, so `project.ext` overrides of it keep working.
Both `onlyIf` specs still reference a captured boolean, so the tasks remain
Configuration Cache compatible, and the original override behavior is restored.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7d293fd. Configure here.
…(CC)
Addresses two more review findings plus a failure surfaced by a full
bundle run under the configuration cache:
1. `copyOptionsFileEnabled` is now a `Property` set in `afterEvaluate` (after
the app build.gradle evaluates), so a `project.ext.shouldCopySentryOptionsFile`
override placed after `apply from` is honored — mirroring the deferral
already applied for `shouldSentryAutoUploadGeneral`.
2. `resolveSentryCliPackagePath(reactRoot)` is now resolved at configuration
time and captured, instead of being called inside the `*_SentryUpload`
`doLast` exec closure. A `:app:createBundle...JsAndAssets` run with
`configuration-cache=true` showed the previous revision still failed at
execution ("Could not find method resolveSentryCliPackagePath() ... on
DefaultExecAction_Decorated"): a serialized task action cannot resolve
top-level script methods.
Verified on a fresh configuration-cache store (React Native 0.83.9,
Gradle 9.0.0): copySentryJsonConfiguration, _SentryUpload, and
_SentryCollectModules execute with no sentry.gradle hard failure. Only the
pre-existing warn-level config-time `require.resolve` external processes
(resolveSentryReactNativeSDKPath / resolveSentryCliPackagePath) remain, which
are out of scope for this PR.
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Update — I ran a full The upload task's After that fix, a fresh configuration-cache store shows So the change now covers both |

📜 Description
Makes the two Sentry Gradle tasks compatible with the Gradle Configuration Cache by removing
project-state access at execution time.Fixes the hard failure reported in #6466 (and the earlier #4252):
...which also occurs for
:app:copySentryJsonConfiguration. These are hard, non-warnable exceptions —org.gradle.configuration-cache.problems=warndoes not rescue them.What changed in
packages/core/sentry.gradle.ktsThe exec-time
projectaccesses were:onlyIf { shouldCopySentryOptionsFile() }/onlyIf { shouldSentryAutoUploadGeneral() }— these resolve closures stored inproject.extra, so evaluating theonlyIf(at execution time) dereferencesproject.copySentryJsonConfiguration'sdoLast:project.rootDirandcopy { … }(i.e.project.copy).*_SentryUploadtask actions:project.loggerandProject.file(...).resolveSentryCliPackagePath(...)(called from the uploaddoLast) used.directory(rootDir).Fixes, all behaviour-preserving and using patterns already present in this file (the CLI itself already runs via an injected
ExecOperations):vals referenced by theonlyIfspecs.project.rootDircaptured at configuration time.copy { }→ an injectedFileSystemOperations(InjectedFsOps), mirroringInjectedExecOps.project.logger→ the task's ownlogger.Project.file("$reactRoot/…")→File("$reactRoot/…")(path is already absolute).resolveSentryCliPackagePathresolves fromreactRootinstead ofrootDir.This is an interim step ahead of the full SAGP migration tracked in getsentry/sentry-android-gradle-plugin#796.
Out of scope (called out for transparency)
resolveSentryReactNativeSDKPathstill runsnode --print require.resolve(...)as an external process at configuration time. That is a separate, warn-level Configuration Cache problem shared with several other React Native libraries (netinfo, keychain, keyboard-controller, …) and does not fail the build the way theonlyIfdid. Left for a follow-up so this PR stays focused on the hard failures.💡 Motivation and Context
Gradle 9 recommends the Configuration Cache by default and nags on every build; the configuration phase is a meaningful share of Android build time on large RN apps. Today
sentry.gradle(.kts)makes the build error out entirely when it's enabled. See #6466 for the full analysis.💚 How did you test it?
Verified end-to-end on a React Native 0.83.9 app with Gradle 9.0.0 (
org.gradle.configuration-cache=true,problems=warn).Because the released
8.xline still ships the Groovysentry.gradle(the.ktsis a8.14.0+rewrite of the same logic), the fix was proven against the equivalent Groovy script installed via 8.10.0, then ported here 1:1 to Kotlin:sentry.gradleCould not evaluate onlyIf predicate for task ':app:copySentryJsonConfiguration'→ BUILD FAILED> Task :app:copySentryJsonConfigurationruns → BUILD SUCCESSFULAfter the fix, the remaining Configuration Cache problems are only the warn-level config-time external-process ones noted above (no
sentry.gradlehard failure).The
*_SentryUploadtask action changes (logger,file(),resolveSentryCliPackagePath) are the same violation classes; they were applied by static analysis (a real upload run needs live credentials), withcopySentryJsonConfigurationas the empirical anchor for the sharedonlyIf/project-access mechanism.📝 Checklist
CHANGELOG.mdentry (Unreleased → Fixes).Closes #6466
Generated with Claude Code