Сегодня мы проведём экскурсию по цеху разработки Badoo, в котором создаётся новый функционал нашего сайта, расскажем о самом процессе — от постановки задачи и до момента выкладки в боевое окружение.
За время существования компании её рабочий процесс эволюционировал от стохастического к хорошо контролируемому и понятному. Ещё полтора-два года назад никто точно не мог ответить на вопрос, какие задачи попали в сегодняшнюю выкладку, а менеджер опрашивал программистов, кто и что выложил. Сейчас же процесс максимально автоматизирован, таск-трекер тесно связан с системой контроля версий, задачи проходят несколько стадий проверки. При этом сохранилась высокая скорость разработки: нормальной считается ситуация, когда задача появилась утром, а после обеда новый функционал уже доступен пользователям на сайте.
Основные этапы
Весь процесс можно разбить на этапы:
- Работа над продуктом: идея, подготовка ТЗ.
- Техническая реализация: декомпозиция, разработка.
- Тестирование и переводы на разные языки.
- Релиз для части пользователей.
- Релиз для всех.
Как известно, любой процесс держится на людях, участвующих в нём. Давайте посчитаем, сколько человек участвует в типовом случае описанного выше процесса: менеджер продукта, дизайнер, копирайтер, менеджер проекта, разработчик, верстальщик, разработчик-ревьювер, QA-инженер. В этом списке не хватает одного действующего лица. Кого же мы намеренно не упомянули? Напишите свой вариант в комментариях!
Девять человек — это минимальное количество участников процесса, когда мы разрабатываем новый функционал только на одном языке. Обычно это тестовый релиз для определённой группы пользователей или специальная промо-акция для конкретной страны. Когда мы делаем релиз для всех пользователей, в процесс включаются ещё и переводчики, которые осуществляют перевод на 40 языков. Некоторые языки поддерживаются в виде нескольких диалектов, например, американский английский и британский английский.
Весь процесс контролируется и формализуется с помощью чётко проработанного workflow в таск-трекере (мы используем JIRA, www.atlassian.com/software/jira/).
Работа над продуктом
Всё начинается с идеи. Обычно она появляется либо в рамках исследования «Как нам увеличить такой-то показатель», либо как улучшение существующего функционала. Разработку идеи доверяют определённому менеджеру продукта, например, отвечающему только за почтовые и push-уведомления, который оформляет её в виде задачи для своей команды со статусом «Идея».
Накопившиеся идеи периодически просматриваются и начинается детальная проработка самых важных из них. В этот момент задача переводится в статус «Подготовка PRD», после чего менеджер продукта готовит краткое описание предполагаемого добавления и направляет его дизайнеру и копирайтеру. Точнее, на них переводится задача в таск-трекере, а все заинтересованные подписываются на её обновления, чтобы быть в курсе её текущего статуса.
PRD (Product Requirements Document) — это нечто среднее между техническим заданием и достаточным описанием нового функционала. Обычно финальный вариант PRD даёт общее представление о том, как это будет выглядеть и как примерно должно работать. Все детали реализации уточняются в процессе разработки.
Как только дизайн и тексты готовы, менеджер собирает все элементы (макеты, файлы с текстами) в PRD и завершает подробное описание нового сервиса. В результате, когда менеджер считает, что его задача становится максимально понятной и автономной, ей присваивается статус «Готова к разработке» и она передаётся менеджеру проекта из Features Team. Часто задачу не принимают с первого раза из-за неполного описания, большой технической сложности или других нюансов, которые обнаруживаются при её проверке менеджером проекта.
Определение приоритета задачи и исполнителя
Приоритет отправленных в разработку задач определяет главный менеджер из Product Team. При этом предпочтение отдаётся тем из них, которые являются составной частью крупных проектов по изменению тех или иных частей сайта. Важность же инфраструктурных задач (баги, исследования и т.п.) определяют сами разработчики.
В свою очередь, разработчики на первое место ставят исправление критичных багов и минимизацию ошибок в логах — на каждую QA-отдел заводит новую задачу с высоким приоритетом. Более того, команда мониторинга круглосуточно следит за состоянием сайта и может связаться с разработчиком во внерабочее время, чтобы починить сломавшийся важный компонент.
Созданием нового функционала занимается специальная команда PHP-программистов, которая разделена на группы по 2-4 человека. Каждая группа отвечает за свой набор компонентов. Так как задача обязательно привязывается к конкретному компоненту, группа, которая будет её выполнять, определяется автоматически.
Все разработчики видят свои задачи на дашборде (англ. dashboard — страница с набором разных фильтров по задачам, настраивается специально под кажую группу) в таск-трекере, где они определённым образом сгруппированы и отсортированы. Есть пул задач на группу и есть список задач, к которым разработчик имеет непосредственное отношение (автор, исполнитель, ревьюер). Ситуация, когда человеку нечем заняться, невозможна в принципе. Ниже график поставленных и выполненных задач из таск-трекера за ноябрь, из которого видно, что работа реально кипит!
Ниже — график задач, попавших в production. По нему можно оценить ежедневный объём исправлений и улучшений в Badoo:
Техническая реализация
С момента разработки и до выкладки на боевые сервера задачу, независимо от её сложности, полностью ведёт один PHP-программист. При необходимости он ставит подзадачу на другие компоненты коллегам из своего отдела, а также сотрудничает с другими специалистами (верстальщиками или системными прораммистами). Если задача нетривиальная и требует особых архитектурных решений, собирается рабочая группа из нескольких наиболее опытных разработчиков, которые сообща определяют, что и как будет сделано.
Рассмотрим этот этап на примере создания фото-рейтинга (http://badoo.com/vote/), новая версия которого была недавно запущена. Из Product Team разработчикам поступил документ, содержащий следующие пункты:
- общее описание, задачи проекта (к примеру, побудить пользователей загружать новые фото);
- подробное описание нюансов ( как расчитывается рейтинг фотографий, как подбираются следующие фотографии и т.п.);
- макеты элементов интерфейса всех необходимых страниц и блоков с описанием того, что означает каждая кнопка, что должно происходить при нажатии по ссылкам, где и какие пункты меню должны быть добавлены;
- описание того, как выглядит неавторизованная версия сервиса.
На основании этого документа были поставлены задачи в разные отделы: верстка шаблонов, разработка сервисов на Си и инфраструктуры на сайте (элементы интерфейса, новые блоки, взаимодействие с сервисами и т.п.).
Проверка каждой выполненной задачи достаточно формализована: есть определённый чек-лист и автоматизированный процесс. Каждая задача разрабатывается в своей ветке системы контроля версий (мы используем Git, git-scm.com/). Ветки имеют особые правила именования (пример: BFG-123_another_cool_ticket), все коммиты автоматически получают номер задачи в начале описания (пример: [BFG-123]: great improvements on photo rating) — это помогает отслеживать движение кода от ветки разработчика до билда и итогового попадания в ветку master.
При каждой отправке изменений из локальной копии в общий репозиторий срабатывают хуки, которые проверяют форматирование и оформление кода. Для форматирования кода под наши внутренние стандарты была создана специальная утилита phpcf, которая умеет как проверять, так и корректно форматировать код (вручную под стандарт обычно форматируют только те участки кода, которые, по мнению разработчика, логичнее переписать, чем оставить в виде громоздкой, но правильно форматированной конструкции).
После того, как разработчик завершает разработку задачи, она попадает на код-ревью человеку, ответственному или имеющему хорошее представление о компоненте. Для осуществления ревью мы доработали утилиту gitphp (http://www.gitphp.org/) так, что в ней стало возможно просматривать общий diff ветки, оставлять комментарии к коду, которые впоследствии отправляются единым комментарием к задаче в JIRA. Обычно ревьюер проверяет, реализована ли задача в соответствии с правилами, принятыми в компании, нет ли явных оплошностей в виде оставленного дебага; может указать на целесообразность использования другого паттерна проектирования или предложить более оптимальную реализацию.
В задаче обязательно должны присутствовать юнит-тесты на внесенные изменения, при этом существующие тесты не должны быть сломаны (!). После завершения на соответствующей ветке при помощи TeamCity (http://www.jetbrains.com/teamcity/) прогоняются все тесты, и если какие-то из них не проходят, разработчик получит уведомление об этом. Для ряда задач заранее настраивается мониторинг важных показателей. После проверки ревьюером задача попадает в отдел контроля качества.
Тестирование и перевод
Выполненная задача попадает в пул команды контроля качества и закрепляется за любым свободным тестировщиком. Обычно тут нет ответственных за компоненты, все тестируют всё, но при особо важных или срочных задачах разработчики могут договорится с отделом тестирования и передать задачу более опытному тестировщику по определённому направлению.
Хорошей практикой считается составление разработчиком инструкции о том, как работает выполненная задача, что и как требуется протестировать. Best-practices по тестированию особо важных компонентов описываются в вики (всю подобную документацию мы ведем при помощи Confluence, www.atlassian.com/software/confluence/).
Во время тестирования все новые и изменённые слова и фразы из шаблонов попадают в специальную систему переводов (разработчик может заранее запустить этот процесс). Из неё при выкладке генерируются шаблоны для каждого из поддерживаемых языков.
Для тестирования задач наша инфраструктура поддерживает несколько возможных окружений:
- локальные домены на серверах разработки, которые эмулируют боевую инфраструктуру. Каждый разработчик ведёт работу на своём домене, а тестировщик проверяет задачи на своём;
- индивидуальное тестовое боевое окружение: одновременно можно проверять неограниченное количество задач, независимо друг от друга;
- общее тестовое боевое окружение, в которое попадает билд — набор задач, готовых к выкладке. В таком наборе задачи тестируются комплексно, чтобы одна не сломала другую.
Когда задача получает статус «Протестировано», она автоматически попадёт в следующий билд (если нет незавершённых дочерних задач и готовы все переводы). Конечно же, конфликты решаются вручную — об этом приходит оповещение. Неработающие задачи откатываются и билд уезжает без них.
Релиз
После всех проверок задача вместе с билдом раскладывается на боевых серверах. Это происходит 2 раза в день (утром и вечером). Нередко новый функционал требуется протестировать на небольшой группе реальных пользователей, оценить эффективность и нагрузку, прежде чем включать для всего сайта. Обычно включение делается для нескольких стран или только для офиса разработки. Большинство задач разрабатываются сразу с возможностью частичного включения и быстрого отката.
Но иногда после выкладки случается, что наше новшество не работает. Допустим, по-быстрому разложили непроверенный код или где-то была допущена логическая ошибка. Даже самые опытные разработчики порой допускают ошибки, которые приводят к неработоспособности некоторых частей системы, а порой она и вовсе складывается по принципу домино.
На каждый из подобных инцидентов составляется «постмортем» — документ, в котором подробно расписаны причины проблемы, на что она повлияла, как быстро была исправлена и, самое важное, что было сделано, чтобы в дальнейшем такой проблемы не возникло. После этого постмортем выносится на общее обсуждение и каждый может высказаться и изложить свое видение ситуации.
Для того, чтобы минимизировать подобные инциденты, мы стараемся максимально автоматизировать и улучшить наши процессы разработки, управление кодом, контроль над выкладками, а также средства мониторинга.
Итог
Результатом множества обсуждений, автоматизации, введения превентивных мер, постоянного аудита наших систем является то, что сейчас весь процесс разработки в Badoo понятен, эффективен и, что немаловажно, достаточно безопасен. Конечно, все возможные ошибки исключить невозможно, но я, как разработчик, чувствую себя комфортно и уверенно, когда вношу правки и разрабатываю новый код, зная, что он будет ещё неоднократно проверен. С одной стороны, это несколько расслабляет, но с другой — возможно, так и должен чувствовать себя программист, чтобы по-настоящему посвятить себя не просто разработке, а творческому процессу?
Александр treg Трегер, разработчик.
Андрей uni Сас, менеджер офлайн-уведомлений.
Автор: Treg