Код-ревью без очередей |
16.09.2021 00:00 |
Автор: Станислав Давыдов, QA Automation в Wrike
Программисты пишут код (удивил, да?) Если это пет-проект, то вы вольны делать со своим кодом все, что хотите. Но когда над одним проектом работает несколько человек или даже целая команда, рано или поздно встаёт вопрос о необходимости код-ревью. Кому отдать на ревью? Как ускорить этот процесс? Как равномерно распределять реквесты по ревьюерам? Вопросов много, а ответы не так очевидны. В этой статье расскажу, с какой проблемой мы столкнулись в команде автотестирования в Wrike, как у нас устроен процесс ревью и зачем нам понадобился самописный сервис. С какой проблемой мы столкнулись в процессе разработки автотестовВ Wrike процесс доставки новой версии продукта от разработчиков до клиентов развит настолько хорошо, что деплои у нас происходят минимум раз в день, а иногда и чаще. В этом, помимо прочего, немалая заслуга автоматического тестирования. У нас есть тесты всех сортов и расцветок: unit-тесты, всевозможные REST-тесты, UI-тесты на базе Selenium, скриншотные, мобильные, нагрузочные и даже тесты на тестовые утилиты. В середине 2016-го года мы переписали фреймворк UI-тестов, реализовав паттерн PageObjects-Steps-Test. Писать тесты стало настолько просто, что количество их авторов перевалило за сотню (активных — больше пятидесяти). Писали все: от QA-инженеров до backend и frontend разработчиков. Но когда в проект коммитят Вы, наверное, догадываетесь, какая из всего этого вытекает проблема — ревью становится долгим. А ведь после изначального ревью могут потребоваться правки, порой и не один раз, потом снова ревью и т.д. Каждая итерация ревью-правок занимает много времени: никто не хочет бросать свои дела и переключаться, а GitLab шлет уведомления об изменениях в МР-ах на email (почту нынче мало кто постоянно проверяет), да еще и с запозданием. Все это привело к тому, что ревью у нас в среднем занимало больше 100 часов в 80 перцентиле (даже если исключить выходные дни). Новые тесты или фиксы старых зачастую связаны с изменениями в продукте, затянувшееся ревью тормозит релиз frontend или backend ветки, что, в свою очередь, ломает планы команд по релизам. Поэтому мы хотели снизить время ревью до 48 часов максимум (80 перцентиль). Варианты решения проблемыЧтобы снизить время ревью, мы начали с самого простого: решили явно раздавать мердж-реквесты ревьюерам. Два лида из команды по очереди каждый день просматривали список новых реквестов в GitLab и назначали на них инженеров из команды, пытаясь сохранять примерно одинаковую нагрузку на каждого реьвюера. Это помогло не сильно, потому что основная проблема с уведомлениями на каждом этапе ревью осталась нерешенной. К тому же это занимало время лидов, отрывая их от более важных задач. Тогда я решил разработать сервис, который сможет контролировать все изменения и присылать уведомления ответственным в личные сообщения в Slack. Изначально от сервиса требовалось только оперативно рассылать уведомления об изменениях в МР-е и его переходе между этапами ревью, правок после ревью и обратно. Чтобы понимать, что изменилось в MP-e, решил хранить прошлое состояние в базе данных. Это позволяло еще и получать статистику по времени жизни реквестов, по всем авторам и ревьюерам. Первая итерация: сервис «на коленке» и автоматическое назначение ревьюеровЛюбой утилите нужно имя, хотя бы чтобы не называть её «ну тот бот, который с ревью помогает». Тем более, когда это проект, который ты сам сделал с нуля. Хотелось, чтобы название перекликалось с системой Git, с которой и работает бот. Вариантов было несколько, но в конечном итоге остановился на названии JiGit — коротко и про Git. Дальше так и буду его называть. На первых порах JiGit создавался «на коленке»: по ночам в виде факультатива. Поэтому я выбрал знакомый и простой способ реализации — в виде теста. Unit-тесты в проекте уже были, как запускать в CI знаем. Почему бы и нет? Что делал «тест» с технической стороны? Сначала запрашивались все открытые мердж-реквесты из GitLab для нашего проекта. Далее для каждого реквеста текущее состоящие сравнивалось с тем, что сохранено в базе. Автор и/или ревьюер получал уведомление о конкретном изменении. В конце текущее состояние перезаписывало сохраненное в базе. Один запуск по всем МР-ам — а их было в среднем в районе 20 — занимал от 1 до 1,5 минут. «Тест» запускался каждые 5 минут — время задержки оповещений было от 0 до 5 минут. Первым шагом для дальнейшего развития сервиса стало автоматическое назначение ревьюеров. Для этого необходимо было учесть:
Нагрузку я брал из базы за последние 60 дней. Тогда даже если ревьюер уходит в отпуск на пару недель, то по возвращении на него не сваливаются сразу 10 МР-ов. Даты отпусков мы отмечаем в графике дежурств: каждый день нужен ответственный QAA-инженер для релиза новой версии продукта. Из этого графика JiGit узнаёт, на кого назначать МР-ы не стоит. А пункт со сложностью кода мы решили введением ряда лейблов в GitLab. Автор мердж-реквеста «клеит» на него лейбл с соответствующей сложностью, а JiGit знает, мердж-реквесты какой сложности может смотреть каждый ревьюер. Мы выделили пять уровней сложности и описали, в каком случае ставить каждый уровень. Если кто-то из авторов забудет поставить лейбл, то JiGit об этом любезно напомнит. Когда код МР-а вмёрдживался в мастер, JiGit высчитывал время, которое заняло ревью и сохранял его в базу. Так мы получили метрику контроля времени ревью. Вторая итерация: SpringBoot и веб-интерфейсШло время, JiGit нужно было подключать к другим QAA-проектам, которые тоже разрослись до неприличных размеров. Еще и разработчики из других команд узнали про инструмент и захотели себе такой же. Архитектура в виде JUnit-теста не была достаточно гибкой, а связность была настолько высокой, что любое изменение кода превращалось в лотерею — неизвестно, где может «стрельнуть». И тогда настало время для глобального рефакторинга. Я решил перенести JiGit на рельсы SpringBoot. Причин было несколько:
Раз уж взялись за рефакторинг, нужно было заодно решить накопившиеся проблемы: большая связность кода, невозможность гибкой настройки под разные проекты, повсеместный hardcode и другие. К примеру, в коде огромное количество условных операторов if. Если в проекте, который нужно подключить к JiGit, другой процесс ревью, придется добавить еще несколько операторов. Становится страшновато, особенно за моих последователей, которым придется во всём этом разбираться. Вот небольшой пример кода:
По мере разработки всё более остро чувствовалась необходимость в веб-интерфейсе для JiGit. И помогло, как всегда, удачное стечение обстоятельств. Команда вебсайта узнала о наших наработках и захотела подключить его в свой проект, где на тот момент были те же проблемы с ревью. Я подключил им JiGit, а заодно мы обсудили пожелания по UI с обеих сторон (ведь UI нужна и бэкендная часть), расписали ТЗ, и ребята разработали и запустили интерфейс для JiGit (за что им огромное спасибо!). С помощью интерфейса можно указывать список ревьюеров в каждом проекте, а также даты их отпуска или больничного. Там же можно смотреть метрики по ревью, строить графики, подключать новые проекты в JiGit и настраивать их. Какие проблемы помог решить сервисОт внедрения JiGit мы получили много пользы. Время код-ревью сократилось. Как и ожидалось, метрики по срокам ревью стали заметно снижаться. Теперь среднее время ревью стало колебаться в районе 24 часов, что видно на графике. И это при том, что количество МР-ов выросло со 150 до 350 в месяц! Метрики помогают контролировать процесс ревью. Имея данные по длительности ревью мердж-реквестов, мы можем своевременно исследовать причины увеличения метрик и реагировать на них. Процесс ревью стал более прозрачным. JiGit помогает понять дальнейшие шаги ревью на каждом этапе, двигаться по процессу и исправлять ошибки, которые могут потенциально затягивать сроки ревью. Например, пишет об упавших пайплайнах или напоминает о необходимости добавить или снять нужные лейблы. Мердж-реквесты распределяются автоматически. Теперь даже самый далекий от автоматизации человек в компании может написать свои тесты, создать мёрдж-реквест и не думать о том, кто должен проводить ревью его кода. JiGit самостоятельно назначает ревьюера. Процесс разработки тестов можно контролировать на всех этапах. С помощью сервиса появилась возможность контролировать разработку тестов на всех этапах от создания МР-а до мёрджа ветки в мастер. Раньше приходилось полагаться только на ответственность авторов кода и ревьюеров, а также на pre-commit хуки GitLab. Это оставляло возможность случайно или специально обойти принятый процесс ревью и смержить любой код в мастер. Теперь JiGit не позволит этого сделать. Чтобы код из ветки попал в мастер, необходимо, чтобы все пайплайны по ветке были зеленые, был создан мёрж-реквест, на него был назначен ревьюер из списка согласованных, именно он поставил «ревью ОК», после ревью не прилетали дополнительные коммиты и т.д. и т.п. Теперь мы уверены, что в мастер не просочится «кривой» код, только если ревьюер по ошибке не пропустит эти изменения. Но полностью человеческий фактор исключить невозможно. Хотя… Может подключить ML и обучить JiGit автоматическому ревью? Быстрый и понятный процесс помогает вовлекать коллег в написание тестов. Наряду с обширной документацией по использованию проекта, процесс ревью, который стал прозрачным и быстрым, уже не отталкивает желающих написать тесты. В нашей компании автотесты пишут не только в QAA-команде, но и QA-инженеры, фронтенд и бэкенд разработчики, за что им большое спасибо. Инженеры из других отделов начали использовать JiGit. Он быстро получил известность в инженерном департаменте компании. Многие команды стали обращаться с просьбой подключить JiGit к их проектам, где были схожие проблемы с длительностью ревью, прозрачностью процессов и сбором метрик. Подход к процессу ревью, налаженный в команде QAA, пришелся по вкусу, и некоторые команды даже поменяли свои процессы ревью, чтобы проще подключать JiGit к их проекту и получать от него большую функциональность. Планы по развитию сервисаУ сервиса JiGit большое будущее, как минимум в Wrike. Сейчас он уже подключен к шести проектам, а в планах подключить и ко всем остальным. Мы работаем над улучшениями функциональности как в общем, так и для отдельных проектов. Из основных задач на будущее:
В светлом будущем мы хотим выложить проект в opensource, ведь наверняка у многих из вас есть или будут похожие проблемы с ревью. Да и сила коллективного сознания может помочь с развитием. А как выглядит процесс ревью в вашей компании? Буду рад, если поделитесь опытом и идеями по поводу сервиса в комментариях. Спасибо за внимание! |