Авторизоваться
Аким Солянкин 6 дней назад Опубликована

В поисках лучшего обзора кода

Существует множество мнений о том, как лучше всего выполнять обзоры кода и pull-request в программном проекте. Некоторые команды и компании очень строги, требуя нескольких уровней рецензентов и только нескольких человек, уполномоченных выполнять слияние. Другие команды находятся в противоположной крайности, позволяя любому объединять свои филиалы в любое время без какого-либо контроля. В этой статье я предложу кое-что посередине.

Проблема

В одном из моих проектов было несколько разработчиков и только один авторизованный рецензент кода (ACR). ACR был единственным человеком с правами на запись в защищенную ветвь, в нашем случае develop. Таким образом, он был единственным человеком, который мог утверждать и объединять ветки функций develop. Интересно, что хотя ACR был членом команды, на него не возлагались какие-либо обязанности по разработке проекта. У него были обязанности по отношению к другим проектам, поэтому понятно, что его время было посвящено в первую очередь этим проектам. В процессе разработки функций были созданы и отправлены в источник функциональные ветви, за которыми следовали pull-request. В этот момент pull-request будут сохраняться, ожидая рассмотрения в течение нескольких дней, а иногда и недель.

В этом конкретном проекте не было достаточно разработчиков, чтобы привлечь других для помощи в разработке или проверке кода, и это быстро разочаровало.

Я решил исследовать более эффективный и действенный процесс.

Цели и ограничения

Моя цель - сократить время, необходимое для открытия, проверки и слияния pull-request с нашей основной веткой разработки.

Некоторые из моих ограничений заключаются в том, что код размещен во внутреннем экземпляре GitHub в частных репозиториях. Это ограничивает круг потенциальных рецензентов.

Рекомендация

Если вы просто хотите увидеть мою рекомендацию, вы можете прочитать этот раздел и остановиться. Остальная часть статьи будет моими поддерживающими аргументами и рассуждениями, которые привели меня к этой рекомендации.

Рабочий процесс разработки

Это примерный поток кода, который я представляю для любой данной функции:

  1. Разработчику (Pat) назначается новая функция.
  2. Pat создает новую ветку (FB) из HEAD «основной» ветки (или как там она называется в вашем репозитории). Примечание: Pat не выполняет разыетвление репозитория, но имеет доступ на запись к нему.
  3. Pat реализует эту функцию в FB, используя столько коммитов, сколько необходимо.
  4. По завершении Pat подталкивает FB к источнику и открывает pull-request
  5. Нажатие FB автоматически запускает сборку FB, а статус сборки возвращается в репозиторий.
  6. Если сборка не удалась, система не разрешит объединение FB.
  7. Репо содержит файл PULL_REQUEST_TEMPLATE.md, который способствует единообразию описаний pull-request.
  8. Pat просит, чтобы два или более партнера рассмотрели pull-request.
  9. «Владелец кода» для репозитория автоматически назначается для просмотра pull-request.
  10. Если какой-либо рецензент запрашивает изменения при проверке кода, Pat не может продолжить выполнение pull-request, пока эти изменения не будут исправлены.
  11. После внесения изменений Pat отправляет новые коммиты в FB, после чего все существующие проверки закрываются, и процесс начинается снова.
  12. Если основная ветвь обновляется, пока открыт запрос на перенос, Pat должен объединить эти изменения в FB, прежде чем его можно будет объединить.
  13. Этот цикл повторяется до тех пор, пока все рецензенты не одобрят его, FB не будет соответствовать основной ветке и все сборки FB не пройдут.
  14. На этом этапе Pat может объединить запрос на перенос и удалить FB.

Настройки защищенной ветки GitHub

Вот скриншот моих рекомендуемых настроек для защиты базовой ветки.

Обоснование

В этом разделе содержится более подробное объяснение вышеуказанного рабочего процесса.

Единая защищенная ветка

Я предлагаю защитить одну ветку, в нашем случае ветку develop, в которой объединяются все наши функциональные ветки. Это может быть известно как «основная» ветвь, «базовая» ветвь и т. д. Я использую все три термина как взаимозаменяемые.

Доступ для записи для всей команды

Чтобы эта рекомендация работала эффективно, каждый член команды должен иметь доступ для записи в репозиторий. Это позволяет создавать ветвь функций непосредственно в репозитории, а не заставлять разработчиков разветвлять репозиторий. Преимущество состоит в том, что рецензенты кода могут легко перенести ветку функции на свой компьютер для тестирования (при необходимости), вместо того, чтобы клонировать разветвленный репозиторий. Использование разветвленных репозиториев было обычным делом в прошлом, до появления защищенных веток. Это по-прежнему обычная практика в проектах с открытым исходным кодом, где функции могут быть добавлены практически кем угодно. В корпоративной среде последний вариант использования маловероятен.

Pull-request с шаблоном

Каждый репозиторий должен включать файл шаблона pull-request (названный PULL_REQUEST_TEMPLATE.md), чтобы обеспечить согласованность описаний pull-request между функциями и разработчиками. Как минимум, шаблон должен запрашивать у разработчика следующую информацию:

  • Ссылка на «историю пользователя» или проблему, на которую обращается pull-request.
  • Краткое изложение изменений.
  • Краткое руководство по созданию и тестированию ветки. Помните, что некоторые рецензенты могут быть из другой команды и могут быть плохо знакомы с проектом.
  • Что искать в приложении.

По желанию

Шаблон pull-request также может содержать подсказки для следующих элементов:

  • Результаты тестирования и линтинга (хотя это можно контролировать с помощью проверки статуса).
  • Снимки экрана текущего пользовательского интерфейса реализации, если необходимо.
  • Любой дополнительный контекст, который поможет просмотреть и протестировать pull-request.

Авторизованные рецензенты

Здесь все становится интересно. Предлагаю следовать модели внешней компании pullrequest.com. Они используют рецензентов кода, которые полностью удалены из проекта, и даже компании, запрашивающие рецензии. Эти рецензенты предлагают свежий взгляд, недоступный тем, кто занимается активной разработкой проекта. Таким лицам нужен только доступ для чтения к репозиторию.

Основное преимущество этого - числа. Больше потенциальных рецензентов означает более быстрое время до первого комментария, что приводит к более быстрой обработке pull-request.

Кроме того, каждый разработчик проекта должен быть авторизованным рецензентом.

Учитывая, что все наши рецензенты имеют доступ к корпоративной сети, мы можем сделать дополнительный шаг. Мы должны разрешить и поощрять наших обозревателей клонировать репозиторий, а затем создавать и запускать приложение из ветки функций.

Полезный побочный эффект включения рецензентов вне непосредственной команды - это помогает избежать разрозненных знаний. В любой момент в будущем рецензенты могут быть привлечены к участию в проекте, временно или постоянно, и не могут входить в проект вслепую.

Строгая проверка статуса

В нашем случае мы интегрированы с конвейером сборки Jenkins. Все отправленные ветки origin создаются, выполняется анализ кода и запускаются все модульные тесты. Статус этой фазы сборки и тестирования передается на GitHub и в pull-request, содержащий эту ветку. Прежде чем соавторы смогут объединить изменения в защищенную ветку, эта сборка должна быть полностью успешной.

Требовать актуальности FB для основной ветки

Функциональная ветвь в pull-request должна быть актуальной после того, как другие участники объединят pull-request в защищенную базовую ветку. Это возлагает бремя конфликтов слияния на разработчика функции, человека, наиболее близкого к коду, который, скорее всего, быстро разрешит их.

Требуемый обзор владельца кода

В каждом проекте должен быть один или несколько «владельцев кода», не входящих в команду разработчиков. Это могут быть технические менеджеры, руководители других проектов или старшие архитекторы. Владельцы кода указываются путем предоставления файла CODEOWNERS в корневой папке базовой ветки. Интересным в этом подходе является то, что разные владельцы кода могут быть назначены для разных типов файлов, веток и т. д. Детали того, кто будет назначен владельцем кода, может быть определена командой проекта.

В обязанности владельцев кода входит не подробное рассмотрение кода, а просто просмотр других проверок, чтобы убедиться, что они выполнены удовлетворительно. После того, как соответствующие владельцы кода рассмотрят и утвердят запрос на перенос, никаких дополнительных проверок не потребуется.

Требовать линейную историю (использовать сквош-слияния из ветвей функций в главную ветвь)

Эта рекомендация касается возврата функций в случае обнаружения проблем позже. Если защищенная ветвь требует линейной истории, то разрешены только слияния сквоша или перебазирования. Я рекомендую первое. Когда сквош-слияние выполняется как часть pull-request, вся функциональная ветвь объединяется в базовую ветвь с помощью одной фиксации. Хотя «лучшая практика» - делать несколько коммитов во время разработки, это может привести к более сложным конфликтам слияния для разработчиков в других ветвях. Использование сквош-слияния из ветки функции в базовую ветвь сократит функцию до одной фиксации, что облегчит другим разработчикам перенос этих изменений в свои собственные ветки функций. Это также помогает в том случае, если необходимо вернуть ветку функции. Предоставление одной обратной фиксации может отменить весь pull-request.

Слияние завершено автором кода

Когда все обзоры и проверки статуса завершены, автор исходной ветки функции должен выполнить слияние и удалить ветку функции, если это необходимо. Удаляете ли вы ветки функций или нет - это решение, которое лучше оставить команде разработчиков. Мне нравится удалять их и сохранять исходную точку в чистоте, но некоторые команды предпочитают их оставлять.

А как насчет автоматического слияния?

GitHub имеет возможность автоматически объединяться после прохождения всех остальных ворот. У меня есть соблазн порекомендовать это, но я буду настаивать на этом только в том случае, если окажется, что цикл сборки / тестирования / развертывания слишком длинный.

Заключение

Надеюсь, это было полезно. Вы можете согласиться или не согласиться с некоторыми из моих предложений, и это нормально. Я надеюсь, что вас впечатлила гибкость политик проверки кода и pull-request в GitHub. Ваша команда должна обсудить, что лучше всего подойдет для вашего проекта, исходя из опыта и потребностей ваших разработчиков.

По крайней мере, я надеюсь, что у вас будет достаточно информации для разговора.

Коментарии
Авторизоваться что-бы оставить комментарий
Присоединяйся в тусовку
Наш сайт использует файлы cookie для вашего максимального удобства. Пользуясь сайтом, вы даете свое согласие с условиями пользования cookie