Существует множество мнений о том, как лучше всего выполнять обзоры кода и pull-request в программном проекте. Некоторые команды и компании очень строги, требуя нескольких уровней рецензентов и только нескольких человек, уполномоченных выполнять слияние. Другие команды находятся в противоположной крайности, позволяя любому объединять свои филиалы в любое время без какого-либо контроля. В этой статье я предложу кое-что посередине.
В одном из моих проектов было несколько разработчиков и только один авторизованный рецензент кода (ACR). ACR был единственным человеком с правами на запись в защищенную ветвь, в нашем случае develop
. Таким образом, он был единственным человеком, который мог утверждать и объединять ветки функций
. Интересно, что хотя ACR был членом команды, на него не возлагались какие-либо обязанности по разработке проекта. У него были обязанности по отношению к другим проектам, поэтому понятно, что его время было посвящено в первую очередь этим проектам. В процессе разработки функций были созданы и отправлены в источник функциональные ветви, за которыми следовали pull-request. В этот момент pull-request будут сохраняться, ожидая рассмотрения в течение нескольких дней, а иногда и недель.develop
В этом конкретном проекте не было достаточно разработчиков, чтобы привлечь других для помощи в разработке или проверке кода, и это быстро разочаровало.
Я решил исследовать более эффективный и действенный процесс.
Моя цель - сократить время, необходимое для открытия, проверки и слияния pull-request с нашей основной веткой разработки.
Некоторые из моих ограничений заключаются в том, что код размещен во внутреннем экземпляре GitHub в частных репозиториях. Это ограничивает круг потенциальных рецензентов.
Если вы просто хотите увидеть мою рекомендацию, вы можете прочитать этот раздел и остановиться. Остальная часть статьи будет моими поддерживающими аргументами и рассуждениями, которые привели меня к этой рекомендации.
Это примерный поток кода, который я представляю для любой данной функции:
PULL_REQUEST_TEMPLATE.md
, который способствует единообразию описаний pull-request.Вот скриншот моих рекомендуемых настроек для защиты базовой ветки.
В этом разделе содержится более подробное объяснение вышеуказанного рабочего процесса.
Я предлагаю защитить одну ветку, в нашем случае ветку develop
, в которой объединяются все наши функциональные ветки. Это может быть известно как «основная» ветвь, «базовая» ветвь и т. д. Я использую все три термина как взаимозаменяемые.
Чтобы эта рекомендация работала эффективно, каждый член команды должен иметь доступ для записи в репозиторий. Это позволяет создавать ветвь функций непосредственно в репозитории, а не заставлять разработчиков разветвлять репозиторий. Преимущество состоит в том, что рецензенты кода могут легко перенести ветку функции на свой компьютер для тестирования (при необходимости), вместо того, чтобы клонировать разветвленный репозиторий. Использование разветвленных репозиториев было обычным делом в прошлом, до появления защищенных веток. Это по-прежнему обычная практика в проектах с открытым исходным кодом, где функции могут быть добавлены практически кем угодно. В корпоративной среде последний вариант использования маловероятен.
Каждый репозиторий должен включать файл шаблона pull-request (названный
), чтобы обеспечить согласованность описаний pull-request между функциями и разработчиками. Как минимум, шаблон должен запрашивать у разработчика следующую информацию:PULL_REQUEST_TEMPLATE.md
Шаблон pull-request также может содержать подсказки для следующих элементов:
Здесь все становится интересно. Предлагаю следовать модели внешней компании pullrequest.com. Они используют рецензентов кода, которые полностью удалены из проекта, и даже компании, запрашивающие рецензии. Эти рецензенты предлагают свежий взгляд, недоступный тем, кто занимается активной разработкой проекта. Таким лицам нужен только доступ для чтения к репозиторию.
Основное преимущество этого - числа. Больше потенциальных рецензентов означает более быстрое время до первого комментария, что приводит к более быстрой обработке pull-request.
Кроме того, каждый разработчик проекта должен быть авторизованным рецензентом.
Учитывая, что все наши рецензенты имеют доступ к корпоративной сети, мы можем сделать дополнительный шаг. Мы должны разрешить и поощрять наших обозревателей клонировать репозиторий, а затем создавать и запускать приложение из ветки функций.
Полезный побочный эффект включения рецензентов вне непосредственной команды - это помогает избежать разрозненных знаний. В любой момент в будущем рецензенты могут быть привлечены к участию в проекте, временно или постоянно, и не могут входить в проект вслепую.
В нашем случае мы интегрированы с конвейером сборки Jenkins. Все отправленные ветки
создаются, выполняется анализ кода и запускаются все модульные тесты. Статус этой фазы сборки и тестирования передается на GitHub и в pull-request, содержащий эту ветку. Прежде чем соавторы смогут объединить изменения в защищенную ветку, эта сборка должна быть полностью успешной.origin
Функциональная ветвь в pull-request должна быть актуальной после того, как другие участники объединят pull-request в защищенную базовую ветку. Это возлагает бремя конфликтов слияния на разработчика функции, человека, наиболее близкого к коду, который, скорее всего, быстро разрешит их.
В каждом проекте должен быть один или несколько «владельцев кода», не входящих в команду разработчиков. Это могут быть технические менеджеры, руководители других проектов или старшие архитекторы. Владельцы кода указываются путем предоставления файла CODEOWNERS
в корневой папке базовой ветки. Интересным в этом подходе является то, что разные владельцы кода могут быть назначены для разных типов файлов, веток и т. д. Детали того, кто будет назначен владельцем кода, может быть определена командой проекта.
В обязанности владельцев кода входит не подробное рассмотрение кода, а просто просмотр других проверок, чтобы убедиться, что они выполнены удовлетворительно. После того, как соответствующие владельцы кода рассмотрят и утвердят запрос на перенос, никаких дополнительных проверок не потребуется.
Эта рекомендация касается возврата функций в случае обнаружения проблем позже. Если защищенная ветвь требует линейной истории, то разрешены только слияния сквоша или перебазирования. Я рекомендую первое. Когда сквош-слияние выполняется как часть pull-request, вся функциональная ветвь объединяется в базовую ветвь с помощью одной фиксации. Хотя «лучшая практика» - делать несколько коммитов во время разработки, это может привести к более сложным конфликтам слияния для разработчиков в других ветвях. Использование сквош-слияния из ветки функции в базовую ветвь сократит функцию до одной фиксации, что облегчит другим разработчикам перенос этих изменений в свои собственные ветки функций. Это также помогает в том случае, если необходимо вернуть ветку функции. Предоставление одной обратной фиксации может отменить весь pull-request.
Когда все обзоры и проверки статуса завершены, автор исходной ветки функции должен выполнить слияние и удалить ветку функции, если это необходимо. Удаляете ли вы ветки функций или нет - это решение, которое лучше оставить команде разработчиков. Мне нравится удалять их и сохранять исходную точку в чистоте, но некоторые команды предпочитают их оставлять.
GitHub имеет возможность автоматически объединяться после прохождения всех остальных ворот. У меня есть соблазн порекомендовать это, но я буду настаивать на этом только в том случае, если окажется, что цикл сборки / тестирования / развертывания слишком длинный.
Надеюсь, это было полезно. Вы можете согласиться или не согласиться с некоторыми из моих предложений, и это нормально. Я надеюсь, что вас впечатлила гибкость политик проверки кода и pull-request в GitHub. Ваша команда должна обсудить, что лучше всего подойдет для вашего проекта, исходя из опыта и потребностей ваших разработчиков.
По крайней мере, я надеюсь, что у вас будет достаточно информации для разговора.