Примеры перехватчиков предварительного получения для 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
Эта строка представляет следующие аргументы.
Аргумент | Description |
---|---|
<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
Доступные всегда
Следующие переменные всегда доступны в среде перехватчика предварительного получения.
«Переменная» | Description | Пример значения |
---|---|---|
$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 | "Конечные точки REST API для ссылок на Git" |
git refs delete api | Удаление ссылки с помощью API | "Конечные точки REST API для ссылок на Git" |
git refs update api | Обновление ссылки с помощью API | "Конечные точки REST API для ссылок на Git" |
git repo contents api | Изменение содержимого файла с помощью API | "Конечные точки REST API для содержимого репозитория" |
merge | Слияние запроса на вытягивание с помощью автоматического слияния | "Автоматическое слияние запроса на вытягивание" |
merge base into head | Обновление ветви раздела из базовая ветвь, если для базовая ветвь требуется строгая проверки состояния (через ветвь обновления в запросе на вытягивание, например) | "Сведения о защищенных ветвях" |
pull request branch delete button | Удаление ветви раздела из запроса на вытягивание в веб-интерфейсе | "Удаление и восстановление ветвей в запросе на вытягивание" |
pull request branch undo button | Восстановление ветви раздела из запроса на вытягивание в веб-интерфейсе | "Удаление и восстановление ветвей в запросе на вытягивание" |
pull request merge api | Слияние запроса на вытягивание через API | "Конечные точки REST API для запросов на вытягивание" |
pull request merge button | Слияние запроса на вытягивание в веб-интерфейсе | "Слияние запроса на вытягивание" |
pull request revert button | Возврат запроса на вытягивание | "Отмена запроса на вытягивание" |
releases delete button | Удаление выпуска | "Управление выпусками в репозитории" |
stafftools branch restore | Восстановление ветви с панели мониторинга администрирования сайта | "Администратор создание экземпляра из пользовательского веб-интерфейса" |
tag create api | Создание тега с помощью API | "Конечные точки REST API для тегов Git" |
web branch create | Создание ветви через веб-интерфейс | "Создание и удаление ветвей в репозитории" |
Доступные для слияний запросов на вытягивание
Следующие переменные доступны в среде перехватчика предварительного получения, когда отправка, которая активирует перехватчик, является отправкой вследствие слияния запроса на вытягивание.
«Переменная» | Description | Пример значения |
---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | Имя пользователя учетной записи, создающей запрос на вытягивание | octocat |
$GITHUB_PULL_REQUEST_HEAD | Имя тематической ветки запроса на вытягивание в формате USERNAME:BRANCH | octocat:fix-bug |
$GITHUB_PULL_REQUEST_BASE | Имя базовой ветви запроса на вытягивание в формате USERNAME:BRANCH | octocat:main |
Доступные для отправок с использованием проверки подлинности SSH
«Переменная» | Description | Пример значения |
---|---|---|
$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 alpine:latest 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 . [+] Building 4.5s (8/8) FINISHED => [internal] load build definition from Dockerfile.dev 0.0s => => transferring dockerfile: 641B 0.0s => [internal] load .dockerignore 0.0s => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/alpine:latest 1.9s => [auth] library/alpine:pull token for registry-1.docker.io 0.0s => [1/3] FROM docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s => => resolve docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s => => sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 1.64kB / 1.64kB 0.0s => => sha256:25fad2a32ad1f6f510e528448ae1ec69a28ef81916a004d3629874104f8a7f70 528B / 528B 0.0s => => sha256:c1aabb73d2339c5ebaa3681de2e9d9c18d57485045a4e311d9f8004bec208d67 1.47kB / 1.47kB 0.0s => [2/3] RUN apk add --no-cache git openssh bash && ssh-keygen -A && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /e 2.3s => [3/3] WORKDIR /home/git 0.0s => exporting to image 0.1s => => exporting layers 0.1s => => writing image sha256:938447846e19a4328a85883fbd1ccf5eb919d97448cc7256efebf403d8b5a196 0.0s => => naming to docker.io/library/pre-receive.dev
-
Запустите контейнер данных, содержащий созданный ключ 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 master > Warning: Permanently added '[127.0.0.1]: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@127.0.0.1:test.git > ! [remote rejected] master -> master (pre-receive hook declined) > error: failed to push some refs to 'git@192.168.99.100:test.git'
Обратите внимание, что отправка была отклонена после выполнения перехватчика предварительного получения и повторения выходных данных скрипта.
Дополнительные материалы
- Настройка Git — пример политики, применяемой Git на веб-сайте Pro Git