Veja exemplos de ganchos de pré-recebimento do GitHub Enterprise Server no repositório github/platform-samples
.
Gravar um script de hook pre-receive
Um script de gancho de pré-recebimento é executado em um ambiente de gancho de pré-recebimento no sua instância do GitHub Enterprise Server. Ao criar um script de hook pre-receive, considere a entrada, saída, estado de saída e variáveis de ambiente disponíveis.
Entrada (stdin
)
Após um push e antes da atualização de quaisquer referências no repositório remoto, o processo git-receive-pack
no sua instância do GitHub Enterprise Server invoca o script do gancho de pré-recebimento. A entrada padrão para o script, stdin
, é uma cadeia de caracteres que contém uma linha para cada referência a ser atualizada. Cada linha contém o nome antigo do objeto para ref, o novo nome do objeto para o ref e o nome completo do ref.
<old-value> SP <new-value> SP <ref-name> LF
Essa frase representa os argumentos a seguir.
Argumento | Descrição |
---|---|
<old-value> | Nome do objeto antigo armazenado na referência. Quando você cria uma referência, o valor é 40 zeros. |
<new-value> | Novo nome de objeto a ser armazenado na referência. Quando você exclui uma referência, o valor é 40 zeros. |
<ref-name> | O nome completo da ref. |
Para obter mais informações sobre git-receive-pack
, confira "git-receive-pack" na documentação do Git. Para obter mais informações sobre as referências, confira "Referências do Git" em Pro Git.
Saída (stdout
)
A saída padrão do script, stdout
, é transmitida novamente para o cliente. As instruções echo
ficarão visíveis para o usuário na linha de comando ou na interface do usuário.
Status da saída
O status de saída de um script pre-receive determina se o push será aceito.
Valor de status de saída | Ação |
---|---|
0 | O push será aceito. |
diferente de zero | O push será rejeitado. |
Variáveis de ambiente
Além da entrada padrão para o script de gancho de pré-recebimento, stdin
, o GitHub Enterprise Server disponibiliza as variáveis a seguir no ambiente do Bash para a execução do script. Para obter mais informações sobre o stdin
do script de gancho de pré-recebimento, confira "Entrada (stdin
)".
Diferentes variáveis de ambiente estão disponíveis para o seu script de hook pre-receive dependendo do que acionar o script.
- Sempre disponível
- Disponível para pushes por meio da interface da Web ou da API
- Disponível para mesclagem de solicitação de pull
- Disponível para pushes que usam a autenticação SSH
Sempre disponível
As seguintes variáveis estão sempre disponíveis no ambiente de do hook pre-receive.
Variável | Descrição | Valor de exemplo |
---|---|---|
$GIT_DIR | Caminho para o repositório remoto na instância | /data/user/repositories/a/ab/ a1/b2/34/100001234/1234.git |
$GIT_PUSH_OPTION_COUNT | O número de opções de push enviadas pelo cliente com --push-option . Para obter mais informações, confira "git-push" na documentação do Git. | 1 |
$GIT_PUSH_OPTION_N | Quando N for um número inteiro que começa no 0, essa variável conterá a cadeia de caracteres da opção de push enviada pelo cliente. A primeira opção enviada é armazenada em GIT_PUSH_OPTION_0 , a segunda opção enviada é armazenada em GIT_PUSH_OPTION_1 etc. Para obter mais informações sobre as opções de push, confira "git-push" na documentação do Git. | abcd |
$GIT_USER_AGENT | String de usuário-agente enviada pelo cliente Git que realizou push das alterações | git/2.0.0 |
$GITHUB_REPO_NAME | Nome do repositório que está sendo atualizado no formato NOME/PROPRIETÁRIO | octo-org/hello-enterprise |
$GITHUB_REPO_PUBLIC | Booleano público, que representa se o repositório está sendo atualizado |
|
$GITHUB_USER_IP | Endereço IP do cliente que iniciou o push | 192.0.2.1 |
$GITHUB_USER_LOGIN | Nome de usuário para a conta que iniciou o push | octocat |
Disponível para pushes a partir da interface web ou API
A variável $GITHUB_VIA
ficará disponível no ambiente do gancho de pré-recebimento quando for feita a atualização de referência que dispara o gancho por meio da interface da Web ou da API do GitHub Enterprise Server. O valor descreve a ação que atualizou o ref.
Valor | Ação | Mais informações |
---|---|---|
auto-merge deployment api | Merge automático do branch base através de uma implantação criada com a API | "Pontos de extremidade da API REST para implantações" |
blob#save | Mudar para o conteúdo de um arquivo na interface web | "Editando arquivos" |
branch merge api | Merge de um branch através da API | "Pontos de extremidade da API REST para ramificações e suas configurações" |
branches page delete button | Exclusão de um branch na interface web | "Criar e excluir branches no repositório" |
git refs create api | Criação de um ref através da API | "Pontos de extremidade da API REST para referências Git" |
git refs delete api | Exclusão de uma ref através da API | "Pontos de extremidade da API REST para referências Git" |
git refs update api | Atualização de um ref através da API | "Pontos de extremidade da API REST para referências Git" |
git repo contents api | Mudança no conteúdo de um arquivo através da API | "Pontos de extremidade da API REST para conteúdos de repositório" |
merge | Mesclagem de uma pull request usando mesclagem automática | "Fazer merge automático de um pull request" |
merge base into head | Atualização do branch do tópico partindo do branch base quando o branch base exige verificações de status rígidas (por meio de Atualizar branch em uma pull request, por exemplo) | "Sobre branches protegidos" |
pull request branch delete button | Exclusão de um branch do tópico de uma pull request na interface da Web | "Excluir e restaurar branches em uma pull request" |
pull request branch undo button | Restauração de um branch do tópico de uma pull request na interface da Web | "Excluir e restaurar branches em uma pull request" |
pull request merge api | Mesclagem de uma pull request por meio da API | "Pontos de extremidade da API REST para pull requests" |
pull request merge button | Mesclagem de uma pull request na interface da Web | "Mesclar uma solicitação de pull" |
pull request revert button | Reversão de uma pull request | "Reverter uma pull request" |
releases delete button | Exclusão de uma versão | "Gerenciar versões em repositórios" |
stafftools branch restore | Restauração de um branch do painel de administração do site | "Administrar sua instância por meio da interface do usuário da Web" |
tag create api | Criação de uma tag através da API | "Pontos de extremidade da API REST para tags do Git" |
web branch create | Criação de um branch por meio da interface da Web | "Criar e excluir branches no repositório" |
Disponível para merge de pull request
As variáveis a seguir estão disponíveis no ambiente de hook pre-receive quando o push que aciona o hook é um push devido ao merge de um pull request.
Variável | Descrição | Valor de exemplo |
---|---|---|
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN | Nome de usuário da conta que criou o pull request | octocat |
$GITHUB_PULL_REQUEST_HEAD | O nome do branch do tópico da solicitação de pull, no formato USERNAME:BRANCH | octocat:fix-bug |
$GITHUB_PULL_REQUEST_BASE | O nome do branch base da solicitação de pull, no formato USERNAME:BRANCH | octocat:main |
Disponível para pushes que usam autenticação SSH
Variável | Descrição | Valor de exemplo |
---|---|---|
$GITHUB_PUBLIC_KEY_FINGERPRINT | A impressão digital da chave pública para o usuário que fez push das alterações | a1:b2:c3:d4:e5:f6:g7:h8:i9:j0:k1:l2:m3:n4:o5:p6 |
Configurar permissões e fazer push de um hook pre-receive para o GitHub Enterprise Server
Um script de gancho de pré-recebimento está contido em um repositório no sua instância do GitHub Enterprise Server. O administrador do site deve considerar as permissões do repositório e garantir que somente os usuários adequados tenham acesso.
Recomendamos consolidar os hooks em um único repositório. Se o repositório do gancho consolidado for público, o README.md
poderá ser usado para explicar a imposição das políticas. Além disso, é possível aceitar contribuições via pull request. No entanto, os hooks pre-receive só podem ser adicionados pelo branch padrão. Em fluxos de trabalho de teste, devem ser usados forks do repositório com a devida configuração.
-
Para usuários de Mac, certifique-se de que os scripts tenham estas permissões de execução:
sudo chmod +x SCRIPT_FILE.sh
Para usuários de Windows, certifique-se de que os scripts tenham estas permissões de execução:
git update-index --chmod=+x SCRIPT_FILE.sh
-
Confirme e envie por push ao repositório designado para ganchos de pré-recebimento no sua instância do GitHub Enterprise Server.
git commit -m "YOUR COMMIT MESSAGE" git push
-
Crie o gancho de pré-recebimento na instância do GitHub Enterprise Server.
Testar scripts pre-receive no local
É possível testar um script de gancho de pré-recebimento localmente antes de criá-lo ou atualizá-lo no sua instância do GitHub Enterprise Server. Uma forma de fazer isso é criar um ambiente Docker local para funcionar como repositório remoto que pode executar o hook pre-receive.
-
Verifique se o Docker está instalado localmente.
-
Crie um arquivo chamado
Dockerfile.dev
contendo: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"]
-
Crie um script de pré-recebimento de teste chamado
always_reject.sh
. Este exemplo de script rejeitará todos os pushes, o que é importante para bloquear um repositório:#!/usr/bin/env bash echo "error: rejecting all pushes" exit 1
-
Verifique se os scripts
always_reject.sh
têm permissões de execução:chmod +x always_reject.sh
-
No diretório que contém
Dockerfile.dev
, compile uma imagem:$ 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
-
Execute um contêiner de dados que contenha uma chave SSH gerada:
docker run --name data pre-receive.dev /bin/true
-
Copie o gancho de pré-recebimento de teste
always_reject.sh
para o contêiner de dados:docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
-
Execute um contêiner de aplicativo que executa
sshd
e executa o gancho. Anote o ID do contêiner:$ docker run -d -p 52311:22 --volumes-from data pre-receive.dev > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
-
Copie a chave SSH gerada do contêiner de dados para a máquina local:
docker cp data:/home/git/.ssh/id_ed25519 .
-
Modifique o repositório remoto de um repositório de teste e efetue push para o repositório
test.git
no contêiner do Docker. Este exemplo usagit@github.com:octocat/Hello-World.git
, mas você poderá usar qualquer repositório que desejar. Este exemplo pressupõe que a sua máquina local (127.0.0.1) está vinculando a porta 52311, mas você pode usar outro endereço IP se o docker estiver sendo executado em uma máquina remota.$ 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'
Observe que o push foi rejeitado após a execução do hook pre-receive e o eco da saída do script.
Leitura adicional
- "Como personalizar o Git – Um exemplo de política imposta pelo Git" do site do Pro Git