Разработка
Как мы ускорили сборки для Android и iOS на 50%
Мы сделали наших инженеров счастливее, сократив время сборки с 50 минут до 16.
Представьте себе, что вы ждете каждой проверки кода до и после слияния более 50 минут. Звучит мучительно, верно? А теперь представьте, что вы проходите через эту каторгу 200 с лишним раз в неделю. Такова была наша реальность, пока мы, команда Test and Release Infrastructure (TRI), не решили, что хватит.
Переходим к сегодняшнему дню. Эти 50-минутные ожидания исчезли. Время сборки Android и iOS теперь составляет менее 20 минут. Вот подробная информация о том, как мы добились этого волшебства — да, это потребовало веселых экспериментов и немного пота (но, к счастью, без слез).
Что сработало (так называемый секретный соус)
1. Новые, более лучшие машины
Скажем прямо: старые AWS инстансы, на которых работали наши сборки, были похожи на попытки смотреть видео высокой четкости по коммутируемому соединению. Их обновление было очевидным первым шагом.
- Для Android: Мы протестировали 16 типов инстансов и на собственном опыте убедились, что увеличение мощности процессора для JVM не помогает — она потребляет много памяти! Экземпляры r7a, с их большим объемом памяти и надежной доступностью, оказались идеальными. Результат? Улучшение времени сборки на 21%. И еще совет: быстрый дисковый ввод-вывод (например, NVMe SSD) еще больше ускоряет сборку Android. Это следующий пункт в нашем списке дел.
- Для iOS: Компьютеры Apple Silicon M2 Mac гораздо эффективнее старых экземпляров mac1.metal на базе x86. Перейдя на машины EC2 mac2-m2.metal, мы сократили время сборки на 60%. Разработчики сразу же заметили улучшения.
И да, мы смирились с немного более высокими затратами. Новые машины стоят дороже, но благодаря более быстрой сборке они стоят каждого пенни.
2. Больше распараллеливания, меньше «узких мест».
Конвейеры CI похожи на переполненные перекрестки. Слишком много всего происходит в одном месте? Затык и пробка. Мы перестроили наши конвейеры, чтобы задачи двигались плавно:
- Для Android: Мы перегруппировали и оптимизировали задачи, сократив время их последовательного выполнения на 20%. Это позволило сбалансировать наши расходы на новые машины.
- Для iOS: Мы покончили с длительными задержками при запуске, отказавшись от конвейеров Jenkins в пользу свободных заданий. Время запуска сократилось, и наши разработчики получали свои сборки быстрее. (Бонус: мы создали отличную библиотеку на Python, чтобы сохранить часть синтаксического сахара, который мы любили в конвейерах).
3. Кэширование — король
Зачем изобретать колесо — или, в данном случае, заново собирать неизменный код?
- Кэширование зависимостей: кэшированные зависимости означают меньшее количество загрузок и меньшую задержку в сети. Для iOS мы взломали код встроенного кэширования SwiftPM, сэкономив ~4 минуты времени сборки.
- Кэширование задач: для Android мы использовали удаленный кэш Gradle в S3. Это позволило избежать лишних компиляций и повторно использовать результаты, когда это было возможно. Результат: сборка на 25% быстрее.
4. Обновления цепочки инструментов (они же «весенняя чистка»)
Иногда все, что вам нужно, — это обновление. Мы попрощались с KAPT (обработка аннотаций Kotlin) и приняли KSP, который быстрее и изящнее. Вместе с улучшением Kotlin это сократило время сборки Android еще на 30%.
Что не сработало (но попробовать стоило)
XCRemoteCache не помог
Мы возлагали большие надежды на XCRemoteCache, инструмент для удаленного кэширования iOS. Но после нескольких месяцев головной боли из-за пропусков кэша и загадочных сбоев в сборке мы были вынуждены отказаться от него. Извлеченный урок? Не каждый инструмент подходит для любой системы. Bazel — следующий в нашем плане.
Результаты: цифры и настроения
Основные выводы (что мы узнали)
- Маленькие победы имеют значение: Даже сокращение времени CI на несколько секунд дает большую разницу на сотнях PR. Разработчики замечают и ценят такие изменения.
- Скорость + стабильность = счастливые разработчики: Медленные, глючные сборки могут снизить производительность. Исправление ошибок и добавление логики повторных попыток позволило сделать работу плавной, быстрой и без разочарований.
- Сокращение отходов, ответственно: Новые машины означают рост затрат, но более разумное распределение ресурсов (привет, план экономии и группы автомасштабирования EC2!) позволяет держать ситуацию под контролем.
Итог
Улучшение времени сборки — это не просто улучшение CI, это создание лучшего опыта для разработчиков. А когда ваши разработчики счастливы, выигрывают все.
Если вы хотите работать в компании, которая ценит и оптимизирует инженерную простоту и превосходство, мы принимаем вас на работу!