Optimizing Gradle Builds
Strategies to Identify, Resolve, and Avoid Cache Issues
Sinan Kozak
Sinan Kozak
Google Developer Expert
Staff Android Developer @DeliveryHero
Fast CI results? Quick local builds?
CI/CD is mostly more centralized in Delivery Hero.
Bigger customer team has splitted infra teams per topic, but
Logistics Tribe has one Mobile Infra.
Practical optimizations with tradeoffs are very critical.
Cycle time increase incident - March 24
90+ minutes
Long PR checks are unacceptable
What does bad look like?
How did it start?
Initial usage
Full migration
Convention plugin
and more tests
CI cost and Cycle time had skyrocketed
Why didn’t we notice earlier?
We had other planned changes that increased CI time.
● Running lint on test code
● Detect verification per commit
Build Benchmark
We use Gradle Profiler on CI to compare times
● Incremental build for ABI and non-ABI changes in critical modules
● Gradle Enterprise scan comparison
We didn’t have profiling for;
● Unit test compile
● Android test compile
Impact analysis
Problem grow with number of feature with screenshot test
● Convention plugin and training increased the speed
● 60+ of 450 modules has screenshot tests now
PR Check CI steps
● Checkout
● Setup
● Lint + Detect
● Unit Test
○ testDebugUnitTest
● Screenshot test
○ verifyPaparazziDebug
● Coverage
○ JoCoCo + dependOn(Test Tasks)
Why does Gradle disable cache for test task?
Where are details? What is output $2
-Dorg.gradle.caching.debug=true
Let’s investigate
Paparazzi suppose to be fast and run on JVM like any other junit test.
● Yes, it is faster to run.
● Yes, it runs on JVM. We don’t need emulator
● But, but, but…
Paparazzi Gradle Plugin configures the Test task
even for non Paparazzi tests!!
What would be nice setup?
● Verify screenshot tests by default
○ Create aggregated report on demand
○ Fail unit test when screenshot test fail
● Make screenshots folder input of tasks for verification case
○ Screenshots are input of verification
● Remove reports path as output. Html report aggregates with every run.
○ Reports are not reproducible.
● Record task is never up to date when we run record
90m -> 35m
~60% improvement after changing a Paparazzi Plugin setup.
Don’t modify cacheability of other tasks
But our devs never use the report
What will we work on next?
More benchmark cases on CI with Gradle Profile
● Unit test and Android Test builds
Make profiling automatic and blocker for certain type of PRs
● Dependency changes
Maintain internal Paparazzi plugin unless they change the defaults
https://github.com/cashapp/paparazzi/issues/1334
https://github.com/cashapp/paparazzi/issues/1365
Gist of modified Paparazzi Plugin
https://gist.github.com/kozaxinan/4b44f817b28ac409f950c041c3627eca
Thank you
Q&A?
Sinan Kozak
@snnkzk

Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024

  • 1.
    Optimizing Gradle Builds Strategiesto Identify, Resolve, and Avoid Cache Issues Sinan Kozak
  • 2.
    Sinan Kozak Google DeveloperExpert Staff Android Developer @DeliveryHero
  • 3.
    Fast CI results?Quick local builds? CI/CD is mostly more centralized in Delivery Hero. Bigger customer team has splitted infra teams per topic, but Logistics Tribe has one Mobile Infra. Practical optimizations with tradeoffs are very critical.
  • 4.
    Cycle time increaseincident - March 24
  • 5.
    90+ minutes Long PRchecks are unacceptable
  • 6.
    What does badlook like?
  • 7.
    How did itstart? Initial usage Full migration Convention plugin and more tests
  • 8.
    CI cost andCycle time had skyrocketed
  • 9.
    Why didn’t wenotice earlier? We had other planned changes that increased CI time. ● Running lint on test code ● Detect verification per commit
  • 10.
    Build Benchmark We useGradle Profiler on CI to compare times ● Incremental build for ABI and non-ABI changes in critical modules ● Gradle Enterprise scan comparison We didn’t have profiling for; ● Unit test compile ● Android test compile
  • 11.
    Impact analysis Problem growwith number of feature with screenshot test ● Convention plugin and training increased the speed ● 60+ of 450 modules has screenshot tests now
  • 12.
    PR Check CIsteps ● Checkout ● Setup ● Lint + Detect ● Unit Test ○ testDebugUnitTest ● Screenshot test ○ verifyPaparazziDebug ● Coverage ○ JoCoCo + dependOn(Test Tasks)
  • 13.
    Why does Gradledisable cache for test task?
  • 14.
    Where are details?What is output $2 -Dorg.gradle.caching.debug=true
  • 15.
    Let’s investigate Paparazzi supposeto be fast and run on JVM like any other junit test. ● Yes, it is faster to run. ● Yes, it runs on JVM. We don’t need emulator ● But, but, but… Paparazzi Gradle Plugin configures the Test task even for non Paparazzi tests!!
  • 18.
    What would benice setup? ● Verify screenshot tests by default ○ Create aggregated report on demand ○ Fail unit test when screenshot test fail ● Make screenshots folder input of tasks for verification case ○ Screenshots are input of verification ● Remove reports path as output. Html report aggregates with every run. ○ Reports are not reproducible. ● Record task is never up to date when we run record
  • 21.
    90m -> 35m ~60%improvement after changing a Paparazzi Plugin setup.
  • 22.
  • 23.
    But our devsnever use the report
  • 24.
    What will wework on next? More benchmark cases on CI with Gradle Profile ● Unit test and Android Test builds Make profiling automatic and blocker for certain type of PRs ● Dependency changes Maintain internal Paparazzi plugin unless they change the defaults https://github.com/cashapp/paparazzi/issues/1334 https://github.com/cashapp/paparazzi/issues/1365 Gist of modified Paparazzi Plugin https://gist.github.com/kozaxinan/4b44f817b28ac409f950c041c3627eca
  • 25.