Всем привет! Меня зовут Тарас, я руководитель релизной команды в inDriver. Команда разработки inDriver в 2022 году — это более 40 кроссфункциональных команд, которые делятся на платформенные и продуктовые. Всего в разработке около 350 инженеров, из них примерно 80 — мобильные разработчики.
C недавних пор мобильные релизы мы выкатываем каждую неделю. Ниже расскажу о том, как мы перешли с хаотичных релизов на регулярные, с какими проблемами столкнулись и как их решали.
Предыстория
В 2018 году разработка в inDriver состояла из 4 команд: Android, iOS, Backend и QA. В них было около 30 сотрудников, 10 из которых — мобильные разработчики. В это время релизы выкатывались только по необходимости — в основном, по готовности больших задач.
У такого подхода был ряд проблем:
Непонятно, когда будет следующий релиз. Сложно спрогнозировать выпуск новой фичи, так как срок больших задач мог занять от нескольких недель до нескольких месяцев.
Долгое ожидание релиза мелких задач. Мелкие улучшения и фиксы, которые уже могли принести пользу нашим пользователям, копились в ожидании релиза.
Долгий выпуск релиза. Из-за того, что в релиз попадало слишком много задач, была высока вероятность выявить множество багов, которые требовали больше времени на проверку. При больших изменениях сложнее найти все баги перед релизом, поэтому это исправлялось множеством хотфиксов, что также растягивало полноценный релиз. И это не говоря о тех задачах, которые «точно должны попасть, давай чуточку подвинем релиз, там осталось немного доделать».
Замедление разработки во время проверки релиза. Все новые фичи застревали на статусе Ready for Test, так как все основные силы тестировщиков на несколько дней перебрасывались на проверку релиза. И в это время новые фичи не могли пройти проверку.
Такая ситуация продолжалась до 2020 года. В конце 2020 года с увеличением штата разработки, мы провели большую трансформацию в структуре разработки и перешли на кроссфункциональные команды. И если недавно достаточно было договориться насчет релиза внутри одной команды, теперь таких команд стало 20. Мобильные разработчики, которые коммитили в общие репозитории, теперь сидели в разных командах, что накладывало ограничения на релиз приложения. Ведь каждая команда хотела релизить свои задачи в зависимости от своих планов и приоритетов.
Надо было что-то менять. Мы приняли решение о создании команды, которая занималась бы вопросами релиза. Так родилась релизная команда.
Переход на регулярные релизы
Первым шагом релизной команды стал переход на регулярные релизы. План был такой:
Определяем релизный цикл.
Фиксируем день недели для создания релизной ветки.
Создаем график релизов.
К этому моменту мы уже предприняли несколько попыток перехода. На их основе у нас сформировался четкий подход к релизам. Мы точно знали, что нам подходит двухнедельный релизный цикл с чередованием платформ. До этого пробовали трехнедельный, но он не устраивал скоростью доставки и тем, что на нем релизы получились достаточно большими, а это влияло на проверку. Поэтому с выбором релизного цикла мы определились быстро.
Днем недели для создании релизной ветки мы выбрали пятницу. Сделали это по несколькими причинами:
Хорошо подходит, потому что это синхронизируется с концом рабочей недели и с завершением спринтов.
Релиз в пятницу поможет ребятам не перерабатывать в выходные, стремясь успеть попасть в релиз.
Старт проверки релиза начинался в понедельник, так как продолжительность проверки релиза в это время занимала несколько дней. Хотелось бы, чтобы релиз успели проверить в течение недели.
Определив релизный цикл и дату среза, мы создали график релизов в Google Sheets:
Но это еще не все. Потребовалось несколько месяцев, чтобы команды привыкли к новому процессу. Оказалось, что никто не готов ждать 2 недели до следующего релиза, поэтому многие активно докидывали свои задачи. Из-за этого возникало много ошибок во время проверки релиза, что сдвигало даты.
Но были и позитивные изменения:
В релиз уже попадало не так много задач, они стали небольшими.
Ускорилась доставка нашего продукта. Мелкие задачи стабильно начали доходить до пользователей.
Появилась возможность планировать свои задачи на основе графика релиза.
В общем, появился более прозрачный процесс. Релизы стали регулярными и небольшими. Но вместе с этим возникло много рутинной работы, так же никуда не делась долгая проверка релиза. Поэтому следующими задачами стали автоматизация процесса и ускорение проверки релиза.
Автоматизация процесса релиза
Процесс релиза приложения состоит из нескольких этапов:
Подготовка релиз-кандидата.
Приемочное тестирование.
Загрузка и отправка релиза в стор на ревью.
Раскатка и мониторинг релиза.
Если все хорошо, то релиз раскатывается для всех пользователей.
На каждом из этапов выполняются определенные действия. Например, на этапе подготовки релиз-кандидата выполняются следующие шаги:
Создаем релизную ветку.
Создаем задачу для релиза.
Создаем pull request.
Собираем релизную сборку.
Повышаем версию приложения.
Получаем список задач и фиксируем их.
Отправляем уведомления о срезе.
Рутинная работа занимала много времени, поэтому мы решили ее автоматизировать. Для автоматизации всех вышеперечисленных шагов мы написали множество скриптов и сейчас активно развиваем свой внутренний сервис для релизов. Вот наш стек технологий:
GitHub Actions.
Bash, Python, Go.
Fastlane.
Docker.
Первым делом мы подготовили источник информации по релизам. Создали новый тип задачи Release в Jira и представили этапы релиза в виде схемы:
Это дало нам возможность понимать, на каком этапе находится той или иной релиз. Если до этого приходилось узнавать у людей, которые занимались релизом, теперь уже можно было не спрашивать.
В релизных задачах собираем необходимую информацию. Можно посмотреть список задач, номер сборки и статусы команд по подзадачам. По этим подзадачам на этапе проверки мы можем понять прогресс в отдельных командах.
Когда находятся баги и ошибки, привязываем их к релизной задаче. Так мы можем посмотреть текущее состояние релиза: сколько багов в работе и какие из них простаивают.
За статусами релизов можно следить в отдельном дашборде:
Создание релизной задачи происходит в пятницу в полночь. По расписанию в Github Action запускаются скрипты, которые выполняют уже рутинную работу.
А так выглядит уведомление о срезе:
Что в итоге:
Улучшили прозрачность релизного процесса. Теперь можно было видеть статусы релизов и список задач, вошедших в релиз.
Сократили рутинную работу, которая занимала много времени.
Стандартизировали процесс релиза под обе платформы.
Ускорение проверки релиза
Как я писал в начале, в 2018 году основная сила тестировщиков перебрасывалась на проверку релиза. В это время новые фичи не могли пройти проверку, что замедляло разработку во время проверки релиза. Чтобы решить проблему, мы решили проводить проверки только силами релизной команды.
Выделили в команду 4 тестировщиков и, тем самым, разгрузили другие команды. Помимо проверки релиза, ребята активно занимались налаживанием релизного процесса, написанием документации, онбордингом новичков и актуализацией тест-кейсов в TMS.
Но у такого подхода выявились ряд минусов:
Устаешь от довольно длительной проверки релиза.
Если кто-то из команды не может участвовать, это сразу дает увеличенную нагрузку на других ребят.
Замыливаются глаза, начинаешь пропускать ошибки.
Небольшой охват по девайсам.
Надо быть хорошим знатоком всех фич, чтобы быстро проверить все приложение.
Надо иметь хорошо написанные тест-кейсы, чтобы проверить незнакомый функционал.
Так продолжалось несколько месяцев. После этого, учитывая выявленные минусы, мы решили масштабировать проверку на всю команду тестировщиков.
Дело пошло гораздо лучше:
Проверка релиза происходит намного быстрее.
Большее покрытие по реальным девайсам.
Попутно улучшили знание продукта и его вертикалей у всех тестировщиков, что в дальнейшем облегчило возможную замену в команде или помощь при критических ситуациях.
Стало ясно, что дальше необходимо автоматизировать проверку релиза, чтобы уменьшить время проверки. Совместно с командой автоматизаторов, которые занимаются разработкой различных инструментов для тестирования, мы начали активно внедрять UI-тесты для проверки релиза. Для этого используем следующие инструменты:
Appium.
Kotlin, JUnit 5.
Docker, Selenoid.
GitHub Actions.
На данный момент UI-тестами покрыто около 30% от общего числа тест-кейсов из приемочного набора. А чтобы держать эти тесты зелеными и заранее обнаруживать баги, запускаем каждый день в ночных прогонах.
Итог
После перехода на регулярные релизы мы решили большинство наших проблем:
Создали график релизов. У команд появилась возможность планировать свои задачи, а бизнесу стало возможно планировать старты и заранее узнавать даты следующих релизов.
Автоматизировали большинство рутиной работы, которая занимала много времени. Это позволило сфокусироваться на других задачах, например, на активное внедрение UI-тестов.
Улучшили прозрачность релизного процесса. Теперь можно было проследить за статусом каждого релиза и посмотреть необходимую информацию.
Сократили время проверки релиза до 1 дня в понедельник, и это время активно сокращается за счет автоматизации.
Но несмотря на это, мы поняли, что у двухнедельного релизного цикла с чередованием платформ долгий срок доставки фич. Команды все равно не готовы ждать 2 недели до следующего релиза, а потом и полную раскатку приложения, поэтому максимально пытались докидывать задачи в релиз. Перед срезом релиза возникала большая очередь задач на влитие, что давало сильную нагрузку на CI. Плюс, из-за чередования платформ, у команд были несинхронные спринты.
Поэтому на следующий год была поставлена цель — перейти на еженедельные релизы. Для этого в конце 2021 года провели экспериментальный недельный релиз и собрали обратную связь от команды. По итогу эксперимента выявили несколько проблем, которые необходимо было улучшить, а что-то уже полностью поменять.
О том, как мы перешли на еженедельные релизы, я расскажу уже в следующей части статьи. Если у вас есть вопросы, буду рад ответить на них в комментариях.
Комментарии (4)
DevilDimon
27.06.2022 19:59+2Идеальных решений не бывает, и в статье хотелось бы услышать и про минусы частых релизов. Озвучу те, что вижу сам:
Release notes, как правило, не будут обновлять каждую неделю и переводить на десятки языков. Это требует усилий как редакторов/маркетологов, так и переводчиков. В итоге release notes превращаются во всеми ненавистные "bug fixes and performance improvements". Проверил - у inDriver в английском сторе примерно так и есть)
Частые релизы подталкивают разработчиков к атомарным мелким PRам и фича-флагам для включения фич. В итоге при ревью контекст кода всей задачи в голове имеет только тот, кто ее реализует, а полного ревью от начала до конца одними и теми же людьми не проводится (как минимум это не энфорсится). В результате в главную ветку может попасть что угодно, если разделить это на достаточно малые части). А обилие фича-флагов мешает пониманию, что в какой сборке приложения есть и в каком качестве - в итоге release notes даже если и будут, то будут бесполезны (фичи могут быть под a/b тестами, выключены/включены у части аудитории, перманентно выключены, но быть в коде и т.п.).
Следствие предыдущего - рост бинарника. Когда PR мелкие и ничего не меняют в боевом приложении (из-за фиче-флагов) их психологически легко принять, и код начинает резко расти. У Убера был кейс, когда приложение росло мегабайтами в неделю. Так же из-за этого сложно вычистить что-то из приложения - сложно понять, не используется ли это, не дописано ли ещё, или уже выпилено выключенным фиче-флагом.
Быстрые релизы не позволяют вносить фундаментальные ломающие изменения в процесс сборки без остановки релиз-поезда хотя бы на время. Когда до релиза три недели, можно сломать весь CI/CD и делать с ним что угодно пару недель. С еженедельными релизами сломать его так не получится. Далеко не всегда можно держать две системы параллельно, и недельные релизы проигрывают при важных изменениях (смена сервиса для переводов, смена провайдера удаленных машин, смена самой платформы, например, на self-hosted или обратно)
tegorov Автор
29.06.2022 11:56Спасибо, что поделились и подробно описали минусы. Некоторые из них мы попробовали решить так:
Для release notes у нас такая схема: 1 или 2 раза в месяц мы пишем подробный release notes. Для этого заранее собираем информацию по продуктовым изменениям и проверяем, чтобы не было такого, что это фича находилась на этапе раскатки. В остальные релизы используем стандартные тексты, их у нас несколько штук.
Чтобы следить за ростом бинарника мы настроили сбор метрики размера приложения. В случае сильного скачка размера это сразу отображается на графике, и потом берется на изучение причины.
Один из минусов — сильная нагрузка на тестирование, чтобы поддерживать такие темпы. Если проект достаточно большой, то тут без автоматизации будет сложно.
Есть еще проблема влияния внешних факторов, независящих от нас:
Долгое ревью в сторе. Недавно в Google Play наше приложение проходило проверку примерно в 1,5 недели.
Режекты при ревью.
Незапланированные изменения, которые надо обязательно отправить.
Такие случаи не так часто происходят, но иногда бывают. Это создает «пробку» в релизах: отодвигаются даты следующих релизов, некоторые даже могут схлопываться. В это время в проекте могут жить несколько релизных веток, и тут тоже могут возникнуть проблемы.
whalemare
Как вы двигаете задачку с релизом по статусам? Поллингом опрашиваете маркеты?
Ваша релизная команда всецело занимается только скриптами для деплоя или просто выделяется время у разработчиков фичей по необходимости?
tegorov Автор
Сейчас релизные задачи двигаем вручную. Автоматическое изменение статусов в планах.
Наша команда всецело занимается мобильными релизами и всем что с ним связано, в том числе улучшением и поддержкой CI/CD, UI-тестов.