Quais tasks executar em seu servidor de CI ?

43328984

 

Ao implantar alguma forma de Integração Contínua no seu projeto, você certamente terá que escolher, dentre um oceano de  opções, um conjunto de steps que seu software deve percorrer até estar “pronto” para produção. Com base na minha tradução do excelente artigo sobre Integração Contínua do Martin Fowler  (que é um recordista de acessos do blog), decidi botar em pauta uma sugestão de pipeline, descrevendo seus steps.

A idéia deste artigo é ser agnóstico em relação ao seu CI server, mas como tenho um background maior com o Jenkins/Hudson, é possivel que use alguma terminologia desse servidor. Se tiver alguma dúvida, pergunte lá na parte de comentários que eu tento ajudar. Vamos lá!

Decidindo quem entra e quem sai

Screen Shot 2013-11-26 at 5.37.51 PM

Decidir quais passos são realmente relevantes para a publicação do seu software nem sempre é uma tarefa simples, dado que existem diversas técnicas e adotar todas elas transformará seu release em um  processo impraticável.

Eu tento seguir os seguintes steps nas pipelines que implemento:

  • Recuperação do código para a máquina de CI;
  • Atualização de bibliotecas locais na máquina de CI;
  • Execução de testes separados por tipos (rápidos primeiro, lentos depois);
  • Atualização da versão stable e geração de nova versão snapshot;
  • Empacotamento do software/Criação de Tags/Publicação para o servidor de artefatos;
  • Deploy para o ambiente de Homologação/Produção (be careful)

Óbvio que nem todos os steps acima são aplicáveis a todos os ambientes, mas servem de exemplo pra gente pegar a idéia. Cabe a você decidir o que colocar no seu projeto ou não. A idéia mínima é a seguinte: pegar o código, rodar os testes e passar o software adiante, quer seja publicando ou congelando em uma versão validada para futuro deploy.

A idéia por trás de cada Step acima é :

Recuperação do código para a máquina de CI

Esse passo é simples: você tem que pegar a última versão do seu projeto em desenvolvimento do seu controle de versão. Vários servidores de CI possuem algum tipo de plugin para comunicar com os SCM mais conhecidos (SVN, GIT, HG, CVS, etc) . A grande decisão nesse passo é se você vai optar por rodar esses passos automaticamente a cada commit feito pela sua equipe de desenvolvedores ou se a sua pipeline iniciará manualmente, com alguém clicando em “Run”.

Minha opnião é : faça automaticamente, a cada commit. Porém existem alguns “poréns”. O primeiro porém é :  como sua pipeline pode demorar para rodar completamente, é possivel que ocorra novos commits enquanto seu servidor de CI ainda esteja rodando a pipeline do commit anterior e isso pode gerar falsos erros devido a execução paralela da mesma pipeline. Para resolver isso, aconselho você configurar seu CI server para rodar com somente um step por vez (sem paralelismo)o que impossibilita que diversas pipelines rodem simultâneamente. O ponto negativo disso é que, em contra-partida, seu processo de release ficará mais lento.

O segundo porém é que você deve se precaver para não permitir  que cada commit, ao final da sua pipeline, vá parar diretamente em produção. Certamente você não vai querer isso, independente se  o commit quebra ou não sua build. Nesse ponto, muita gente critica erroneamente o Continuous Delivery, pensando que ele prega que todos os commits irão gerar novas versões do seu software , e consecutivamente, essas versões devem ir direto para produção, sem um “double check humano”. Não, Continuous Delivery não diz isso, ele diz que a última versão do seu software sempre esta preparada para ir para produção, o que é beeem diferente de estar em produção.

chaves

 

Uma solução para isso (que na verdade não é nenhuma novidade) é sempre ter um ambiente de Homologação (ou QA, ou aceitação, seja lá como você o chame)  e apontar seu servidor de Integração para fazer o deploy ao final da sua pipeline para este servidor. Assim, você garante que sempre terá um ambiente testado, rodando e pronto para um double check humano, que viabilizará o OK para subida em produção.

 

Atualização de bibliotecas locais na máquina de CI

Nesse passo temos a tarefa de atualizar seu servidor de CI com todas as versões de bibliotecas externas que seu software usa. Um grande alívio para nós, desenvolvedores foi alguém, em algum lugar, ter tido a incrível idéia de integrar um gerenciador de pacotes ao no seu processo de desenvolvimento.

Uma vez que seu projeto use um easy-install, pip, gem, maven ou qualquer outra forma de especificar as bibliotecas, versões e repositórios, cabe nesse step você utilizar o programa responsável para instalar localmente essas dependências. É bom manter esse step separado dos demais para facilmente identificar algum problema na instalação/atualização dessas bibliotecas.

 

Execução de testes por tipos (rápidos x lentos)

Nesse step (ou steps) é onde você realmente roda os testes na sua aplicação – eu escrevi “steps” por que acho aconselhável separar cada tipo de teste em um step próprio e organizar para que os testes mais rápidos rodem primeiro, pois se eles quebrarem, você será notificado mais rápidamente. Um tendência bem comum é que alguns tipos de testes demorem muito para rodar, principalmente com o projeto crescendo. Um exemplo disto são os testes funcionais, que exigem uma observação adicional.

Testes funcionais exigem que você tenha um ambiente “up and running” para que possam rodar. Como a idéia da pipeline é você só atualizar seu  servidor se o software estiver testado, fica claro que você precisa de um ambiente adicional para rodar seus testes funcionais. O que faço é:  depois que todos os outros testes tiverem rodado, faço um deploy da aplicação para um ambiente separado e assim rodo os testes funcionais contra esse ambiente. Para os que usam um SO unix-like e dependam de um navegador para rodar os testes funcionais (comum para quem usa Selenium por exemplo), você pode usar o XBFV e rodar browsers virtuais por ele.

 

Atualização da versão stable e geração de versão snapshot

n64-kid_o_GIFSoup.com_thumb

Parabéns campeão, seu presente tá quase pronto. 

Bom, se seu commit passou por todos os passos anteriores, meus parabéns, isso significa que seu código esta rodando e portanto, falta muito pouco para ir ao ar. E nesse passo você sinaliza isso, fazendo a atualização da versão que esta em pronta para deploy e da versão que esta em desenvolvimento. É comum, por exemplo, você adotar uma nomeclatura que diferencie a versão em desenvolvimento da versão que esta pronta pra deploy.

Por exemplo, vamos imaginar que temos as seguintes versões antes de rodar a pipeline:

  • Última versão “estável” : 1.01
  • Versão em desenvolvimento: 1.02-SNAPSHOT

Depois de rodar sua pipeline, você terá:

  • Última versão “estável” : 1.02
  • Versão em desenvolvimento: 1.03-SNAPSHOT

Uma regra bem definida na nomenclatura das versões do seu software ajuda a identificar o que esta pronto e o que esta em desenvolvimento, além de ser possível ter um roadmap de que alterações entraram em cada versão. Alguns sistemas de gerenciamento de tarefas (como Jira) podem até fazer a associação das tasks X versões do seu software automaticamente. Procure alguma biblioteca que te ajude a controlar as versões do seu sofware (em Ruby tem o versionomy), mas um simples controle com um arquivo .version na raiz do seu projeto já funciona.

 

Empacotamento do software/ Criação de Tags/ Publicação para o servidor de artefatos

Essa é a hora de comunicar ao mundo que seu software esta pronto para ir ao ar. Nesse step, você já pode “congelar” seu código publicando para os devidos repositórios e gerenciadores de artefatos.  Geralmente os SCMs tem alguma forma de sinalizar as versões fechadas (como as Tags do SVN). Já vi algumas pessoas criarem branches no Git/Hg com as versões geradas no passo anterior ou até mesmo publicar um .zip com a aplicação para algum repositório de artefatos. A idéia é você ter um lugar de rápido acesso caso precise pegar uma versão antiga para reverter um deploy catastrófico que foi feito no ambiente de homologação/produção.

Deploy para o ambiente de Homologação/Produção (be careful)

43327918

Por uma política interna muito sensata (mas burocrática), algumas empresas impedem que os processos de publicação a produção sejam de responsabilidade da equipe de desenvolvimento, delegando a uma equipe de SysOps essa responsabilidade. Se esse é o seu caso, uma simples notificação ao final da pipeline pode ser enviada ao setor responsável, suprimindo assim a necessidade de chamadas diretas a algum software de deploy.

Para ser franco, o processo de subida geralmente não é um processo simples, principalmente para ambientes distribuídos. Geralmente você tem diversas máquinas em nuvem que precisam serem atualizadas e não pode derrubar a aplicação completamente para upgrade, correndo o risco de apresentar alguma inconsistência em seu serviço. O Twitter, Facebook e outras empresas com um número gigante de servidores em produção precisam até usar métodos extremamente alternativos (como publicação de build via torrent) para acelerar suas subidas para produção em suas milhares de máquinas. Embora seja muito bacana, isso é papo para outro post.

Conclusão

Tentei nesse post ser breve, sem deixar de passar por alguns pontos que achei importante. É óbvio que muita coisa foi posta de fora, mas nada que novos posts ou um bate papo na parte de comentários abaixo não resolva. Pretendo, futuramente, fazer um step-by-step ensinando a como encadear os jobs no seu Jenkins, criando uma pipeline parecida com essa que descrevi. Aguardo seus comentários :-)

Code Smells – Duplicação de Código

tumblr_mp8dtqhOmI1sx2peuo1_500

  Semana passada postei uma tradução do artigo em inglês sobre Code Smells, escrito pelo Martin Fowler. Pretendo criar alguns posts rápidos comentando sobre smells clássicos e possíveis formas de combatê-los. Por hoje, vamos ver em Ruby como … [Continue reading]

Code Smells

code_smells

O texto abaixo é a uma tradução do artigo escrito pelo Martin Fowler. Para acessar a versão original em inglês, clique aqui . Caso você tenha sugestões para tornar a tradução melhor, compartilhe através da seção de comentários no final da … [Continue reading]

Testes funcionais com Cucumber e Page Objects

  Aproveitando que meu último post foi justamente uma tradução do ótimo artigo do Martin Fowler sobre  Page Objects, vou engatar no tema e postar algumas sugestões de como usar esse pattern com o cucumber para criar os testes funcionais da … [Continue reading]

Tradução do artigo sobre PageObjects

pageObject

  O texto abaixo é a uma tradução autorizada do artigo escrito pelo Martin Fowler. Para acessar a versão original em inglês, clique aqui . Caso você tenha sugestões para tornar a tradução melhor, compartilhe através da seção de comentários no … [Continue reading]

Resenha de Livro : APIs – A Strategy Guide

20111231-1110

Acabei de entrar na reta final do livro APIs: A Strategy Guide  e acho que já vale me adiantar e publicar uma resenha rápida do mesmo. O livro em questão é do Daniel Jacobson (@daniel_jacobson), juntamente com Greg Brail e Dan Woods. Estes dois … [Continue reading]

Scala : Curso gratuito com guru da linguagem

Scala_logo

    Muito tem se falado sobre o poder das linguagens funcionais atualmente - o velho entrou (novamente) na moda. Fiz há alguns meses este curso do Coursera, que é ministrado pelo próprio Martin Odersky - pai da linguagem e quase … [Continue reading]

Pé na estrada com phonegap: primeiros passos

Organizacao de arquivos JS

  Visto a complexidade que é desenvolver  aplicações para as diversas plataformas mobile existentes, vários projetos tem aparecido propondo soluções  na construção de aplicações hibridas. O caminho é quase sempre o mesmo: construir … [Continue reading]

Instalando wkhtmltopdf em uma Amazon EC2

timthumb

  Depois de uma bela surra de gato morto, é bem fácil instalar o wkhtmltopdf em uma instância Amazon Ec2 AMI baseada em CentOS. Para quem não conhece o wkhtmltopdf, é uma app usada pra gerar PDFs  de páginas HTMLs, usando Webkit como motor de … [Continue reading]

Meteor: eis ai algo que me impressionou.

Screenshot-at-2012-04-13-121857

Meteor: 100% Javascript, hot deploy, banco distribuído com manipulação direto no cliente, baixa latência na atualização dos outros clientes, entre outras coisas. Enfim, o projeto promete, tire você mesmo suas próprias … [Continue reading]

10 coisas que lideres ágeis devem ter

executive-10-things-poster

É pra imprimir e colocar na porta de entrada! Fonte: http://acarlos.net/post/19405198842/10-things-leaders-should-do-differently-in-an-agile   … [Continue reading]