Skip to main content
Мы публикуем частые обновления нашей документации, и перевод этой страницы, возможно, еще выполняется. Актуальные сведения см. в документации на английском языке.

Поддержка этой версии GitHub Enterprise будет прекращена 2023-03-15. Исправления выпускаться не будут даже при критических проблемах безопасности. Для повышения производительности, укрепления безопасности и новых функций установите последнюю версию GitHub Enterprise. Чтобы получить справку по обновлению, обратитесь в службу поддержки GitHub Enterprise.

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

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

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

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

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

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

ПеременнаяОписаниеПример значения
$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Раздел База данных 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:BRANCHoctocat:fix-bug
$GITHUB_PULL_REQUEST_BASE
Имя базовой ветви запроса на вытягивание в формате USERNAME:BRANCHoctocat: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 для объяснения применения политик. Кроме того, вклады можно принимать с помощью запросов на вытягивание. Однако перехватчики предварительного получения можно добавлять только из ветви по умолчанию. Для рабочего процесса тестирования следует использовать вилки репозитория с конфигурацией.

  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 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"]
    
  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 .
    > 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
  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 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'

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

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