Примеры перехватчиков предварительного получения для GitHub Enterprise Server можно просмотреть в репозитории github/platform-samples
.
Написание скрипта перехватчика предварительного получения
Скрипт перехватчика предварительного получения выполняется в среде перехватчика предварительного получения на экземпляр GitHub Enterprise Server. При создании скрипта перехватчика предварительного получения учитывайте доступные входные и выходные данные, состояние выхода и переменные среды.
Входные данные (stdin
)
После отправки и перед обновлением ссылок для удаленного репозитория git-receive-pack
процесс экземпляр GitHub Enterprise Server вызывает скрипт перехватчика предварительного получения. Стандартные входные данные для скрипта stdin
— это строка, содержащая строку для каждой обновляемой ссылки. Каждая строка содержит старое имя объекта для ссылки, новое имя объекта для ссылки и полное имя ссылки.
<old-value> SP <new-value> SP <ref-name> LF
Эта строка представляет следующие аргументы.
Аргумент | Описание |
---|---|
<old-value> | Старое имя объекта, хранящееся в ссылке. При создании новой ссылки это значение представляет собой 40 нулей. |
<new-value> | Новое имя объекта для сохранения в ссылке. При удалении ссылки это значение представляет собой 40 нулей. |
<ref-name> | Полное имя ссылки. |
Дополнительные сведения о процессе git-receive-pack
см. в разделе git-receive-pack в документации Git. Дополнительные сведения о ссылках см. в разделе Ссылки Git в Pro Git.
Выходные данные (stdout
)
Стандартные выходные данные для скрипта stdout
передаются обратно в клиент. Все инструкции echo
будут видны пользователю в командной строке или пользовательском интерфейсе.
Состояние выхода
Состояние выхода скрипта предварительного получения определяет, будет ли принята отправка.
Значение состояния выхода | Действие |
---|---|
0 | Отправка будет принята. |
ненулевое значение | Отправка будет отклонена. |
Переменные среды
Помимо стандартных входных данных для скрипта перехватчика предварительного получения stdin
GitHub Enterprise Server делает следующие переменные доступными в среде Bash для выполнения вашего скрипта. Дополнительные сведения о stdin
для скрипта перехватчика предварительного получения см. в разделе Входные данные (stdin
).
Для скрипта перехватчика предварительного получения доступны разные переменные, в зависимости от того, что запускает скрипт.
- Доступные всегда
- Доступные для отправок из веб-интерфейса или API
- Доступные для слияний запросов на вытягивание
- Доступные для отправок с использованием проверки подлинности SSH
Доступна всегда
Следующие переменные всегда доступны в среде перехватчика предварительного получения.
Переменная | Описание | Пример значения |
---|---|---|
$GIT_DIR | Путь к удаленному репозиторию в экземпляре | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git |
$GIT_PUSH_OPTION_COUNT | Количество параметров отправки, отправленных клиентом с помощью --push-option . Дополнительные сведения см. в разделе git-push документации Git. | 1 |
$GIT_PUSH_OPTION_N | Если N является целым числом от 0 и выше, эта переменная содержит строку параметра отправки, отправленную клиентом. Первый отправленный параметр сохраняется в GIT_PUSH_OPTION_0 , второй отправленный параметр — в GIT_PUSH_OPTION_1 и т. д. Дополнительные сведения о параметрах отправки см. в разделе "git-push документации Git. | abcd |
$GIT_USER_AGENT | Строка агента пользователя, отправленная клиентом Git, которая отправляет изменения | git/2.0.0 |
$GITHUB_REPO_NAME | Имя обновляемого репозитория в формате NAME/OWNER | octo-org/hello-enterprise |
$GITHUB_REPO_PUBLIC | Логическое значение, указывающее, является ли обновляемый репозиторий общедоступным |
|
$GITHUB_USER_IP | IP-адрес клиента, который инициировал отправку | 192.0.2.1 |
$GITHUB_USER_LOGIN | Имя пользователя учетной записи, которая инициировала отправку | octocat |
Доступные для отправок из веб-интерфейса или API
Переменная $GITHUB_VIA
доступна в среде перехватчика предварительного получения, когда обновление ссылки, активирующее перехватчик, происходит через веб-интерфейс или API для GitHub Enterprise Server. Значение описывает действие, которое обновило ссылку.
Значение | Действие | Дополнительные сведения |
---|---|---|
auto-merge deployment api | Автоматическое слияние базовой ветви через развертывание, созданное с помощью API | Развернутые приложения в документации по REST API |
blob#save | Изменение содержимого файла в веб-интерфейсе | "Изменение файлов" |
branch merge api | Слияние ветви с помощью API | Ветви в документации по REST API |
branches page delete button | Удаление ветви в веб-интерфейсе | "Создание и удаление ветвей в репозитории" |
git refs create api | Создание ссылки с помощью API | База данных Git в документации по REST API |
git refs delete api | Удаление ссылки с помощью API | База данных Git в документации по REST API |
git refs update api | Обновление ссылки с помощью API | База данных Git в документации по REST API |
git repo contents api | Изменение содержимого файла с помощью API | Репозитории в документации по REST API |
Доступные для слияний запросов на вытягивание
Следующие переменные доступны в среде перехватчика предварительного получения, когда отправка, которая активирует перехватчик, является отправкой вследствие слияния запроса на вытягивание.
Переменная | Описание | Пример значения |
---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | Имя пользователя учетной записи, создающей запрос на вытягивание | octocat |
$GITHUB_PULL_REQUEST_HEAD | Имя тематической ветки запроса на вытягивание в формате USERNAME:BRANCH | |
$GITHUB_PULL_REQUEST_BASE | Имя базовой ветви запроса на вытягивание в формате USERNAME:BRANCH | octocat:main |
Доступные для отправок с использованием проверки подлинности SSH
Переменная | Описание | Пример значения |
---|---|---|
$GITHUB_PUBLIC_KEY_FINGERPRINT | Отпечаток открытого ключа для пользователя, который отправил изменения | a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6 |
Задание разрешений и отправка перехватчика предварительного получения в GitHub Enterprise Server
Скрипт перехватчика предварительного получения содержится в репозитории в экземпляр GitHub Enterprise Server. Администратор сайта должен учитывать разрешения репозитория и обеспечить, чтобы доступ имелся только у соответствующих пользователей.
Рекомендуется объединить перехватчики в один репозиторий. Если консолидированный репозиторий перехватчиков является общедоступным, можно использовать README.md
для объяснения применения политик. Кроме того, вклады можно принимать с помощью запросов на вытягивание. Однако перехватчики предварительного получения можно добавлять только из ветви по умолчанию. Для рабочего процесса тестирования следует использовать вилки репозитория с конфигурацией.
-
Для пользователей Mac убедитесь, что скрипты имеют разрешения на выполнение:
$ sudo chmod +x SCRIPT_FILE.sh
Для пользователей Windows убедитесь, что скрипты имеют разрешения на выполнение:
git update-index --chmod=+x SCRIPT_FILE.sh
-
Фиксация и отправка в назначенный репозиторий для перехватчиков предварительного получения в экземпляр GitHub Enterprise Server.
$ git commit -m "YOUR COMMIT MESSAGE" $ git push
-
Создайте перехватчик предварительного получения в экземпляре GitHub Enterprise Server.
Локальное тестирование скриптов предварительного получения
Вы можете протестировать скрипт перехватчика предварительного получения локально, прежде чем создавать или обновлять его в экземпляр GitHub Enterprise Server. Один из способов — создать локальную среду Docker для работы в качестве удаленного репозитория, который может выполнять перехватчик предварительного получения.
-
Убедитесь, что Docker установлен в локальной среде.
-
Создайте файл с именем
Dockerfile.dev
и следующим содержимым:FROM gliderlabs/alpine:3.3 RUN \ apk add --no-cache git openssh bash && \ ssh-keygen -A && \ sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \ adduser git -D -G root -h /home/git -s /bin/bash && \ passwd -d git && \ su git -c "mkdir /home/git/.ssh && \ ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P '' && \ mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && \ mkdir /home/git/test.git && \ git --bare init /home/git/test.git" VOLUME ["/home/git/.ssh", "/home/git/test.git/hooks"] WORKDIR /home/git CMD ["/usr/sbin/sshd", "-D"]
-
Создайте тестовый скрипт предварительного получения с именем
always_reject.sh
. В этом примере скрипт отклоняет все отправки, что полезно для блокировки репозитория:#!/usr/bin/env bash echo "error: rejecting all pushes" exit 1
-
Убедитесь, что скрипты
always_reject.sh
имеют разрешения на выполнение:$ chmod +x always_reject.sh
-
Из каталога, содержащего
Dockerfile.dev
, создайте образ:$ docker build -f Dockerfile.dev -t pre-receive.dev . > Sending build context to Docker daemon 3.584 kB > Step 1 : FROM gliderlabs/alpine:3.3 > ---> 8944964f99f4 > Step 2 : RUN apk add --no-cache git openssh bash && ssh-keygen -A && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && adduser git -D -G root -h /home/git -s /bin/bash && passwd -d git && su git -c "mkdir /home/git/.ssh && ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P ' && mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && mkdir /home/git/test.git && git --bare init /home/git/test.git" > ---> Running in e9d79ab3b92c > fetch http://alpine.gliderlabs.com/alpine/v3.3/main/x86_64/APKINDEX.tar.gz > fetch http://alpine.gliderlabs.com/alpine/v3.3/community/x86_64/APKINDEX.tar.gz ....truncated output.... > OK: 34 MiB in 26 packages > ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519 > Password for git changed by root > Generating public/private ed25519 key pair. > Your identification has been saved in /home/git/.ssh/id_ed25519. > Your public key has been saved in /home/git/.ssh/id_ed25519.pub. ....truncated output.... > Initialized empty Git repository in /home/git/test.git/ > Successfully built dd8610c24f82
-
Запустите контейнер данных, содержащий созданный ключ SSH:
$ docker run --name data pre-receive.dev /bin/true
-
Скопируйте тестовый перехватчик предварительного получения
always_reject.sh
в контейнер данных:$ docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
-
Запустите контейнер приложения, который запускает
sshd
и выполняет перехватчик. Запишите возвращенный идентификатор контейнера:$ docker run -d -p 52311:22 --volumes-from data pre-receive.dev > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
-
Скопируйте созданный ключ SSH из контейнера данных на локальный компьютер:
$ docker cp data:/home/git/.ssh/id_ed25519 .
-
Измените удаленный репозиторий тестов и отправьте его в репозиторий
test.git
в контейнере Docker. В этом примере используетсяgit@github.com:octocat/Hello-World.git
, но вы можете использовать любой подходящий репозиторий. В этом примере предполагается, что локальный компьютер (127.0.0.1) является портом привязки 52311, но вы можете использовать другой IP-адрес, если Docker работает на удаленном компьютере.$ git clone git@github.com:octocat/Hello-World.git $ cd Hello-World $ git remote add test git@127.0.0.1:test.git $ GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 52311 -i ../id_ed25519" git push -u test main > Warning: Permanently added '[192.168.99.100]:52311' (ECDSA) to the list of known hosts. > Counting objects: 7, done. > Delta compression using up to 4 threads. > Compressing objects: 100% (3/3), done. > Writing objects: 100% (7/7), 700 bytes | 0 bytes/s, done. > Total 7 (delta 0), reused 7 (delta 0) > remote: error: rejecting all pushes > To git@192.168.99.100:test.git > ! [remote rejected] main -> main (pre-receive hook declined) > error: failed to push some refs to 'git@192.168.99.100:test.git'
Обратите внимание, что отправка была отклонена после выполнения перехватчика предварительного получения и повторения выходных данных скрипта.
Дополнительные материалы
- Настройка Git — пример политики, применяемой Git на веб-сайте Pro Git