[Crashlytics] Fix release build cache invalidation#8185
Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
Reuse the on-disk id when present and valid for the current mode; only generate a new UUID on first build, after clean, or when the mode flips. This lets the task report UP_TO_DATE and stops invalidating downstream release tasks (mergeResources, R8, packaging, bundling) on every build. Fixes firebase#6770
Covers: UP_TO_DATE on second run, resource preserved across rebuilds, re-run after clean, mode-toggle invalidates the task.
Wrap the existingMappingFileId() KDoc to satisfy ktfmt.
b02cde8 to
7e1c779
Compare
Source-file fingerprint drives UP_TO_DATE; id regenerates on edits.
Adds source-invalidation test; rewires firebase#6770 tests to buildGradleRunner.
| .withProjectDir(projectDir) | ||
| .withArguments(":injectCrashlyticsMappingFileIdRelease", "--configuration-cache") | ||
| .build() | ||
| buildGradleRunner( |
| if (!useBlank) { | ||
| this.obfuscatableSources.from( | ||
| project.fileTree("src").matching { patterns -> | ||
| patterns.include( |
There was a problem hiding this comment.
We tried something like this before, it looked more like this.sourceFiles.from(variant.sources.java?.all, variant.sources.kotlin?.all)
But this created circular dependencies when apps used things like compose. If source depends on resources, and resources depend on sources, we have a circular dependency. Can you confirm if this has the same problem?
There was a problem hiding this comment.
Ran both implementations against the real repro6770 app
| App configuration | variant.sources.java?.all + kotlin?.all |
Current fileTree("src") |
|---|---|---|
| Compose only | builds, no cycle | builds, no cycle |
| Compose + viewBinding | Circular dependency — BUILD FAILED | builds; inject SUCCESS → UP-TO-DATE; id stable |
Compose alone is not a trigger, the trigger is view/data binding. So the circular dependency will only be present if I use variant.sources.java?.all + kotlin?.all + view/data binding.
The project.fileTree("src") form builds cleanly on the same app (task UP-TO-DATE on rebuild, stable id) because it's a plain FileTree: no builtBy/task-dependency edges for Gradle to order against, and it only scans src/**. Never build/generated/** where the binding-generated sources live.
Crashlytics: content-driven mapping file id for release builds
Fixes #6770
injectCrashlyticsMappingFileIdReleaseminted a new UUID on every release build, cascading throughmergeResources→processResources→ R8 → packaging and breaking the build cache for every minified release.This PR makes the task content-driven: Gradle's input snapshotting decides when to re-execute. While the variant's user sources are unchanged, the task stays
UP-TO-DATEand the entire downstream cascade stays cached. When sources change — which is when R8 would produce a differentmapping.txt— the task re-runs and a fresh id is minted.How
useBlankMappingFileIdpromoted from@Internalto@Input(mode flip natively invalidates).@InputFiles obfuscatableSourcespopulated fromproject.fileTree("src")withjava/**+kotlin/**patterns (tests excluded). Path-based, no task deps — sidesteps the cycle thatvariant.sources.*.allwould close through AGP's resource graph.upToDateWhenand on-disk reuse path removed.Verification
:spotlessApply,:validatePlugins,:test,:functionalTest— green (19/19).compileSdk36, real Firebase project). Pre-fix plugin3.0.3flipsmappingFileId.txtevery rebuild and re-runs the full cascade. With this branch (mavenLocal()), the id stays byte-identical across rebuilds, every downstream task isUP-TO-DATE, secondassembleReleasefinishes in ~1s. Editing a Kotlin source mints a new id;cleanandmappingFileUploadEnabledtoggle behave as expected.Verification from manual test plan above
compileSdk36,isMinifyEnabled = true, real Firebase project).com.google.firebase.crashlytics:3.0.3—mappingFileId.txtflipped every rebuild (f5f0310…→6514b43…), and:app:processReleaseResources,:app:uploadCrashlyticsMappingFileRelease,:app:packageRelease,:app:assembleReleaseall re-executed with no source changes.mavenLocal()as3.0.7and bumping the app's plugin version —mappingFileId.txtstays byte-identical across rebuilds,:app:injectCrashlyticsMappingFileIdReleasereportsUP-TO-DATE, and the full downstream cascade (:mergeReleaseResources,:processReleaseResources,:minifyReleaseWithR8,:packageRelease,:assembleRelease) isUP-TO-DATE. SecondassembleReleasefinishes in ~1s.cleanstill mints a fresh id, and togglingmappingFileUploadEnabled = falsere-runs the task and writes the blank id0…0.TEST_RESULTS_ISSUE_6770.md.