Slide 1

Slide 1 text

Speeding up the build 
 process of a monolithic app Maciej Piotrowski

Slide 2

Slide 2 text

20 million customers each month one of top ten most visited e-commerce sites worldwide mobile apps big chunk of traffic The most popular product search engine in Poland

Slide 3

Slide 3 text

370 804 LOC 3.2 GHz 6-Core CPU 32 GB RAM 5+ minutes on CI servers 2.2 GHz 6-Core CPU 32 GB RAM 10+ minutes on workstations compiled

Slide 4

Slide 4 text

Swift + Objective-C (LoC) 400 000 500 000 600 000 329 692 676 303 19 month increment (Jun 2019 - Dec 2020)

Slide 5

Slide 5 text

when # lines of code grow the compilation time follows

Slide 6

Slide 6 text

Clean Build (s) 190 130 88 177 220 250 307 12 month increment (Jun 2019 - May 2020) 238

Slide 7

Slide 7 text

Clean Build (s) 190 130 88 177 220 250 307 19 month increment (Jun 2019 - Dec 2020) 238

Slide 8

Slide 8 text

Codebase lifecycle

Slide 9

Slide 9 text

Clean Build (s) 190 130 177 220 250 307 19 month increment (Jun 2019 - Dec 2020) 238 How did we compile 78 modules in 88 s? 88

Slide 10

Slide 10 text

How to achieve fast compile times? build & cache binaries of frameworks tuist.io bazel.build buck.build

Slide 11

Slide 11 text

BUILD project files bazel build //Modules/Cart single language codebase unified structure of sub-projects

Slide 12

Slide 12 text

one more thing … goal: provide seamless developer experience BUILD project files bazel build //Modules/Cart multi language codebase (Swift+ObjC) undefined structure of sub-projects

Slide 13

Slide 13 text

Unify projects’ structure

Slide 14

Slide 14 text

Unify projects’ structure and settings Cart-Debug.xcconfig

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

yonaskolb/XcodeGen

Slide 17

Slide 17 text

Describe project’s structure in an .yml manifest xcodegen -spec project.yml

Slide 18

Slide 18 text

How to enforce same structure for new modules? modulegen tool: unzips a template replaces integrates into workspace links as a dependency

Slide 19

Slide 19 text

apple/swift-argument-parser

Slide 20

Slide 20 text

github.com/paciej00/replace-in-file-cli

Slide 21

Slide 21 text

./replace project.yml Cart

Slide 22

Slide 22 text

./replace project.yml Cart

Slide 23

Slide 23 text

./modulegen generate NewFancyFeatureModule ./xcodegen generate --spec Modules/Cart/project.yml ./fixme.sh --force

Slide 24

Slide 24 text

./steve generate NewFancyFeatureModule ./steve fixme -g ./steve fixme -f

Slide 25

Slide 25 text

OVERVIEW: Steve provides you a convenient way to solve daily development problems and complete repetitive tasks. USAGE: steve OPTIONS: --version Show the version. -h, --help Show help information. SUBCOMMANDS: fixme Fixes most common issues that developers encounter generate Allows to generate multiple items related to Allegro app bazel Use this command to invoke bazel with parameters focus Allows you to focus on selected modules from Allegro workspace test Run tests for given project and scheme

Slide 26

Slide 26 text

unified structure of sub-projects single language codebase BUILD file bazel build //Modules/Cart Bazel integration

Slide 27

Slide 27 text

Bazel BUILD file

Slide 28

Slide 28 text

bazel query 'deps(//Modules/Cart)' --noimplicit_deps --output package

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

bazel query 'rdeps(//Modules/..., //Modules/Networking)’ --output graph

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

Bazel BUILD file

Slide 33

Slide 33 text

Bazel rule allegro_xcodebuild_module.bzl

Slide 34

Slide 34 text

allegro_xcodebuild_module.bzl Bazel rule

Slide 35

Slide 35 text

Bazel rule allegro_xcodebuild_module.bzl

Slide 36

Slide 36 text

Bazel rule allegro_xcodebuild_module.bzl

Slide 37

Slide 37 text

Bazel rule allegro_xcodebuild_module.bzl

Slide 38

Slide 38 text

Bazel rule allegro_xcodebuild_module.bzl

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

./steve focus cart

Slide 41

Slide 41 text

./steve focus cart

Slide 42

Slide 42 text

Continuous Integration A CI plan with 2 jobs fills a remote cache per each PR and the main branch: - job building frameworks for iOS simulator - job building frameworks for iOS device

Slide 43

Slide 43 text

Bazel can cache any output by executing an action on inputs

Slide 44

Slide 44 text

bazel test //Modules/Cart:Cart_Tests

Slide 45

Slide 45 text

bazel test //Modules/Cart:Cart_Tests

Slide 46

Slide 46 text

Bazel gotchas

Slide 47

Slide 47 text

190 130 88 177 220 250 307 238 Bazel gotchas

Slide 48

Slide 48 text

Bazel gotchas just opening Storyboard/XIBs can invalidate cache exclude .DS_STORE otherwise it can invalidate cache single language codebase not needed no progress bar while running Bazel by a run script in Xcode

Slide 49

Slide 49 text

from 32 to 78 in 1 year ./steve jobs more small modules = faster builds 307s 88s 57s ./xcodegen generate -s project.yml

Slide 50

Slide 50 text

allegro.tech Speeding up iOS builds with Bazel Speeding up warm builds in Xcode Maciej Piotrowski twitter.com/paciej00

Slide 51

Slide 51 text

https://allegro.tech/2020/12/speeding-up-ios-builds-with-bazel.html https://allegro.tech/2020/12/speeding-up-warm-builds.html https://bazel.build https://buck.build https://tuist.io https://docs.bazel.build/versions/3.7.0/tutorial/ios-app.html https://github.com/yonaskolb/XcodeGen https://github.com/bazelbuild/rules_apple https://github.com/apple/swift-argument-parser https://github.com/paciej00/replace-in-file-cli