After three years experimenting with Bazel, in 2020 Spotify decided to adopt it as their official build system for the Spotify iOS app. Thanks to this, they could reduce build times to a fourth, explains Spotify engineer Patrick Balestra.
For the Spotify iOS team was crucial to complete the transition without ever stopping development or impacting release frequency. Previous to adopting Bazel, Spotify was using a custom-made Ruby DSL based on YAML to allow developers to add new modules declaratively, including the specification of a build target, the source files required to build it, as well as resources and dependencies. This was instrumental, says Balestra, to ensure a seamless transition to Bazel, since the same DSL scripts could be reused to generate BUILD.bazel files instead of Xcode .pxbproj files.
Switching to Bazel, as mentioned, brought build+test times down from 80 minutes (seven-day 75th percentile) to as little as 20 minutes.
We moved our CI configurations to Bazel one by one, starting with the configurations that took the longest. One in particular, with more than 800 test targets containing close to 3 million lines of code, took more than 45 minutes when building with Xcode. After moving to Bazel, this time decreased to less than 10 minutes.
According to Balestra, the improvement was mostly the result of Bazel's efficient remote cache as well as to its support for parallelizing builds across several machines.
The process was not so straightforward as just piping the builds into Bazel, though. Rather, it involved a careful process to identify performance issues and bottlenecks using the telemetry insights provided by BuildBuddy, a tool aimed at unlocking Bazel's power through a graphical user interface and a command line interface. Using bazel-diff the team could also better identify which portions of the build graphs were affected by each change in order to require only a minimal set of tests to be run for each new build.
To improve the coexistence between Xcode builds, which were run locally by developers, and Bazel builds, used in the CI infrastructure, Spotify adopted rules-xcodeproj. This allowed them to generate Xcode projects directly from Bazel build files instead of using the legacy Ruby/YAML build system, with the benefit of reducing cases where builds would succeed locally but fail in CI, which generated maintenance and troubleshooting costs.
The last step to complete the migration to Bazel was to define a rollout strategy where Bazel builds were directly deployed to employee devices for two weeks before being pushed through to external alpha and beta testers and final to the general audience.
With all this in place, the transition was carried through successfully, says Balestra, as also proved by crash and performance metrics, which showed no signicant differences.