Skip to main content

Создание скрипта перехватчика предварительного получения

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

Примеры перехватчиков предварительного получения для 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).

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

Доступные всегда

Следующие переменные всегда доступны в среде перехватчика предварительного получения.

«Переменная»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/OWNERocto-org/hello-enterprise
$GITHUB_REPO_PUBLIC
Логическое значение, указывающее, является ли обновляемый репозиторий общедоступным
  • true: репозиторий видим всем
  • false: репозиторий является частным или внутренним
$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:BRANCHoctocat:fix-bug
$GITHUB_PULL_REQUEST_BASE
Имя базовой ветви запроса на вытягивание в формате USERNAME:BRANCHoctocat: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 для объяснения применения политик. Кроме того, вклады можно принимать с помощью запросов на вытягивание. Однако перехватчики предварительного получения можно добавлять только из ветви по умолчанию. Для рабочего процесса тестирования следует использовать вилки репозитория с конфигурацией.

  1. Для пользователей Mac убедитесь, что скрипты имеют разрешения на выполнение:

    sudo chmod +x SCRIPT_FILE.sh
    

    Для пользователей Windows убедитесь, что скрипты имеют разрешения на выполнение:

    git update-index --chmod=+x SCRIPT_FILE.sh
    
  2. Фиксация и отправка в указанный репозиторий для перехватчики предварительного получения на ваш экземпляр GitHub Enterprise Server.

    git commit -m "YOUR COMMIT MESSAGE"
    git push
    
  3. Создайте перехватчик предварительного получения в экземпляре GitHub Enterprise Server.

Локальное тестирование скриптов предварительного получения

Перед созданием или обновлением скрипта перехватчика предварительной передачи можно протестировать на ваш экземпляр GitHub Enterprise Server. Один из способов — создать локальную среду Docker для работы в качестве удаленного репозитория, который может выполнять перехватчик предварительного получения.

  1. Убедитесь, что Docker установлен в локальной среде.

  2. Создайте файл с именем 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"]
    
  3. Создайте тестовый скрипт предварительного получения с именем always_reject.sh. В этом примере скрипт отклоняет все отправки, что полезно для блокировки репозитория:

    #!/usr/bin/env bash
    
    echo "error: rejecting all pushes"
    exit 1
    
  4. Убедитесь, что скрипты always_reject.sh имеют разрешения на выполнение:

    chmod +x always_reject.sh
    
  5. Из каталога, содержащего 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
    
  6. Запустите контейнер данных, содержащий созданный ключ SSH:

    docker run --name data pre-receive.dev /bin/true
    
  7. Скопируйте тестовый перехватчик предварительного получения always_reject.sh в контейнер данных:

    docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
    
  8. Запустите контейнер приложения, который запускает sshd и выполняет перехватчик. Запишите возвращенный идентификатор контейнера:

    $ docker run -d -p 52311:22 --volumes-from data pre-receive.dev
    > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
    
  9. Скопируйте созданный ключ SSH из контейнера данных на локальный компьютер:

    docker cp data:/home/git/.ssh/id_ed25519 .
    
  10. Измените удаленный репозиторий тестов и отправьте его в репозиторий 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'
    

    Обратите внимание, что отправка была отклонена после выполнения перехватчика предварительного получения и повторения выходных данных скрипта.

Дополнительные материалы