Três ganchos do Git para integração contínua

Discover how Git hooks enforce clean builds on feature branches and more.

Sarah Goff-Dupont Sarah Goff-Dupont

If you've used Git for a while, you've probably heard of Git hooks. Maybe you've even played around with them a bit. Git hooks are awesome in the context of continuous integration, so in this article I'll dive into three use cases and point you to ready-made hooks you can add to your workflow. If you're new to Git hooks, no worries: we'll start with the basics.

Understanding Git hooks

Hooks are Git's native mechanism for triggering custom scripts before or after operations like commit and merge. Think of them as Git’s plugin system. If you look in the .git directory of any Git repository you’ll see a directory named “hooks” which contains a set of example hook scripts. 

.git/hooks

Installing Git hooks is straightforward and well-documented, so I won't get into that here.

There are two broad classes of hooks: client-side and server-side. Client-side hooks run on your local workstation, while server-side hooks run on your Git server.

Você também pode classificar ganchos como pré ou pós. Ganchos pré-recebimento são invocados antes de determinadas operações Git e têm a opção de cancelar uma operação, se necessário. Eles atuam como seguranças protegendo seu repositório por trás de uma corda, impedindo que você e seus colegas confirmem códigos com defeito. Ganchos pós-recebimento são executados após uma operação ter sido concluída e, portanto, não têm a opção de cancelá-la. Em vez disso, ganchos pós-recebimento automatizam partes do seu fluxo de trabalho de desenvolvimento.

Using #Git hooks is like having little robot minions to carry out your every wish (muwa-ha-haaaa!).

Ganchos de Git automatizam coisas como…

  • verifying that you included the associated JIRA issue key in your commit message
  • enforcing preconditions for merging
  • enviar notificações à sala de bate-papo da equipe
  • configurar seu espaço de trabalho depois de mudar para um branch diferente

Impor builds limpos em branches de recursos

Server-side pre-receive hooks are an especially powerful compliment to continuous integration because they can prevent developers from pushing code to master, unless the code meets certain conditions – like elite ninja guardians, protecting it from bad code.

Developers are generally conscientious enough not to merge to master when there are broken tests on their branch. But sometimes we forget to check. Or when we’re sharing a branch with other people, sometimes more changes get made since we last checked the branch build… stuff happens.

So you can add a server-side hook that looks for incoming merges to master. When it finds one, the script checks the latest build on your branch, and if there are any failing tests, the merge is rejected. My colleague and Atlassian developer advocate Tim Petterson wrote a hook script for this, designed to work with Bamboo, and made it available on Bitbucket. You can grab it, customize it, and add it to your repo.

Protegendo sua cobertura de código duramente conquistada

Something I’ve seen lots of teams struggle with is maintaining code coverage. Often times they’ve had to retroactively cover their code base with tests, and it’s really frustrating to see that hard-earned coverage slip away as more features get added without tests shoring them up. So Tim also wrote a pre-receive server-side hook to protect master from declining code coverage.

This hook also looks for incoming merges to master. It then calls out to the continuous integration server to check current code coverage on master, and coverage on the branch. If the branch has inferior coverage, the merge is rejected.

Most continuous integration servers don't expose code coverage data through their remote APIs, so the script pulls down the code coverage report. To do this, the build must be configured to publish the report as a shared artifact, both on master and on the branch build. Once published, you can grab the latest coverage report from master by calling the continuous integration server. For branch coverage, you fetch the coverage report either from the latest build, or for builds related to the commit being merged.

And just to be clear, this all assumes you already have code coverage running. The hook doesn’t magically do that – it just looks for the coverage data in your build results. This one also works with Bamboo by default, as well as Clover (Atlassian's code coverage tool for Java and Groovy). But it can be customized to integrate with any build server or code coverage tool.

Checking the status of branch builds

Because friends don't let friends check out broken branches.

Here's a chance to play with client-side Git hooks: a post-checkout hook script that exposes branch build status right inside your terminal window, also from Tim. The script gets the branch's head revision number from your local copy, then queries the continuous integration server to see whether that revision has been built – and if so, whether the build succeeded.

Digamos que você queira ramificar a partir do mestre. Esse gancho dirá se a confirmação principal no mestre foi compilada com sucesso, o que significa que é uma confirmação "segura" da qual criar um branch de recursos. Ou digamos que o gancho diga que o build para a revisão falhou, ainda assim, o mural da equipe mostra um build verde para o branch (ou vice-versa). Isso significa que sua cópia local está desatualizada. Ficará a seu critério decidir se você obterá as atualizações ou continuará trabalhando na cópia local que você tem.

Usar esse gancho poupou aos desenvolvedores da Atlassian inúmeras dores de cabeça. Se você não consegue convencer a sua equipe a adotar os ganchos de servidor discutidos acima, pelo menos instale esse na sua estação de trabalho local. Você não vai se arrepender.

Todos os ganchos do Git para integração contínua que eu mostrei aqui funcionam com Bamboo, Clover e Bitbucket por padrão. Porém, lembre-se de que os ganchos do Git são neutros em termos de fornecedor; assim, você pode personalizá-los para que funcionem com qualquer pilha de ferramentas que você tenha. Automação para a vitória!