Git Hooks
Publicados: 2022-07-02O Git é um poderoso sistema de controle de versão no qual mal arranhamos a superfície em nossos últimos posts. Hoje, veremos o poder de automação que o Git pode oferecer a você com o Git Hooks.
Todo repositório recebe hooks embutidos quando você usa o comando git init
. Quando um repositório é inicializado, você obtém um diretório .git
oculto e dentro dele há um diretório chamado hooks que conterá todos os seus hooks. Abra qualquer repositório git que você tenha à mão e use ls -a
para ver o diretório oculto, depois abra-o em seu editor de código favorito.
Para começar, você verá vários arquivos com extensões de arquivo .sample
. Estes são exatamente o que eles dizem, scripts de amostra que você pode usar em seus projetos. Os arquivos são nomeados para corresponder ao gancho em que são executados. Então post-commit.sample
é executado no gancho post-commit
.
Você pode usar praticamente qualquer linguagem para escrever um gancho. O arquivo é analisado de acordo com a notação shebang na parte superior do arquivo. Se você quisesse usar o nó, usaria #! /usr/bindi/env node
#! /usr/bindi/env node
e seu arquivo será analisado como um arquivo node.
Antes de nos aprofundarmos no que você pode fazer com os ganchos do git, vamos dar uma olhada em alguns dos ganchos que estão disponíveis para você.
Tipos de Git Hooks
Confirmar ganchos de fluxo de trabalho
pre-commit
é executado antes mesmo de você inserir sua mensagem de commit e pode ser ignorado com git commit --no-verify
.
prepare-commit-msg
pode ser usado para editar a mensagem padrão que você vê em sua mensagem de commit. Use-o para dar instruções aos desenvolvedores sobre que tipo de mensagem de commit eles devem deixar. Ele também pode ser usado para automatizar o conteúdo de onde a mensagem é gerada automaticamente para você, como mesclagens ou para adicionar um número de problema à sua mensagem de confirmação automaticamente.
commit-msg
pode ser usado para validar a mensagem de commit para seu projeto. Talvez você não queira que ninguém coloque uma mensagem de commit que diga simplesmente “lidando com espaço em branco”. Você pode usar esse gancho para detectar a presença das palavras espaço em branco e, em seguida, sair e fornecer um aviso ao usuário de que ele precisa ter uma mensagem de confirmação melhor.
post-commit
é executado após todos os hooks de commit acima. É mais útil para uma notificação de que um commit foi feito.
Ganchos do cliente
post-checkout
é executado depois que você executa um comando git checkout bem-sucedido. Se você tivesse um conjunto de arquivos grandes usados no site, mas não os quisesse no controle do código-fonte, você poderia usar este comando para mover os arquivos para você.
pre-push
é executado durante um comando git push antes de quaisquer objetos serem transferidos para o repositório remoto.
Ganchos do Servidor
pre-receive
é executado quando um cliente envia código para um repositório remoto. Isso pode ser usado para verificar o código que está sendo enviado para garantir que ele atenda aos critérios do seu projeto antes de aceitar o envio.
post-receive
é executado após seu repositório remoto ter recebido as atualizações. Isso pode ser usado para chamar um web hook que aciona um processo de implantação ou notifica uma sala de bate-papo que um commit foi recebido e está pronto para revisão.
Muitos dos ganchos acima podem ser configurados para serem executados apenas em ramificações específicas. Isso pode significar quando você usa um gancho post-receive
somente quando alguém envia o código para a ramificação principal que deveria estar pronta para implantação. Uma lista de desenvolvedores pode ser notificada para revisar o código e depois implantá-lo. Dessa forma, você sempre teria dois pares de olhos em uma implantação, o que pode significar detectar erros que um único desenvolvedor pode facilmente perder.
Eu pulei alguns dos ganchos que estão disponíveis porque nunca vi necessidade de usá-los. Um conjunto de ganchos sobre os quais não falei são os ganchos de fluxo de trabalho de e-mail. Se você não estiver aceitando patches para seu código por e-mail, provavelmente nunca precisará deles. Você pode encontrar todos os ganchos disponíveis na documentação.
Na prática, os ganchos que mais usei são:
- pré-comprometer
- pré-empurrar
- commit-msg
- pré-receber
- pós-commit
- pós-recebimento
Agora vamos fazer algo com esses ganchos.
Ativando um plugin do WordPress com WP Cli e Git Hooks
Para um projeto de cliente este ano, eu estava adicionando uma loja e ainda fazendo algumas tarefas no site principal. Isso significava que o site principal não tinha nenhum dos nossos plugins WooCommerce instalados ou ativados. Eu precisava desenvolver a loja WooCommerce em uma filial e só quando eu estava pronto para colocar tudo ao vivo, eu queria mover o WooCommerce para o main.
Para começar, precisaremos de um novo branch chamado store. Podemos obter isso usando git checkout -b store
. Isso cria uma nova ramificação e verifica para nós. Agora vamos preparar o gancho.
Primeiro precisamos criar o hook post-checkout com este comando touch .git/hooks/post-checkout
.
Em seguida, precisamos torná-lo executável. Podemos fazer isso com o comando chmod do terminal chmod +x .git/hooks/post-checkout
.
Agora abra o arquivo no editor de código de sua escolha e copie o código abaixo em seu arquivo post-checkout
.
#! /bin/bash
wp plugin activate woocommerce
echo "activated WooCommerce"
wp plugin activate automatewoo
echo "activated AutomateWoo"
Você pode demonstrar isso mudando para qualquer ramal via terminal. Você deve ver duas linhas informando que o WooCommerce e o AutomateWoo foram ativados. Sabemos que está funcionando, mas não é bem o que queremos porque ele ativará os plugins toda vez que mudarmos para qualquer branch.
O que realmente queremos é ativá-los quando nos mudarmos para nossa filial de loja e desativá-los quando estivermos em nossa filial principal. Para fazer isso, precisaremos do gancho para detectar de qual branch somos um. Troque o conteúdo do post-checkout
com o código abaixo.
#! /bin/bash
oldrev=$1
newrev=$2
branch_name="(git symbolic-ref HEAD 2>/dev/null)"
if [ "refs/head/store" = "$branch_name" ];then
wp plugin activate woocommerce
echo "activated Woo"
wp plugin activate automatewoo
echo "activated AutomateWoo"
fi
if [ "refs/head/main" = "$branch_name" ];then
wp plugin deactivate woocommerce
echo "deactivated Woo"
wp plugin deactivate automatewoo
echo "deactivated AutomateWoo"
fi
Este código começa atribuindo o branch que estamos verificando à variável branch_name
. Então temos duas instruções if. O primeiro verifica se nos mudamos para a filial da loja. Se tivermos, ele usa o WP CLI para ativar o WooCommerce e o AutomateWoo.
A próxima instrução if verifica se estamos no branch principal. Se estivermos, ele desativará os plugins com WP CLI e nos informará sobre isso no terminal.
Controlando fluxos de trabalho do Git com Git Hooks
Em um post anterior no Git, falei sobre diferentes fluxos de trabalho do Git. Um caso de uso muito comum para hooks é impedir que alguém comita código diretamente no branch principal. Você pode usar um gancho para garantir que todo o código seja mesclado de uma ramificação diferente em main.
Comece renomeando pre-commit.sample
para pre-commit
e, em seguida, torne-o executável como descrevi acima. Em seguida, pegue o código abaixo e use-o no arquivo de pré-commit.
#! /bin/bash
username=$GIT_AUTHOR_NAME
branch="$(git symbolic-ref HEAD 2>/dev/null)"
if [ "$branch" = "refs/heads/main" ]; then
echo "WHOA that was '"${branch}"' you should not do that. Stop doing silly stuff and create your own branch and merge it."
exit 1 # if you remove this it won't block the commit but it will send the message to slack
fi
Isso verifica se estamos no branch principal e, se estivermos, o commit é interrompido. Em seguida, ele imprime um lembrete para o usuário de que ele não deve se comprometer diretamente com a ramificação principal.
Lembre-se de que muitos lugares estão mudando para main
como seu branch. Projetos mais antigos podem precisar de master
aqui se não tiverem sido atualizados.
Você pode até dar um passo adiante e usar cURL para acessar a API de um aplicativo de bate-papo e depois reclamar publicamente que alguém tentou se comprometer com o main.
As únicas limitações dos git hooks são sua imaginação. Você pode usá-los para impedir que alguém cometa se um TODO estiver presente em seu código ou para interromper o espaço em branco no final de um arquivo.
Se você tem alguma parte do seu fluxo de trabalho que é um obstáculo contínuo, veja os ganchos para automatizá-lo, para que você não precise se lembrar.