Три скрипта Git hook для непрерывной интеграции

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

Sarah Goff-Dupont Sarah Goff-Dupont

Если вы не первый день используете Git, то наверняка слышали о скриптах Git hook. Возможно, вам даже приходилось с ними экспериментировать. Скрипты Git hook превосходно работают в контексте непрерывной интеграции, поэтому в этой статье я расскажу о трех примерах их использования и укажу на готовые скрипты, которые вы можете добавить в свой процесс. Если вы никогда раньше не использовали скрипты Git hook, не беспокойтесь: мы начнем с самого простого.

Общие сведения о скриптах Git hook

Скрипты hook — это встроенный механизм запуска пользовательских скриптов до или после таких операций, как коммит и слияние. Их можно рассматривать как систему плагинов Git. В каталоге .git любого репозитория Git можно увидеть каталог под названием hooks с набором образцов скриптов hook.

.git/hooks

Порядок установки скриптов Git hook прост и хорошо документирован, поэтому я не буду здесь в это вдаваться.

Существует два обширных класса скриптов hook: скрипты, работающие на стороне клиента, и скрипты, работающие на стороне сервера. Клиентские скрипты hook выполняются на локальной рабочей станции, а серверные скрипты hook — на сервере Git.

Скрипты hook могут выполняться до (pre-) или после (post-) какого-либо события. Скрипты pre-receive hook вызываются до запуска определенных операций в Git и могут отменить эту операцию в случае необходимости. Такие скрипты выступают в роли стражей, охраняющих репозиторий и не позволяющих вам или членам вашей команды выполнять коммиты кода, содержащего ошибки. Скрипты post-receive hook выполняются по завершении какой-либо операции. Отменить операцию они, соответственно, не могут. Скрипты post-receive hook позволяют автоматизировать отдельные шаги процесса разработки.

Скрипты #Git hook можно сравнить с крошечными роботами-миньонами, которые готовы исполнить любое ваше желание (злодейский хохот).

Скрипты Git hook могут автоматически выполнять, к примеру:

  • проверка того, что включили ли вы ключ связанной задачи Jira в свое сообщение коммита;
  • обеспечение выполнения предварительных условий для слияния;
  • отправку уведомлений в чат вашей команды;
  • настройку вашего рабочего пространства после переключения в другую ветку.

В функциональных ветках — только «чистые» сборки

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

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

Итак, вы можете добавить на стороне сервера скрипт hook, который будет обнаруживать входящие запросы на слияние с главной веткой. При обнаружении такого запроса скрипт проверяет последнюю сборку в вашей ветке, и, если там есть ошибки в тестах, слияние отклоняется. Мой коллега и консультант по разработке в Atlassian Тим Петтерсон написал такой скрипт hook, предназначенный для работы с Bamboo, и опубликовал его в Bitbucket. Вы можете взять его, изменить под себя и добавить в собственный репозиторий.

Как защитить достигнутое покрытие кода

Мне доводилось наблюдать, как многие команды отчаянно стараются поддерживать покрытие кода. Часто им приходится покрывать свою базу кода тестами «задним числом», и бывает весьма досадно видеть, как с трудом полученное покрытие исчезает, как только добавляются новые возможности, не подкрепленные тестами. По этой причине Тим также написал скрипт hook, действующий перед приемом изменений на стороне сервера, который призван защитить главную ветку от уменьшения покрытия кода.

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

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

И хочу сразу пояснить: все это предполагает, что у вас уже обеспечено покрытие кода. Сам скрипт hook не делает никакой магии: он просто ищет данные о покрытии в результатах вашей сборки. Этот скрипт по умолчанию работает с Bamboo и с Clover (инструмент покрытия кода от Atlassian, предназначенный для Java и Groovy). Однако можно настроить его интеграцию с любым сервером сборки или инструментом покрытия кода.

Проверка статуса сборок веток

Потому что друзья не позволяют друзьям использовать поломанные ветки.

Вот возможность поэкспериментировать со скриптами Git hook на стороне клиента: скрипт hook, запускаемый после извлечения изменений, который отображает статус сборки ветки прямо в окне терминала (тоже от Тима). Скрипт получает номер редакции из указателя head ветки в вашей локальной копии, а затем обращается к серверу непрерывной интеграции, чтобы узнать, была ли эта редакция собрана, и если да, была ли сборка успешной.

Предположим, вы хотите создать новое ответвление от главной ветки. Этот скрипт hook сообщит о том, успешно ли прошла общая сборка коммита в главной ветке, т. е. даст понять, безопасен ли данный коммит для создания функциональной ветки на его основе. Бывает, скрипт hook сообщает, что сборка для этой версии завершилась неудачно, хотя настенная панель команды показывает «зеленую» сборку для этой ветки (или наоборот). Это означает, что ваша локальная копия устарела. Можно принять любое решение: осуществить pull обновлений или продолжить работать с имеющейся у вас локальной копией.

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

Все описанные здесь скрипты Git hook для непрерывной интеграции работают с Bamboo, Clover и Bitbucket по умолчанию. Но не забывайте, что скрипты Git hook являются универсальными, их можно настроить для работы с любым используемым набором инструментов. Это автоматизация во имя успеха!