Политика именования веток в git

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

Политика именования веток в git

Примеры настройки CI/CD будут приводиться на основе GitHub Actions, но я буду стараться предоставить код, который максимально переносим на другие платформы.

Git hooks

По умолчанию git никак не проверяет формат имени веток, за исключением базовой проверки на допустимость тех или иных символов/сочетаний (см. git-check-ref-format). Реализовать подобную проверку можно с помощью git hooks (= хук, перехватчик). Хук – обычный скрипт, который выполняется при наступлении того или иного события (например post- или pre- commit). Бывают серверные и клиентские хуки. Если серверные хуки реализовать на GiHub Actions не представляется возможным, то клиентские полностью в нашей власти.

Примечание: хук теоретически позволяет выполнять произвольный код и наличие подобной опции на публично доступном сервисе наподобие GitHub явно было бы угрозой безопасности. Однако ваш локальный GitLab подобных ограничений не имеет (см. GitLab Git server hooks).

Тем не менее реализовать логику серверных хуков вполне возможно. Рассмотрим это ниже, а пока создадим наш первый локальный хук.

Настройка локальных хуков

В каталоге .git/hooks хранятся примеры неактивных хуков с расширениями .sample. Чтобы они заработали, это расширение надо убрать или создать новый файл с аналогичным именем без расширения .sample. Имена должны строго соответствовать тем, что уже есть (никакие *.sh, *.py и др. не допускаются). Впрочем shell-скрипты будут работать и так, а изнутри вы можете вызвать уже что угодно. Итак, вот простейший bash-скрипт, который позволяет проверить название ветки:

Обратите внимание на переменную:

Примечание: её значение это ни что иное, как регулярное выражение. Важным моментом является тот факт, что команда – [[…]] – позволяет проверить соответствие строки регулярному выражению, но её устаревший вариант – […] – нет. Будьте внимательны. Вот вам мануал Tests and Conditionals.

Скриншот ниже наглядно демонстрирует какие имена веток попадают под регулярное выражение, а какие нет:

Вероятно ваши политики будут отличаться, а потому составьте и отладьте свою регулярку. Вам в помощь огромное количество онлайн-сервисов, например regex101.com.

Примечание: знание регулярных выражений это основа, которую знать нужно обязательно. Регулярные выражения бывают разные, но начать рекомендую с изучения стандарта POSIX, который содержит в том числе и описание регулярок. Ну а ключевой момент в понимании – квантификаторы, которые бывают ленивые и жадные. Статья Жадные и ленивые квантификаторы идеально раскрывает их суть.

Для проверки работы хука поместите скрипт в файл .git/hooks/pre-commit и выполните команды:

Ветку создать у вас получится, а вот закоммитить в неё даже пустоту (флаг –allow-empty) git вам уже не разрешит:

Выставим ветке корректное имя:

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

Доставка локальных хуков

Git это не инструмент контроля соответствия окружения тем или иным политикам, а потому ждать чуда от него не стоит – за локальные копии репозитория отвечает сам разработчик и никто иной. Тем не менее мы можем упросить для него жизнь, написав скрипт начальной подготовки окружения. Воспользуемся всем знакомой утилитой Make, которая часто уже установлена в системе по умолчанию.

Примечание: те, кто занимался сборкой приложений из исходных кодов, знают утилиту Make не понаслышке. Нам собирать исходники не придется, но вот удобная логика работы Make нам окажется очень даже к месту. Кто хочет знать больше, читайте обзорную статью Просто о make.

Итак, сохраним скрипт проверки имени ветки (см. выше) в отдельный файл:

Примечание: конструкция с EOF выше называется Bash Heredoc. Кавычки вокруг EOF вверху обязательны, иначе bash будет подставлять значения переменных и интерпретировать спецсимволы. Подробнее читайте в статье Bash Heredoc.

Далее в корне создаем Makefile со следующим содержимым:

Примечание: перед командой cp должен быть символ табуляции, иначе Make выдаст ошибку. IDE обычно проверяют Makefile на корректность, но может потребоваться установить расширения.

Достаточно выполнить команду ниже, чтобы скопировать все необходимые хуки из корня репозитория в каталог ./git/hooks/:

Хранить одни и те же хуки в каждом репозитории может показаться не совсем рациональным. Вы вполне можете создать отдельный репозиторий со служебной информацией (в том числе с хуками) и подтягивать данные при необходимости. Задача этой статьи – показать как можно сделать, а усложнить сценарии вы сможете и без меня.

Настройка окружения

Все описанное выше остается на усмотрение разработчика и даже выполнение всего лишь одной команды может быть легко забыто. Очень уместно в данном случае создать файл CONTRIBUTING.md в корне репозитория например с таким содержимым:

Ну а в README.md сделать на него отсылку:

Так выглядит уже гораздо лучше, а у вас появится больше порядка.

Проверка на стороне сервера

Проверять имена веток на стороне GitHub можно с помощью отдельного пайплайна CI/CD. Скрипт для проверки можно взять тот же, который использовали выше.

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

Обратите внимание на список переменных в скрипте – их стало на одну меньше. Мы можем не вычислять самостоятельно имя ветки, ведь GitHub Actions хранит это значение в переменной GITHUB_REF_NAME. Также не забудьте подправить имя ветки, на которой пайплайн запускаться не будет (действительно, зачем проверять main?).

Теперь остается сделать прохождение данного пайплайна обязательным. Для этого заходим в настройки репозитория – Settings / Branches / Branch protection rules. Добавляем правило, в шаблоне веток указываем main и ставим галочку на “Require status checks to pass before merging”. Вот так это выглядит:

Примечание: к этому моменту пайплайн уже должен быть хоть раз запущен, иначе вы его не увидите в списке “Status checks”. Он там не появится и в том случае, если последние запуски были более недели назад.

А вот так выглядит статус пул реквеста с не прошедшей проверкой (см. Validate branch name):

Теперь обойти проверки уже не получится, если вы конечно не администратор репозитория.

Заключение

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

Яндекс.Метрика