Deploys Automáticos com Git

Primeiramente, é preciso deixar claro que git não é uma ferramenta de deploy. Há diversos motivos porque digo isso, mas os principais que devem ser lembrados são:

  1. git não mantém permissões de arquivo;
  2. git não versiona pasta vazias;

Porém, existem algumas boas práticas que podem efetivamente automatizar os seus deploys para servidores de teste ou produção.

Para esta tarefa, iremos utilizar uma funcionalidade do Git chamada “hooks”.

Um Pouco Sobre Repositórios Bare

Embora possa ser usada em repositórios comuns, esta ferramenta é mais eficiente em repositórios bare.

Um repositório bare é o mesmo tipo de repositório utilizado por serviços populares como o Github, Bitbucket ou Heroku. Ele pode ser criado com o comando git init --bare.

Este repositório é diferente de repositórios de trabalho comuns. Ele não possui um working directory, ou seja, não possui uma pasta com arquivos para trabalho, e não possui uma branch específica. Ele é basicamente um diretório .git exposto, criado apenas para fins de compartilhamento.

Git Hooks

A funcionalidade de hooks permite que o Git execute scripts quando determinados eventos ocorrem no repositório. Podemos, por exemplo, executar scripts antes e após atos de commit, merge ou pushes tanto na máquina de envio quanto na máquina de recebimento.

A pasta hooks dentro do repositório Git (ou na pasta .git/hooks, para repositórios de trabalho) já contém alguns exemplos dos hooks mais comuns. No caso de deploys, os hooks úteis serão o pre-receive e o post-receive, com nomes bem indicativos de quando eles irão executar.

No nosso script, iremos utilizar o post-receive.

Script de deploy

Os scripts podem depender muito da linguagem com a qual se está trabalhando, então falaremos aqui apenas da parte agnóstica, que irá ajudar em qualquer linguagem.

O objetivo do script é realizar uma cópia do projeto em alguma pasta que esteja sendo servida, mantendo o repositório em si intocado. Precisamos que todos os arquivos que forem deletados no controle de versão também sejam deletados na pasta de instalação, mas também precisamos que arquivos não trackeados sejam ignorados pelo deploy. Muitas vezes teremos arquivos de configuração específicos do servidor de produção, e não queremos apagá-los toda vez que houver um push, certo?

No arquivo post-receive:

#!/bin/sh
export GIT_WORK_TREE=/diretorio/de/deploy
git checkout -f master

Este script funciona dessincronizando temporariamente o index e a work tree do repositório, fazendo com que o checkout trabalhe com arquivos em um diretório separado. Caso você decida mudar a branch em que está realizando checkout, pode ser necessário limpar o seu diretório de deploy.

Customizações

Para abortar o deploy caso ache mudanças em arquivos trackeados, use este comando antes do checkout:

git diff --quiet || exit 1

Esta linha encerrará o script caso alguma modificação seja encontrada.

Caso precise, também é possível abortar no caso de encontrar arquivos não trackeados:

git ls-files -o | grep >/dev/null . && exit 1

Em caso de dúvidas, fique a vontade para deixar um comentário.


480 Words

2014-06-02 07:27 -0300

comments powered by Disqus