Как использовать Git Hooks для автоматизации задач разработки и развертывания

Вступление

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

Хотя набор инструментов + git + предлагает множество хорошо реализованных функций, одной из наиболее полезных характеристик является его гибкость. Благодаря использованию системы «ловушек» git позволяет разработчикам и администраторам расширять функциональность, определяя сценарии, которые git будет вызывать, основываясь на различных событиях и действиях.

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

Предпосылки

Перед началом работы на вашем сервере должен быть установлен + git +. Если вы подписаны на Ubuntu 14.04, вы можете проверить наше руководство на https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-14-04 как установить git. на Ubuntu 14.04] здесь.

Вы должны быть знакомы с тем, как использовать git в общем смысле. Если вам нужно введение, серия, частью которой является установка, называется Introduction to Git: Installation , Использование и Филиалы, это хорошее место для начала.

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

Основная идея с Git Hooks

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

Git-хуки основаны на событиях. Когда вы запускаете определенные команды git, программа проверит каталог + hooks + в репозитории git, чтобы увидеть, есть ли связанный скрипт для запуска.

Некоторые сценарии выполняются до выполнения действия, которое можно использовать для обеспечения соответствия кода стандартам, для проверки работоспособности или для настройки среды. Другие сценарии запускаются после события для развертывания кода, восстановления правильных разрешений (что-то, что git не может очень хорошо отслеживать), и так далее.

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

В книге Скотта Чакона Pro Git делается попытка разделить различные типы крючков на категории. Он классифицирует их как таковые:

  • Клиентские хуки: хуки, которые вызываются и исполняются на компьютере коммиттера. Они в свою очередь делятся на несколько отдельных категорий:

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

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

  • Другое: Другие клиентские хуки включают хуки, которые выполняются при объединении, проверке кода, перебазировании, переписывании и очистке репозиториев.

  • Перехватчики на стороне сервера: Эти перехватчики выполняются на серверах, которые используются для получения запросов. Как правило, это было бы основным git-репо для проекта. И снова Чакон разделил их на категории:

  • Предварительный прием и последующий прием: они выполняются на сервере, получающем push-уведомление, для выполнения таких операций, как проверка соответствия проекта и развертывание после push-уведомления.

  • Обновление: это похоже на предварительное получение, но работает по принципу ветвления для выполнения кода перед принятием каждой ветки.

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

Некоторые хуки также принимают параметры. Это означает, что когда git вызывает скрипт для ловушки, он передает некоторые релевантные данные, которые скрипт затем может использовать для выполнения задач. В целом, доступны следующие крючки:

Hook Name Invoked By Description Parameters (Number and Description)

applypatch-msg

git am

Can edit the commit message file and is often used to verify or actively format a patch’s message to a project’s standards. A non-zero exit status aborts the commit.

(1) name of the file containing the proposed commit message

pre-applypatch

git am

This is actually called after the patch is applied, but before the changes are committed. Exiting with a non-zero status will leave the changes in an uncommitted state. Can be used to check the state of the tree before actually committing the changes.

(none)

post-applypatch

git am

This hook is run after the patch is applied and committed. Because of this, it cannot abort the process, and is mainly used for creating notifications.

(none)

pre-commit

git commit

This hook is called before obtaining the proposed commit message. Exiting with anything other than zero will abort the commit. It is used to check the commit itself (rather than the message).

(none)

prepare-commit-msg

git commit

Called after receiving the default commit message, just prior to firing up the commit message editor. A non-zero exit aborts the commit. This is used to edit the message in a way that cannot be suppressed.

(1 to 3) Name of the file with the commit message, the source of the commit message (message, template, merge, squash, or commit), and the commit SHA-1 (when operating on an existing commit).

commit-msg

git commit

Can be used to adjust the message after it has been edited in order to ensure conformity to a standard or to reject based on any criteria. It can abort the commit if it exits with a non-zero value.

(1) The file that holds the proposed message.

post-commit

git commit

Called after the actual commit is made. Because of this, it cannot disrupt the commit. It is mainly used to allow notifications.

(none)

pre-rebase

git rebase

Called when rebasing a branch. Mainly used to halt the rebase if it is not desirable.

(1 or 2) The upstream from where it was forked, the branch being rebased (not set when rebasing current)

post-checkout

git checkout and git clone

Run when a checkout is called after updating the worktree or after git clone. It is mainly used to verify conditions, display differences, and configure the environment if necessary.

(3) Ref of the previous HEAD, ref of the new HEAD, flag indicating whether it was a branch checkout (1) or a file checkout (0)

post-merge

git merge or git pull

Called after a merge. Because of this, it cannot abort a merge. Can be used to save or apply permissions or other kinds of data that git does not handle.

(1) Flag indicating whether the merge was a squash.

pre-push

git push

Called prior to a push to a remote. In addition to the parameters, additional information, separated by a space is passed in through stdin in the form of “<local ref> <local sha1> <remote ref> <remote sha1>”. Parsing the input can get you additional information that you can use to check. For instance, if the local sha1 is 40 zeros long, the push is a delete and if the remote sha1 is 40 zeros, it is a new branch. This can be used to do many comparisons of the pushed ref to what is currently there. A non-zero exit status aborts the push.

(2) Name of the destination remote, location of the destination remote

pre-receive

git-receive-pack on the remote repo

This is called on the remote repo just before updating the pushed refs. A non-zero status will abort the process. Although it receives no parameters, it is passed a string through stdin in the form of “<old-value> <new-value> <ref-name>” for each ref.

(none)

update

git-receive-pack on the remote repo

This is run on the remote repo once for each ref being pushed instead of once for each push. A non-zero status will abort the process. This can be used to make sure all commits are only fast-forward, for instance.

(3) The name of the ref being updated, the old object name, the new object name

post-receive

git-receive-pack on the remote repo

This is run on the remote when pushing after the all refs have been updated. It does not take parameters, but receives info through stdin in the form of “<old-value> <new-value> <ref-name>”. Because it is called after the updates, it cannot abort the process.

(none)

post-update

git-receive-pack on the remote repo

This is run only once after all of the refs have been pushed. It is similar to the post-receive hook in that regard, but does not receive the old or new values. It is used mostly to implement notifications for the pushed refs.

(?) A parameter for each of the pushed refs containing its name

pre-auto-gc

git gc --auto

Is used to do some checks before automatically cleaning repos.

(none)

post-rewrite

git commit --amend, git-rebase

This is called when git commands are rewriting already committed data. In addition to the parameters, it receives strings in stdin in the form of “<old-sha1> <new-sha1>”.

(1) Name of the command that invoked it (amend or rebase)

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

Настройка репозитория

Для начала мы создадим новый пустой репозиторий в нашем домашнем каталоге. Мы назовем это + proj +.

mkdir ~/proj
cd ~/proj
git init
Initialized empty Git repository in /home/demo/proj/.git/

Теперь мы находимся в пустом рабочем каталоге каталога, управляемого git. Прежде чем что-то делать, давайте перейдем к хранилищу, которое хранится в скрытом файле с именем + .git + в этом каталоге:

cd .git
ls -F
branches/  config  description  HEAD  hooks/  info/  objects/  refs/

Мы можем увидеть ряд файлов и каталогов. Нам интересен каталог + hooks +:

cd hooks
ls -l
total 40
-rwxrwxr-x 1 demo demo  452 Aug  8 16:50 applypatch-msg.sample
-rwxrwxr-x 1 demo demo  896 Aug  8 16:50 commit-msg.sample
-rwxrwxr-x 1 demo demo  189 Aug  8 16:50 post-update.sample
-rwxrwxr-x 1 demo demo  398 Aug  8 16:50 pre-applypatch.sample
-rwxrwxr-x 1 demo demo 1642 Aug  8 16:50 pre-commit.sample
-rwxrwxr-x 1 demo demo 1239 Aug  8 16:50 prepare-commit-msg.sample
-rwxrwxr-x 1 demo demo 1352 Aug  8 16:50 pre-push.sample
-rwxrwxr-x 1 demo demo 4898 Aug  8 16:50 pre-rebase.sample
-rwxrwxr-x 1 demo demo 3611 Aug  8 16:50 update.sample

Мы можем увидеть несколько вещей здесь. Во-первых, мы видим, что каждый из этих файлов помечен как исполняемый. Поскольку эти сценарии просто называются по имени, они должны быть исполняемыми, и их первая строка должна быть ссылкой shebang magic number, чтобы вызвать правильный интерпретатор сценария. , Чаще всего это скриптовые языки, такие как bash, perl, python и т. Д.

Второе, что вы можете заметить, это то, что все файлы заканчиваются на + .sample a. Это потому, что git просто смотрит на имя файла, когда пытается найти подключаемые файлы для выполнения. Отклонение от имени скрипта, которое ищет git, в основном отключает скрипт. Чтобы включить любой из сценариев в этом каталоге, нам нужно удалить суффикс + .sample +.

Давайте вернемся в наш рабочий каталог:

cd ../..

Первый пример. Развертывание на локальном веб-сервере с хуком после фиксации

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

Сначала мы установим веб-сервер Apache, чтобы продемонстрировать:

sudo apt-get update
sudo apt-get install apache2

Для того, чтобы наш скрипт изменил корень сети в + / var / www / html (это корень документа в Ubuntu 14.04. Изменить по мере необходимости), нам нужно иметь разрешение на запись. Давайте дадим нашему обычному пользователю право собственности на этот каталог. Вы можете сделать это, набрав:

sudo chown -R `whoami`:`id -gn` /var/www/html

Теперь в каталоге нашего проекта давайте создадим файл + index.html +:

cd ~/proj
nano index.html

Внутри мы можем добавить немного HTML, чтобы продемонстрировать идею. Это не должно быть сложным:

<h1>Here is a title!</h1>

<p>Please deploy me!</p>

Добавьте новый файл, чтобы git отслеживал файл:

git add .

Теперь, перед тем как вы сделаете коммит, мы собираемся установить наш хук + post-commit + для репозитория. Создайте этот файл в каталоге + .git / hooks + для проекта:

vim .git/hooks/post-commit

Прежде чем мы перейдем к тому, что поместить в этот файл, нам нужно немного узнать о том, как git настраивает среду при запуске ловушек.

Отдельно об экологических переменных с помощью Git Hooks

Прежде чем мы сможем начать наш скрипт, нам нужно немного узнать о том, какие переменные среды устанавливает git при вызове хуков Чтобы заставить наш скрипт функционировать, нам в конечном итоге потребуется сбросить переменную окружения, которую устанавливает git при вызове хука + post-commit.

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

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

К счастью, Марк Лонгэйр разработал a метод для тестирования каждой из переменных, которые git устанавливает при запуске этих хуков. Он включает в себя размещение следующего содержимого в различных скриптах git hook:

#!/bin/bash
echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

Информация на его сайте с 2011 года работает с git версии 1.7.1, поэтому произошли некоторые изменения. На момент написания этой статьи в августе 2014 года текущая версия git в Ubuntu 14.04 была 1.9.1.

Результаты тестов для этой версии git приведены ниже (включая рабочий каталог, который видит git при запуске каждой ловушки). Локальный рабочий каталог для теста был + / home / demo / test_hooks +, а пустой пульт (где это необходимо) был + / home / demo / origin / test_hooks.git +:

  • * Hooks *: + applypatch-msg +, + pre-applypatch +, + post-applypatch +

  • * Экологические переменные *:

  • + GIT_AUTHOR_DATE = 'Пн, 11 августа 2014 11:25:16 -0400' +

  • + GIT_AUTHOR_EMAIL = демо @ example.com +

  • + GIT_AUTHOR_NAME = 'Демонстрационный пользователь' +

  • + GIT_INTERNAL_GETTEXT_SH_SCHEME = ГНУ +

  • + GIT_REFLOG_ACTION = ат +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Хуки *: + pre-commit,` + prepare-commit-msg`, + commit-msg +, + post-commit

  • * Экологические переменные *:

  • + GIT_AUTHOR_DATE = '@ 1407774159 -0400' +

  • + GIT_AUTHOR_EMAIL = демо @ example.com +

  • + GIT_AUTHOR_NAME = 'Демонстрационный пользователь' +

  • + GIT_DIR = .git +

  • + GIT_EDITOR = +

  • + GIT INDEX FILE = .git / index

  • + GIT_PREFIX = +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Крючки *: + pre-rebase +

  • * Экологические переменные *:

  • + GIT_INTERNAL_GETTEXT_SH_SCHEME = ГНУ +

  • + GIT_REFLOG_ACTION = Rebase +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Крючки *: + после оформления заказа +

  • * Экологические переменные *:

  • + GIT_DIR = .git +

  • + GIT_PREFIX = +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Крючки *: + post-merge

  • * Экологические переменные *:

  • + GITHEAD_4b407c …​ +

  • + GIT_DIR = .git +

  • + GIT_INTERNAL_GETTEXT_SH_SCHEME = ГНУ +

  • + GIT_PREFIX = +

  • + GIT_REFLOG_ACTION = 'вытащить другого мастера' +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Крючки *: + pre-push +

  • * Экологические переменные *:

  • + GIT_PREFIX = +

  • * Рабочий каталог *: + / home / demo / test_hooks +

  • * Крючки *: + pre-receive,` + update`, + post-receive,` + post-update`

  • * Экологические переменные *:

  • + GIT_DIR = +.

  • * Рабочий каталог *: + / home / demo / origin / test_hooks.git +

  • * Крючки *: + pre-auto-gc +

  • (неизвестно, потому что это трудно вызвать надежно)

  • * Крючки *: + post-rewrite +

  • * Экологические переменные *:

  • + GIT_AUTHOR_DATE = '@ 1407773551 -0400' +

  • + GIT_AUTHOR_EMAIL = демо @ example.com +

  • + GIT_AUTHOR_NAME = 'Демонстрационный пользователь' +

  • + GIT_DIR = .git +

  • + GIT_PREFIX = +

  • * Рабочий каталог *: + / home / demo / test_hooks +

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

Вернуться к сценарию

Теперь, когда у вас есть представление о типе среды, которая будет иметь место (посмотрите на переменные, установленные для хука + post-commit +), мы можем начать наш скрипт.

Поскольку git hooks являются стандартными скриптами, нам нужно указать git, какой интерпретатор использовать:

#!/bin/bash

После этого мы просто будем использовать сам git для распаковки последней версии репозитория после коммита в наш веб-каталог. Для этого мы должны установить наш рабочий каталог в корневой каталог документов Apache. Мы также должны установить наш каталог git для репозитория.

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

#!/bin/bash
git --work-tree=/var/www/html --git-dir=/home//proj/.git checkout -f

На этом мы почти закончили. Тем не менее, нам нужно внимательно посмотреть на переменные среды, которые устанавливаются каждый раз, когда вызывается хук + post-commit +. В частности, + GIT INDEX FILE установлен в` + .git / index`.

Этот путь относится к рабочему каталогу, который в данном случае является + / var / www / html +. Поскольку индекс git не существует в этом месте, сценарий завершится ошибкой, если мы оставим его как есть. Чтобы избежать этой ситуации, мы можем вручную unset переменную, которая заставит git искать по отношению к каталогу репо, как это обычно делается. Нам нужно добавить это * над * строкой оформления заказа:

#!/bin/bash

git --work-tree=/var/www/html --git-dir=/home//proj/.git checkout -f

Эти типы конфликтов - то, почему проблемы с git-хуком иногда трудно диагностировать. Вы должны знать, как git создал среду, в которой он работает.

Когда вы закончите с этими изменениями, сохраните и закройте файл.

Поскольку это обычный файл скрипта, нам нужно сделать его исполняемым:

chmod +x .git/hooks/post-commit

Теперь мы наконец готовы зафиксировать изменения, которые мы сделали в нашем git-репо. Убедитесь, что вы вернулись в правильный каталог, а затем передайте изменения:

cd ~/proj
git commit -m "here we go..."

Теперь, если вы посещаете доменное имя или IP-адрес вашего сервера в браузере, вы должны увидеть созданный вами файл + index.html +:

http://

изображение: https: //assets.digitalocean.com/articles/git_hooks/first_deploy.png [Test index.html]

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

echo "<p>Here is a change.</p>" >> index.html
git add .
git commit -m "First change"

Когда вы обновите свой браузер, вы должны сразу увидеть новые изменения, которые вы применили:

изображение: https: //assets.digitalocean.com/articles/git_hooks/deploy_changes.png [развернуть изменения]

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

Использование Git Hooks для развертывания на отдельном производственном сервере

В следующем примере мы продемонстрируем лучший способ обновления рабочего сервера. Мы можем сделать это, используя модель push-to-deploy, чтобы обновлять наш веб-сервер всякий раз, когда мы перемещаемся в пустой git-репозиторий.

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

На нашей производственной машине мы будем настраивать другой веб-сервер, пустой git-репозиторий, на который будем отправлять изменения, и git-хук, который будет выполняться всякий раз, когда получено push-уведомление. Выполните следующие шаги как обычный пользователь с привилегиями sudo.

Настройте рабочий сервер после получения хука

На рабочем сервере начните с установки веб-сервера:

sudo apt-get update
sudo apt-get install apache2

Опять же, мы должны передать право владения корнем документа пользователю, с которым мы работаем:

sudo chown -R `whoami`:`id -gn` /var/www/html

Нам также нужно помнить, чтобы установить git на эту машину:

sudo apt-get install git

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

mkdir ~/proj
cd ~/proj
git init --bare

Поскольку это пустой репозиторий, рабочего каталога нет, и все файлы, которые находятся в + .git + в обычной установке, находятся в самом главном каталоге.

Нам нужно создать еще один git hook. На этот раз нас интересует хук + post-receive +, который запускается на сервере, получающем + git push +. Откройте этот файл в вашем редакторе:

nano hooks/post-receive

Опять же, нам нужно начать с определения типа сценария, который мы пишем. После этого мы можем набрать ту же команду checkout, которую мы использовали в нашем файле + post-commit +, модифицированной для использования путей на этом компьютере:

#!/bin/bash
git --work-tree=/var/www/html --git-dir=/home//proj checkout -f

Поскольку это пустой репозиторий, + - git-dir + должен указывать на каталог верхнего уровня этого репозитория. Остальное довольно похоже.

Однако нам нужно добавить дополнительную логику в этот скрипт. Если мы случайно добавим ветку + test-feature + на этот сервер, мы не хотим, чтобы это было развернуто. Мы хотим убедиться, что мы будем только развертывать ветку + master +.

Для хука + post-receive + вы, возможно, заметили в таблице ранее, что git передает хеш коммитов старой ревизии, хеш коммита новой ревизии и ссылку, которая выдвигается как стандартный ввод в скрипт. Мы можем использовать это, чтобы проверить, является ли ссылка главной веткой или нет.

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

#!/bin/bash
while read oldrev newrev ref
do
   git --work-tree=/var/www/html --git-dir=/home//proj checkout -f
done

Итак, теперь у нас будет три переменные, основанные на том, что выдвигается. Для push главной ветки объект + ref + будет содержать нечто, похожее на + refs /heads / master +. Мы можем проверить, имеет ли ref, который получает сервер, этот формат, используя конструкцию + if +:

#!/bin/bash
while read oldrev newrev ref
do
   if [[ $ref =~ .*/master$ ]];
   then
       git --work-tree=/var/www/html --git-dir=/home//proj checkout -f
   fi
done

Для серверных перехватов git может фактически передавать сообщения обратно клиенту. Все, что отправлено на стандартный выход, будет перенаправлено клиенту. Это дает нам возможность явно уведомить пользователя о том, какое решение было принято.

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

#!/bin/bash
while read oldrev newrev ref
do
   if [[ $ref =~ .*/master$ ]];
   then
       echo "Master ref received.  Deploying master branch to production..."
       git --work-tree=/var/www/html --git-dir=/home//proj checkout -f
   else
       echo "Ref $ref successfully received.  Doing nothing: only the master branch may be deployed on this server."
   fi
done

Когда вы закончите, сохраните и закройте файл.

Помните, мы должны сделать исполняемый скрипт, чтобы хук работал:

chmod +x hooks/post-receive

Теперь мы можем настроить доступ к этому удаленному серверу на нашем клиенте.

Настройте удаленный сервер на вашем клиентском компьютере

Вернувшись на свою клиентскую (разрабатывающую) машину, вернитесь в рабочий каталог вашего проекта:

cd ~/proj

Внутри добавьте удаленный сервер как удаленный с именем + production. Вам нужно будет знать имя пользователя, которое вы использовали на своем производственном сервере, а также его IP-адрес или имя домена. Вам также нужно будет узнать расположение чистого репозитория, который вы настроили по отношению к домашнему каталогу пользователя.

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

git remote add production @:proj

Давайте перенесем нашу текущую главную ветку на наш производственный сервер:

git push production master

Если у вас не настроены ключи SSH, возможно, вам придется ввести пароль пользователя вашего производственного сервера. Вы должны увидеть что-то похожее на это:

Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 473 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)

To [email protected]:proj
  009183f..f1b9027  master -> master

Как видите, текст из вашей ловушки + post-receive находится в выходных данных команды. Если мы посетим доменное имя или IP-адрес нашего производственного сервера в нашем веб-браузере, мы должны увидеть текущую версию нашего проекта:

изображение: https: //assets.digitalocean.com/articles/git_hooks/push_prod.png [запрошенная продукция]

Похоже, что ловушка успешно подтолкнула наш код к производству, как только она получила информацию.

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

Создайте новую ветку с именем + test_feature + и проверьте новую ветку, набрав:

git checkout -b test_feature

Сейчас мы работаем в ветке + test_feature +. Давайте внесем изменения, которые мы, возможно, хотим перенести в производство. Мы передадим это в эту ветку:

echo "<h2>New Feature Here</h2>" >> index.html
git add .
git commit -m "Trying out new feature"

На этом этапе, если вы переходите на IP-адрес или имя домена компьютера, на котором вы разрабатываете, вы должны увидеть свои изменения:

изображение: https: //assets.digitalocean.com/articles/git_hooks/devel_commit.png [зафиксировать изменения]

Это потому, что наша машина разработки все еще переустанавливается при каждом коммите. Этот рабочий процесс отлично подходит для тестирования изменений перед их переносом в производство.

Мы можем отправить нашу ветку + test_feature + на наш удаленный производственный сервер:

git push production test_feature

Вы должны увидеть другое сообщение из нашей ловушки + post-receive + в выводе:

Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 301 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)

To [email protected]:proj
  83e9dc4..5617b50  test_feature -> test_feature

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

Теперь, когда мы проверили наши изменения на нашей машине разработки, мы уверены, что хотим включить эту функцию в нашу основную ветку. Мы можем проверить нашу ветку + master + и объединить ее с нашей веткой + test_feature + на нашей машине для разработки:

git checkout master
git merge test_feature

Теперь вы слили новую функцию в основную ветку. Нажатие на рабочий сервер приведет к развертыванию наших изменений:

git push production master

Если мы проверим доменное имя или IP-адрес нашего производственного сервера, мы увидим наши изменения:

изображение: https: //assets.digitalocean.com/articles/git_hooks/new_prod.png [отправлено в производство]

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

Заключение

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

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

Related