Skip to main content

Criar um script de hook pre-receive

Use os scripts de hooks pre-receive a fim de criar requisitos para aceitar ou rejeitar um push com base no conteúdo.

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.

ArgumentoDescrição
<old-value>Nome do objeto antigo armazenado na referência.
Quando você cria um novo ref, 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 de saída

O status de saída de um script pre-receive determina se o push será aceito.

Valor de status de saídaAção
0O push será aceito.
diferente de zeroO 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, consulte 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](#always-available)
    
  •         [Disponível para pushes por meio da interface da Web ou da API](#available-for-pushes-from-the-web-interface-or-api)
    
  •         [Disponível para mesclagem de pull request](#available-for-pull-request-merges)
    
  •         [Disponível para envios que utilizam autenticação SSH](#available-for-pushes-using-ssh-authentication)
    

Sempre disponível

As seguintes variáveis estão sempre disponíveis no ambiente de do hook pre-receive.

VariávelDescriçãoValor 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_OBJECT_DIRECTORY
Caminho para um diretório temporário que contém os objetos do push/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/
objects/ghq_luvYC864B9j
$GIT_QUARANTINE_PATH
Contém o mesmo valor que $GIT_OBJECT_DIRECTORY/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/
objects/ghq_luvYC864B9j
$GIT_ALTERNATE_OBJECT_
DIRECTORIES
Caminho para o diretório de objetos do repositório na instância/data/user/repositories/a/ab/
a1/b2/34/100001234/1234.git/objects
$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çõesgit/2.0.0
$GITHUB_REPO_NAME
Nome do repositório que está sendo atualizado no formato NOME/PROPRIETÁRIOocto-org/hello-enterprise
$GITHUB_REPO_PUBLIC
Booleano público, que representa se o repositório está sendo atualizado
  • true: A visibilidade do repositório é pública
  • false: A visibilidade do repositório é privada ou interna
$GITHUB_USER_IP
Endereço IP do cliente que iniciou o push192.0.2.1
$GITHUB_USER_LOGIN
Nome de usuário para a conta que iniciou o pushoctocat

Disponível para pushes por meio da interface da Web ou da 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.

ValorAçãoMais informações
auto-merge deployment api
Fusão automática do branch base por meio de uma implantação criada com a API
          [AUTOTITLE](/rest/deployments#create-a-deployment) |

|

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 uma ramificação 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 | Endpoints da API REST para conteúdo de repositório | | merge | Mesclagem de uma pull request usando mesclagem automática | Mesclar automaticamente uma pull request | |
merge base into head
| Atualização da ramificação de tópico a partir da ramificação base quando a ramificação base exige verificações de status estritas (por meio de Atualizar ramificação em uma solicitação de pull, por exemplo) | Sobre os branches protegidos | |
pull request branch delete button
| Exclusão de um ramo de tópico de uma solicitação de pull na interface 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 | Endpoints da API REST para solicitações de pull | |
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 uma ramificação a partir do painel de controle 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 | Endereços da API REST para tags do Git | |
web branch create
| Criação de um ramo através da interface 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ávelDescriçãoValor de exemplo
$GITHUB_PULL_REQUEST_AUTHOR_LOGIN
Nome de usuário da conta que criou o pull requestoctocat
$GITHUB_PULL_REQUEST_HEAD
O nome do branch do tópico da solicitação de pull, no formato USERNAME:BRANCH
          <span style="white-space: nowrap;">octocat:fix-bug</span> |

|

$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 a autenticação SSH

VariávelDescriçãoValor de exemplo
$GITHUB_PUBLIC_KEY_FINGERPRINT
A impressão digital da chave pública para o usuário que fez push das alteraçõesa1: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.

  1. 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 Windows usuários, verifique se os scripts têm permissões de execução:

    git update-index --chmod=+x SCRIPT_FILE.sh
    
  2. 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
    
  3.        [Crie o gancho de pré-recebimento](/admin/policies/enforcing-policy-with-pre-receive-hooks/managing-pre-receive-hooks-on-the-github-enterprise-server-appliance#creating-pre-receive-hooks) 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.

  1. Verifique se o Docker está instalado localmente.

  2. 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"]
    
  3. 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
    
  4. Verifique se os scripts always_reject.sh têm permissões de execução:

    chmod +x always_reject.sh
    
  5. 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
    
  6. Execute um contêiner de dados que contenha uma chave SSH gerada:

    docker run --name data pre-receive.dev /bin/true
    
  7. 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
    
  8. 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
    
  9. Copie a chave SSH gerada do contêiner de dados para a máquina local:

    docker cp data:/home/git/.ssh/id_ed25519 .
    
  10. 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 usa git@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](https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy) do _site do Pro Git_