Close

Git com integração/implementação contínua: cinco dicas para repositórios Git de fácil utilização com IC

Fique pronto para o sucesso — seu repositório é o ponto de partida para todo o restante.

Foto de rosto de Sarah Goff-Dupont
Sarah Goff-Dupont

Escritora principal


Git e entrega contínua representam uma dessas deliciosas combinações de "chocolate e manteiga de amendoim" que às vezes a gente encontra no mundo do software — dois ótimos sabores que ficam excelentes juntos. Assim, quero compartilhar algumas dicas para fazer seus builds no Bamboo serem bem reproduzidos com seus repositórios do Bitbucket. A maior parte da interação acontece nas fases de build e de teste da entrega contínua. Assim, você vai ver que vou falar mais sobre integração contínua, em vez de implementação contínua.

1: Armazene arquivos grandes fora do repositório


Algo que você escuta com frequência sobre Git é que deve evitar colocar arquivos grandes em seu repositório: binários, arquivos de mídia, artefatos arquivados, etc. Isso porque, depois de adicionar um arquivo, ele sempre estará lá no histórico do repositório, o que significa que, sempre que o repositório for clonado, aquele arquivo enorme e pesado também será clonado.

Tirar qualquer arquivo do histórico do repositório é chatinho — é o mesmo que operar o cérebro da sua base de código. Essa extração cirúrgica do arquivo altera todo o histórico do repositório, fazendo com que você perca a visibilidade de quais alterações foram feitas,e quando. São ótimos motivos para evitar arquivos grandes, como regra geral. E...

Manter arquivos grandes fora dos seus repositórios Git é importante, em especial, para CI

Sempre que você executa um build, seu servidor de CI precisa clonar seu repositório no diretório de build de trabalho. Se o seu repositório estiver repleto de artefatos enormes, ele tornará esse processo lento e aumentará o tempo que seus desenvolvedores precisarão esperar pelos resultados do build.

Ok, tudo bem. Mas e se o seu build depender de binários de outros projetos ou artefatos grandes? Essa é uma situação muito comum, e provavelmente sempre será. Assim, a pergunta é: como podemos lidar com ele de maneira eficaz?

Ver solução

Crie e opere softwares com o Open DevOps

Material relacionado

Descubra o que é desenvolvimento baseado em troncos

Os sistemas de armazenamento externo como o Artifactory (que cria um complemento para o Bamboo), o Nexus ou o Archiva podem ajudar no caso dos artefatos gerados pela sua equipe ou pelas equipes ao redor. Os arquivos de que você precisa podem ser incluídos no diretório de builds no início do build — assim como as bibliotecas de terceiros que você obtém via Maven ou Gradle.

Fica a dica: se os artefatos são alterados com frequência, não sincronize arquivos grandes com o servidor de build todas as noites. Basta fazer a transferência deles no disco no momento do build. Entre as sincronizações noturnas, a equipe vai acabar desenvolvendo com versões obsoletas dos artefatos. Além disso, os desenvolvedores vão precisar desses arquivos para os builds em suas estações de trabalho locais de qualquer jeito. Então, no geral, o mais organizado a fazer é integrar o download de artefatos ao processo de build.

Se a rede não conta com nenhum sistema de armazenamento externo, é mais fácil aproveitar a compatibilidade com arquivos grandes (LFS) oferecida pelo Git.

Git LSF é uma extensão que armazena ponteiros para arquivos grandes em seu repositório, em vez de armazenar os arquivos em si. Os arquivos em si são armazenados em um servidor remoto. Como você pode imaginar, isso reduz o tempo de clonagem drasticamente.

Git LSF

É provável que você já tenha acesso ao Git LFS — compatível com Bitbucket e GitHub.

2: Usar clones superficiais para CI


Sempre que um build é executado, seu servidor de build clona o repositório no diretório de trabalho atual. Como mencionei antes, quando um Git clona um repositório, ele clona todo o histórico do repositório por padrão. Assim, ao longo do tempo, essa operação vai levar cada vez mais tempo.

Com clones superficiais, apenas o instantâneo atual do seu repositório será aberto. Assim, pode ser bastante útil para reduzir tempos de execução de build, especialmente ao trabalhar com repositórios grandes e/ou mais antigos.

Captura de tela de repositório Git

Digamos que seu build exija todo o histórico do repositório: se, por exemplo, uma das etapas no seu build atualizar o número de versão no seu POM (ou similar), ou você estiver mesclando dois branches a cada build. Ambos os casos exigem que o Bamboo envie as alterações por push de volta ao seu repositório.

Com o Git, as alterações simples feitas nos arquivos (como atualizar o número da versão) podem ser enviadas sem todo o histórico presente. Porém, para o processo de merge, o histórico do repositório ainda é necessário, pois o Git precisa de informações passadas para encontrar o ancestral comum das duas ramificações. E essa exigência é problemática quando o build usa clonagem superficial. O que me leva à dica nº 3.

3: Armazenar em cache o repositório em agentes de build


A operação de clonagem também fica muito mais rápida, e o Bamboo faz essa ação por padrão.

Observe que o armazenamento em cache do repositório o beneficia apenas se você estiver usando agentes que persistam de um build para outro. Se você criar e destruir agentes de build em EC2 ou outro provedor de nuvem sempre que um build é executado, o armazenamento em cache do repositório não fará diferença, pois você estará trabalhando com um diretório de build vazio e precisará obter uma cópia completa do repositório de qualquer maneira.

Clones superficiais mais armazenamento em cache de repositório dividido pelos agentes elásticos vs. persistentes é igual a uma interessante rede de fatores. Aqui está uma pequena matriz para ajudá-lo a criar uma estratégia.

Captura de tela de agentes permanentes vs. agentes elásticos

4: Escolha seus acionadores com sabedoria


É (quase) desnecessário dizer que implementar a integração contínua em todas as suas ramificações ativas é mais do que recomendado. Porém, é bom executar todas os builds em todas as ramificações em relação a todos os commits? É provável que não. Entenda o motivo.

Considere a Atlassian, por exemplo. A gente tem mais de 800 desenvolvedores, todos enviando alterações para o repositório várias vezes ao dia — a maioria envia para as ramificações de recursos. É muito build! E, a menos que você faça a escala instantânea e infinita dos agentes de build, essa imensidão de builds resulta em muita espera na fila.

Um dos nossos servidores internos do Bamboo abriga 935 planos de builds diferentes. A gente conectou 141 agentes de build a esse servidor sem deixar de seguir as práticas recomendadas, como aprovação de artefatos e paralelização de teste, para que todo build seja o mais eficiente possível. E o pior: a criação de builds depois de cada push estava atrapalhando o progresso do trabalho.

Em vez de simplesmente montar outra instância do Bamboo com outros 100 agentes ou mais, recuamos e perguntamos se isso era realmente necessário. E a resposta foi negativa.

Dessa forma, demos aos desenvolvedores a opção de transformar seus builds de branch em botões, em vez de sempre acioná-los automaticamente. É uma boa maneira de equilibrar o rigor de teste com a preservação de recursos, e os branches são o local em que a maior parte da atividade está acontecendo. Por isso, é uma ótima oportunidade para economias.

Muitos desenvolvedores gostam de ter o maior controle que botões oferecem e consideram que se encaixam perfeitamente no fluxo de trabalho deles. Outros preferem não pensar sobre quando executar um build e atêm-se a acionadores automáticos. Ambas as abordagens podem funcionar. O importante é ter seus branches em teste em primeiro lugar e garantir que você tenha um build limpo antes de mesclar na cadeia produtiva.

Miniatura de acionadores contínuos

Porém, ramificações críticas, como ramificações da versão estável e principal, são outra história. Builds têm acionamento automático, seja sondando o repositório quanto a alterações ou enviando notificações push do Bitbucket para o Bamboo. Uma vez que a gente usa ramificações de desenvolvimento para todo o trabalho em andamento, os únicos commits que vêm para o principal devem (em teoria) ser ramificações de desenvolvimento sendo mescladas. Além disso, essas são as linhas de código com base nas quais a gente lança e cria as ramificações de desenvolvimento. Assim, é muito importante termos resultados de teste em tempo hábil para cada merge.

5: Pare de sondar, comece a capturar


Fazer pesquisas no repositório a cada poucos minutos à procura de alterações é uma operação muito fácil no Bamboo. Porém, ao escalar até centenas de builds em milhares de ramificações envolvendo dezenas de repositórios, o uso de recursos aumenta rápido. Em vez de sobrecarregar o Bamboo com toda essa pesquisa, você pode fazer com que o Bitbucket avise quando uma alteração for enviada e precisar ser criada.

É comum alcançar esse feito por meio da adição de hooks ao repositório, mas a integração entre o Bitbucket e o Bamboo faz toda a configuração "por baixo dos panos". Depois de vinculados no back-end, o build orientado a repositório aciona o Just Work™ pronto para uso. Não é necessário usar Hooks ou configurações especiais.

Captura de tela de configuração do Bitbucket

Não importa a ferramenta usada, os acionadores controlados por repositório têm a vantagem de "hibernarem" automaticamente quando a ramificação-alvo fica inativa. Ou seja, chega de desperdiçar os ciclos de CPU do sistema de integração contínua pesquisando centenas de ramificações abandonadas ou de perder tempo com o fechamento manual dos builds das ramificações. (Vale observar que o Bamboo pode ser configurado com facilidade para ignorar as ramificações após X dias de inatividade, se ainda assim você quiser fazer as pesquisas.)

O essencial para usar o Git com integração contínua é…


...ter atenção. Todas as coisas funcionaram muito bem quando você estava fazendo integração contínua com um VCS centralizado? Não vai ser bem assim com o Git. Portanto, verifique suas suposições — esse é o primeiro passo. Para os clientes da Atlassian, o segundo passo é integrar o Bamboo ao Bitbucket. Consulte a documentação para saber mais informações e divirta-se!

Sarah Goff-Dupont
Sarah Goff-Dupont

Sarah é uma engenheira de controle de qualidade que virou escritora cujo trabalho foi apresentado na Harvard Business Review, Inc., Huffington Post, bem como em publicações do setor. Ela trabalha de casa em Minnesota e ama cada minuto. Quando ela não está escrevendo, você pode encontrá-la lendo, fazendo snowboard, cozinhando e/ou trocando trocadilhos cringe com os filhos.

Entre em contato com Sarah no LinkedIn


Compartilhe este artigo

Leitura recomendada

Marque esses recursos para aprender sobre os tipos de equipes de DevOps ou para obter atualizações contínuas sobre DevOps na Atlassian.

Ilustração DevOps

Comunidade de DevOps

Ilustração DevOps

Leia o blog

Ilustração do mapa

Comece gratuitamente

Inscreva-se para receber a newsletter de DevOps

Thank you for signing up