Slide 1

Slide 1 text

Scaling Android Builds in Pandemic Times Iñaki Villar @inyaki_mwc

Slide 2

Slide 2 text

BUILD

Slide 3

Slide 3 text

BUILD GRADLE PLUGINS .GRADLE .KTS

Slide 4

Slide 4 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 5

Slide 5 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 6

Slide 6 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP ~/.gradle — wrapper — caches — modules-2 — files-1 — …

Slide 7

Slide 7 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 8

Slide 8 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP ./gradlew clean

Slide 9

Slide 9 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 10

Slide 10 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP LOCAL CACHE

Slide 11

Slide 11 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 12

Slide 12 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 13

Slide 13 text

- Task Type / Classpath - Build Stack Components (Gradle, AGP, KGP, builders…) - Build script when affects execution of the task - Names of the output properties Build Cache Key

Slide 14

Slide 14 text

- Task Type / Classpath Build cache key for task 'generateDebugBuildConfig' is d7ac6c5c1072df6d3f86efda018f0136 - Build Stack Components (Gradle, AGP, KGP, builders…) - Build script when affects execution of the task - Names of the output properties Build Cache Key

Slide 15

Slide 15 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 16

Slide 16 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP ./gradlew clean

Slide 17

Slide 17 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 18

Slide 18 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP GRADLE REMOTE

Slide 19

Slide 19 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 20

Slide 20 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP rm -rf ~/.gradle/caches

Slide 21

Slide 21 text

BUILD GRADLE PLUGINS .GRADLE .KTS DEP DEP DEP DEP DEP DEP

Slide 22

Slide 22 text

BUILD LOCAL CACHE REMOTE CACHE

Slide 23

Slide 23 text

BUILD LOCAL CACHE REMOTE CACHE GRADLE ENTERP. REDIS S3

Slide 24

Slide 24 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } }

Slide 25

Slide 25 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } }

Slide 26

Slide 26 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } } https://docs.gradle.org/current/dsl/org.gradle.caching.http.HttpBuildCache.html

Slide 27

Slide 27 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } }

Slide 28

Slide 28 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } } buildCache { registerBuildCacheService(S3.class, S3CacheFactory.class) remote(S3.class) { enabled = true push = true region = AWS_REGION bucket = AWS_BUCKET awsAccessKeyId = AWS_KEY awsSecretKey = AWS_SECRET awsSessionToken = AWS_TOKEN } }

Slide 29

Slide 29 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } } buildCache { registerBuildCacheService(S3.class, S3CacheFactory.class) remote(S3.class) { enabled = true push = true region = AWS_REGION bucket = AWS_BUCKET awsAccessKeyId = AWS_KEY awsSecretKey = AWS_SECRET awsSessionToken = AWS_TOKEN } }

Slide 30

Slide 30 text

buildCache { local { enabled = !gradle.ext.isCi } remote(HttpBuildCache) { url = buildCacheUrl push = gradle.ext.isCi } } buildCache { registerBuildCacheService(S3.class, S3CacheFactory.class) remote(S3.class) { enabled = true push = true region = AWS_REGION bucket = AWS_BUCKET awsAccessKeyId = AWS_KEY awsSecretKey = AWS_SECRET awsSessionToken = AWS_TOKEN } }

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

CI BUILD REMOTE CACHE LOCAL BUILD LOCAL BUILD LOCAL BUILD

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Task Task Task Task Task Task Task Task Task

Slide 35

Slide 35 text

Task Task Task Task Task Task Task Task Task

Slide 36

Slide 36 text

Task Task Task Task Task Task Task Task Task 2k tasks

Slide 37

Slide 37 text

Task Task Task Task Task Task Task Task Task 2k tasks

Slide 38

Slide 38 text

Task Task Task Task Task Task Task Task Task 2k tasks 13m 42s

Slide 39

Slide 39 text

Task Task Task Task Task Task Task Task Task 2k tasks 13m 42s 99% Hit Ratio

Slide 40

Slide 40 text

Task Task Task Task Task Task Task Task Task 6k tasks

Slide 41

Slide 41 text

Task Task Task Task Task Task Task Task Task 6k tasks 3m 10s 100% Hit Ratio

Slide 42

Slide 42 text

CI BUILD LOCAL BUILD

Slide 43

Slide 43 text

CI BUILD LOCAL BUILD

Slide 44

Slide 44 text

CI BUILD LOCAL BUILD —scan

Slide 45

Slide 45 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 CI BUILD LOCAL BUILD

Slide 46

Slide 46 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 CI BUILD LOCAL BUILD

Slide 47

Slide 47 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 CI BUILD LOCAL BUILD

Slide 48

Slide 48 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 CI BUILD LOCAL BUILD

Slide 49

Slide 49 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 CI BUILD LOCAL BUILD

Slide 50

Slide 50 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 CI BUILD LOCAL BUILD

Slide 51

Slide 51 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 CI BUILD LOCAL BUILD

Slide 52

Slide 52 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 CI BUILD LOCAL BUILD

Slide 53

Slide 53 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 Remote Cache (HTTP) Operations Hit 4027 Miss library:ui:kaptDebugKotlin library:ui:compileDebugKotlin app:kaptDebugKotlin app:compileDebugKotlin … CI BUILD LOCAL BUILD

Slide 54

Slide 54 text

Task requested from cache 6805 Hit 6805 100% Local disabled Remote 6805 100% Miss 0 Task requested from cache 6805 Hit 6755 99% Local 2728 40% Remote 4027 59% Miss 50 Remote Cache (HTTP) Operations Hit 4027 Miss library:ui:kaptDebugKotlin library:ui:compileDebugKotlin app:kaptDebugKotlin app:compileDebugKotlin … CI BUILD LOCAL BUILD

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Infrastructure

Slide 61

Slide 61 text

Switches

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

gradleEnterprise { buildScan { isCaptureTaskInputFiles = true } }

Slide 65

Slide 65 text

gradleEnterprise { buildScan { isCaptureTaskInputFiles = true } } ./gradlew build -Dscan.capture-task-input-files

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

./gradlew build -PisStrictModeEnabled=true

Slide 75

Slide 75 text

Cache misses

Slide 76

Slide 76 text

Cache misses Directory is only declared as an input in build A

Slide 77

Slide 77 text

Cache misses

Slide 78

Slide 78 text

Cache misses

Slide 79

Slide 79 text

Cache misses

Slide 80

Slide 80 text

Cache misses

Slide 81

Slide 81 text

Cache misses

Slide 82

Slide 82 text

https://developers.soundcloud.com/blog/gradle-remote-build-cache-misses-part-2 https://developers.soundcloud.com/blog/gradle-remote-build-cache-misses By Nelson Osacky Cache misses

Slide 83

Slide 83 text

Analyzing Local Builds

Slide 84

Slide 84 text

-Dorg.gradle.caching.debug=true Analyzing Local Builds

Slide 85

Slide 85 text

> Task :library:data:generateDebugBuildConfig 'appPackageName' to build cache key: f6bd6b3389b872033d462029172c8612 'buildConfigPackageName' to build cache key: 314a123772713f0e033d60dfa62e8a83 'buildTypeName' to build cache key: 1d2b35e3e2924d8f29639aa6b3873a11 'debuggable' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'enableGradleWorkers' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'flavorName' to build cache key: f1d3ff8443297732862df21dc4e57262 'itemValues' to build cache key: 8222d82255460164427051d7537fa305 'library' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'versionCode' to build cache key: 8d6fc65b288946cac11b2aaa4ef11de5 'versionName' to build cache key: f13b59d185c6ccc578fb0e600efd5f05 'mergedManifests' to build cache key: 5fd1e7396e8de4cb5c23dc6aadd7787a Appending output property name to build cache key: sourceOutputDir Build cache key for task ':library:data:generateDebugBuildConfig' is d7ac6c5c1072df6d3f86efda018f0136

Slide 86

Slide 86 text

> Task :library:data:generateDebugBuildConfig 'appPackageName' to build cache key: f6bd6b3389b872033d462029172c8612 'buildConfigPackageName' to build cache key: 314a123772713f0e033d60dfa62e8a83 'buildTypeName' to build cache key: 1d2b35e3e2924d8f29639aa6b3873a11 'debuggable' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'enableGradleWorkers' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'flavorName' to build cache key: f1d3ff8443297732862df21dc4e57262 'itemValues' to build cache key: 8222d82255460164427051d7537fa305 'library' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'versionCode' to build cache key: 8d6fc65b288946cac11b2aaa4ef11de5 'versionName' to build cache key: f13b59d185c6ccc578fb0e600efd5f05 'mergedManifests' to build cache key: 5fd1e7396e8de4cb5c23dc6aadd7787a Appending output property name to build cache key: sourceOutputDir Build cache key for task ':library:data:generateDebugBuildConfig' is d7ac6c5c1072df6d3f86efda018f0136

Slide 87

Slide 87 text

> Task :library:data:generateDebugBuildConfig 'appPackageName' to build cache key: f6bd6b3389b872033d462029172c8612 'buildConfigPackageName' to build cache key: 314a123772713f0e033d60dfa62e8a83 'buildTypeName' to build cache key: 1d2b35e3e2924d8f29639aa6b3873a11 'debuggable' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'enableGradleWorkers' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'flavorName' to build cache key: f1d3ff8443297732862df21dc4e57262 'itemValues' to build cache key: 8222d82255460164427051d7537fa305 'library' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'versionCode' to build cache key: 8d6fc65b288946cac11b2aaa4ef11de5 'versionName' to build cache key: f13b59d185c6ccc578fb0e600efd5f05 'mergedManifests' to build cache key: 5fd1e7396e8de4cb5c23dc6aadd7787a Appending output property name to build cache key: sourceOutputDir Build cache key for task ':library:data:generateDebugBuildConfig' is d7ac6c5c1072df6d3f86efda018f0136

Slide 88

Slide 88 text

> Task :library:data:generateDebugBuildConfig 'appPackageName' to build cache key: f6bd6b3389b872033d462029172c8612 'buildConfigPackageName' to build cache key: 314a123772713f0e033d60dfa62e8a83 'buildTypeName' to build cache key: 1d2b35e3e2924d8f29639aa6b3873a11 'debuggable' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'enableGradleWorkers' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'flavorName' to build cache key: f1d3ff8443297732862df21dc4e57262 'itemValues' to build cache key: 8222d82255460164427051d7537fa305 'library' to build cache key: f6d7ed39fe24031e22d54f3fe65b901c 'versionCode' to build cache key: 8d6fc65b288946cac11b2aaa4ef11de5 'versionName' to build cache key: f13b59d185c6ccc578fb0e600efd5f05 'mergedManifests' to build cache key: 5fd1e7396e8de4cb5c23dc6aadd7787a Appending output property name to build cache key: sourceOutputDir Build cache key for task ':library:data:generateDebugBuildConfig' is d7ac6c5c1072df6d3f86efda018f0136

Slide 89

Slide 89 text

CI BUILD LOCAL BUILD

Slide 90

Slide 90 text

coroutinesStr$kotlin_gradle_plugin sourceCompatibility targetCompatibility classpath commonSourceSet CI BUILD LOCAL BUILD incrementalCompilationEnabled

Slide 91

Slide 91 text

f6bd6b3389b872033d462029172c8612 f6bd6b3389b872033d462029172c8612 coroutinesStr$kotlin_gradle_plugin incrementalCompilationEnabled sourceCompatibility targetCompatibility classpath commonSourceSet 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 5fd1e7396e8de4cb5c23dc6aadd7787a 5fd1e7396e8de4cb5c23dc6aadd7787a CI BUILD LOCAL BUILD f6d7ed39fe24031e22d54f3fe65b901c 8222d82255460164427051d7537fa305

Slide 92

Slide 92 text

f6bd6b3389b872033d462029172c8612 f6bd6b3389b872033d462029172c8612 coroutinesStr$kotlin_gradle_plugin sourceCompatibility targetCompatibility classpath commonSourceSet 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 5fd1e7396e8de4cb5c23dc6aadd7787a 5fd1e7396e8de4cb5c23dc6aadd7787a f6d7ed39fe24031e22d54f3fe65b901c 8222d82255460164427051d7537fa305 CI BUILD LOCAL BUILD incrementalCompilationEnabled

Slide 93

Slide 93 text

100%?

Slide 94

Slide 94 text

100%?

Slide 95

Slide 95 text

https://github.com/gradle/android-cache-fix-gradle-plugin

Slide 96

Slide 96 text

https://github.com/gradle/android-cache-fix-gradle-plugin

Slide 97

Slide 97 text

https://github.com/gradle/android-cache-fix-gradle-plugin

Slide 98

Slide 98 text

https://github.com/gradle/android-cache-fix-gradle-plugin plugins { id(“org.gradle.android.cache-fix”).version(“1.0.13") }

Slide 99

Slide 99 text

No content

Slide 100

Slide 100 text

BUILD ENVIRONMENT CI REMOTE CACHE LOCAL BUILD LOCAL BUILD LOCAL BUILD

Slide 101

Slide 101 text

REMOTE CACHE LOCAL BUILD LOCAL BUILD LOCAL BUILD CI INTERNAL BUILD ENVIRONMENT EXTERNAL BUILD ENVIRONMENT

Slide 102

Slide 102 text

REMOTE CACHE LOCAL BUILD LOCAL BUILD LOCAL BUILD POPULATE CACHE JOB CI INTERNAL BUILD ENVIRONMENT EXTERNAL BUILD ENVIRONMENT REPOSITORY

Slide 103

Slide 103 text

CI BUILD EXTERNAL BUILD ENVIRONMENT REPOSITORY CI BUILD CI BUILD CI BUILD

Slide 104

Slide 104 text

CI BUILD EXTERNAL BUILD ENVIRONMENT REPOSITORY CI BUILD CI BUILD CI BUILD BUILD CACHE

Slide 105

Slide 105 text

CI BUILD EXTERNAL BUILD ENVIRONMENT REPOSITORY CI BUILD CI BUILD CI BUILD BUILD CACHE S3 BUCKET

Slide 106

Slide 106 text

CI BUILD EXTERNAL BUILD ENVIRONMENT REPOSITORY CI BUILD CI BUILD CI BUILD BUILD CACHE S3 BUCKET AWS-CLI AWS ROLE AES_256

Slide 107

Slide 107 text

RESULTS

Slide 108

Slide 108 text

RESULTS

Slide 109

Slide 109 text

f6bd6b3389b872033d462029172c8612 Task X COMMIT MAIN

Slide 110

Slide 110 text

f6bd6b3389b872033d462029172c8612 Task X COMMIT MAIN POPULATE CACHE

Slide 111

Slide 111 text

f6bd6b3389b872033d462029172c8612 Task X COMMIT MAIN POPULATE CACHE REPO LOCAL BUILD

Slide 112

Slide 112 text

f6bd6b3389b872033d462029172c8612 Task X COMMIT MAIN POPULATE CACHE REPO LOCAL BUILD f6bd6b3389b872033d462029172c8612 Task X

Slide 113

Slide 113 text

f6bd6b3389b872033d462029172c8612 Task X COMMIT MAIN POPULATE CACHE REPO LOCAL BUILD f6bd6b3389b872033d462029172c8612 Task X

Slide 114

Slide 114 text

f6bd6b3389b872033d462029172c8612 8222d82255460164427051d7537fa305 Task X COMMIT MAIN POPULATE CACHE REPO LOCAL BUILD Task X

Slide 115

Slide 115 text

f6bd6b3389b872033d462029172c8612 314a123772713f0e033d60dfa62e8a83 Task X COMMIT MAIN POPULATE CACHE REPO LOCAL BUILD Task X

Slide 116

Slide 116 text

? POPULATE CACHE

Slide 117

Slide 117 text

? POPULATE CACHE BUILD STACK GRADLE AGP KGP BULDSRC INVALIDATE CACHE

Slide 118

Slide 118 text

PR PR PR PR

Slide 119

Slide 119 text

+ + + + BUILD STACK CHANGE GRADLE AGP KGP BULDSRC PR PR PR PR

Slide 120

Slide 120 text

+ + + + BUILD STACK CHANGE GRADLE AGP KGP BULDSRC REMOTE CACHE 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 5fd1e7396e8de4cb5c23dc6aadd7787a PR PR PR PR

Slide 121

Slide 121 text

+ + + + BUILD STACK CHANGE GRADLE AGP KGP BULDSRC REMOTE CACHE LOCAL BUILD LOCAL BUILD LOCAL BUILD LOCAL BUILD 314a123772713f0e033d60dfa62e8a83 1d2b35e3e2924d8f29639aa6b3873a11 8d6fc65b288946cac11b2aaa4ef11de5 5fd1e7396e8de4cb5c23dc6aadd7787a PR PR PR PR

Slide 122

Slide 122 text

RESULTS

Slide 123

Slide 123 text

RESULTS

Slide 124

Slide 124 text

Thanks

Slide 125

Slide 125 text

@ZacSweers @AutonomousApps @CesarDielo @arunkumar_9t2 @VladimirSitnikv @Louis_CAD @ubiratanfsoares @ychescale9 @sboishtyan @CristianGM_dev @nellyspageli @vRallev @artem_zin Thanks @anton_malinskiy @stepango @joenrv @schatchenko @___mokkun___ @jeoj

Slide 126

Slide 126 text

Thanks Iñaki Villar @inyaki_mwc