Каждый коммит в iOS-приложении проходит долгий путь: от локальной машины разработчика до пользовательского устройства. В hh.ru этот путь автоматизирован настолько, чтобы минимизировать ручные операции и ускорить обратную связь. В статье разберём, как устроена инфраструктура, какие шаги проходит коммит, как проверяются сборки и какие метрики помогают понять, где узкие места. Материал будет полезен iOS-разработчикам и тимлидам, которые хотят выстроить похожий процесс.
Подготовка окружения и генерация проекта
Первый шаг — подготовка рабочего окружения. В hh.ru используют генерацию Xcode-проекта из шаблонов (например, через Tuist или XcodeGen), чтобы избежать конфликтов в .pbxproj и упростить добавление новых модулей. Разработчик клонирует репозиторий, запускает скрипт генерации и получает проект, готовый к сборке. Важно, чтобы генерация была детерминированной: одинаковый набор входных данных должен давать одинаковый проект. Это снижает количество «works on my machine» и упрощает CI.
Типичная ошибка — хранить сгенерированный проект в репозитории. Это приводит к конфликтам при слиянии и рассинхронизации. Лучше генерировать проект на лету и добавить его в .gitignore. Также стоит зафиксировать версии инструментов (Tuist, SwiftGen и т.д.) через lock-файлы, чтобы у всех участников и на CI использовались одинаковые версии.
Пайплайн: от коммита до проверок
После пуша в удалённый репозиторий запускается CI-пайплайн. Первым делом система определяет затронутые сервисы и модули. Для этого анализируются изменённые файлы и зависимости между модулями. Если изменения коснулись только одного модуля, нет смысла собирать и тестировать всё приложение. Такой подход экономит время и ресурсы.
Далее проект собирается один раз и переиспользуется в разных задачах: статический анализ, юнит-тесты, UI-тесты. Например, собранный .app или .xctestrun передаётся между шагами пайплайна. Это позволяет избежать повторных сборок и ускорить прохождение проверок. Важно кэшировать зависимости (CocoaPods, SPM) и промежуточные артефакты, чтобы не тратить время на повторную загрузку.
- Определение затронутых модулей по изменённым файлам и графу зависимостей.
- Сборка проекта один раз с кэшированием зависимостей.
- Параллельный запуск статического анализа и тестов, где это возможно.
- Публикация результатов обратно в pull request.
Результаты проверок должны быть доступны в PR: отчёты линтеров, результаты тестов, покрытие кода. Это ускоряет ревью и позволяет автору сразу видеть проблемы. Не стоит ограничиваться только статусом «упало/прошло» — нужны детали.
Статический анализ и UI-тесты
Статический анализ включает линтеры (SwiftLint), анализ зависимостей и проверку на наличие утечек памяти. Важно настроить правила так, чтобы они не мешали разработке, но ловили реальные проблемы. Например, можно начать с предупреждений, а затем постепенно переводить критичные правила в ошибки. Не стоит включать все правила сразу — это приведёт к большому количеству шума и игнорированию отчётов.
UI-тесты — самая ресурсоёмкая часть. В hh.ru их запускают не на каждый коммит, а по расписанию или для определённых веток. Чтобы ускорить, используют параллельный запуск на нескольких симуляторах и переиспользуют собранный проект. Также важно изолировать тесты друг от друга и очищать состояние между запусками. Типичная ошибка — запускать все UI-тесты на каждый коммит: это замедляет пайплайн и увеличивает очередь. Лучше разделить тесты на дымовые (быстрые) и полные (по расписанию).
Проверка сборок и релиз
Перед релизом собирается финальная сборка, которая проходит дополнительные проверки: подпись, размер, наличие необходимых ресурсов. В hh.ru используют отдельные конфигурации для разных сред (dev, staging, production). Важно, чтобы конфигурации были максимально приближены к продакшену, иначе можно пропустить ошибки, связанные с окружением.
После успешных проверок сборка попадает в TestFlight или внутренний магазин приложений. Релиз может быть постепенным (поэтапная раскатка), чтобы снизить риски. На этом этапе важно иметь метрики: время от коммита до релиза, частота падений, время прохождения пайплайна. Эти метрики помогают понять, где узкие места, и принимать решения об оптимизации.
- Собирайте метрики времени на каждом этапе: сборка, тесты, статический анализ, релиз.
- Определите целевое время для каждого этапа и отслеживайте отклонения.
- Пересматривайте частоту запуска тяжёлых тестов, если они не влияют на качество.
- Автоматизируйте ручные операции, чтобы уменьшить человеческий фактор.
Когда стоит сокращать повторы тестов? Если тесты стабильны и не находят ошибок на протяжении длительного времени, можно запускать их реже или только для изменённых модулей. Но не стоит полностью отказываться от проверок — это может привести к регрессиям.
В итоге, инфраструктура hh.ru — это баланс между скоростью и качеством. Ключевые принципы: генерация проекта, переиспользование сборок, определение затронутых модулей, информативные отчёты в PR и метрики для постоянного улучшения. Начните с малого: автоматизируйте сборку и базовые проверки, затем добавляйте новые шаги, измеряя их влияние.