FONT-FAMILY: Verdana; mso-bidi-font-size: 28.0pt">Conhecendo o CruiseControl

Implementando integração contínua em um projeto com a ajuda deste servidor

Aprenda a montar um ambiente de integração contínua usando CruiseControl, Maven e Subversion

É quase impossível encontrar uma aplicação ou sistema feito por um único programador, já que cada vez mais a engenharia de software é colocada a serviço da resolução de problemas complexos. Pelo contrário, o comum é vermos ambientes compostos por vários desenvolvedores (e equipes) que precisam construir um software coerente, em projetos que incluem requisitos como reutilização de código, integração com outros sistemas e convivência com legado. Essas situações apresentam diversas dificuldades de administração, sendo uma das principais a dependência entre os diversos componentes escritos por diferentes desenvolvedores.

Existem práticas e ferramentas que têm por objetivo tornar o processo de desenvolvimento mais gerenciável, o que resulta em aumento da qualidade do produto final. Equipes escrevem testes unitários para garantir que cada "peça" do software funcione como esperado e testes de aceitação para validar com o cliente se a aplicação faz o que ele tinha imaginado. Também usa-se ferramentas de controle de versão para que os desenvolvedores tenham um local único para buscar as últimas atualizações que eles ou outros fizeram na base de código, bem como buscar versões anteriores caso seja necessário voltar atrás. E adota-se uma metodologia, que define o relacionamento da equipe entre si e com seus clientes, além de estipular a forma pela qual o desenvolvimento se dará.

Uma metodologia que não pára de ganhar força no mercado de software é Extreme Programming (XP). A partir de práticas revolucionárias (algumas, como programação pareada, considerada insana por alguns), XP promove o desenvolvimento de software de qualidade de maneira flexível, sustentável, e rápida na medida do possível. Mas uma de suas práticas menos conhecidas e utilizadas, provavelmente por parecer difícil de ser implantada, é a Integração Contínua. Esse artigo pretende mostrar o quão simples pode ser colocar essa "rede de segurança" em um projeto.

O que é integração contínua?

Integração contínua é na verdade um conjunto de práticas, listadas em artigo escrito por Martin Fowler em 2000, que tem por objetivo garantir que a todo momento o software desenvolvido se encontre num estado consistente.


Para mais informações sobre integração contínua, ver artigo publicado na Java Magazine 35.

 

Infra-estrutura

A primeira delas é o uso de um sistema de controle de versão central para que os desenvolvedores tenham um local bem definido para guardar e procurar arquivos com código, configurações, html ou qualquer outro conteúdo necessário para a construção do software. Para entender mais sobre controle de versão, veja quadro Controle de versão e Subversion. Além disso, testar o software em um clone do ambiente de produção é desejável. Obviamente existem limites para tal, tanto em termos de custos quanto de organização, mas alguns itens são simples de serem realizados, como usar os mesmos sistema operacional e banco de dados. Essa é uma boa forma de descobrir com antecedência se a aplicação está suscetível a problemas que existem em produção devido à sua interação com outros componentes do ambiente.

Automação

Outro item muito importante é a presença de um processo de build automático. O processo de build de um projeto pode ser complexo, envolvendo compilação do código, criação de tabelas no banco de dados, cópia de arquivos de configuração, etc. O responsável pelo build pode cometer um erro em qualquer uma dessas etapas caso o processo seja manual. Ter um build automático diminui drasticamente as chances de algo dar errado na geração do software por alguma bobagem como apagar um arquivo por um erro de digitação. Além disso, a equipe pode gerar e ver a aplicação funcionando rapidamente, o que é bastante valioso e recompensador. Para entender mais sobre o processo de build, veja quadro Processo de build e Maven. Aliado ao build, testes automatizados dão segurança e agilidade tanto à equipe quanto aos clientes, pois mostram a qualquer momento que o software está funcionando como esperado (ou, caso não esteja, pelo menos os desenvolvedores descobrem isso o quanto antes). O ideal é que sejam desenvolvidos tanto testes unitários, que verificam o comportamento dos componentes individuais da aplicação (como classes), quanto os testes de aceitação, que verificam a aplicação como um todo, do ponto de vista do usuário. Escrever testes automatizados não é fácil, em especial os de aceitação, mas desenvolver um projeto sem eles é certamente muito mais difícil.

O último item a ser automatizado é o deploy da aplicação, ou seja, deve ser possível enviar a aplicação para produção através de scripts. A justificativa para tal é que para ser ágil, o projeto precisa poder ser colocado automaticamente em uma máquina qualquer, o que é importante para que não se perca tempo, por exemplo, levando-o para um ambiente de homologação. Já que esse suporte existe, fazer o deploy em produção não deve ser um problema. Um ponto de atenção é que o rollback, para o caso de algo dar errado, também deve estar automatizado.

 

Agilidade

Além das práticas já citadas, outra de fundamental importância são commits freqüentes. Algumas coisas podem dar errado ao se fazer um commit, como um conflito surgir quando um desenvolvedor tentar colocar uma nova classe no repositório depois de outro ter feito o mesmo ou o novo código "quebrar" os testes. Se os commits são feitos freqüentemente, uma vez por dia por desenvolvedor pelo menos, fica fácil resolver essas questões, já que além de os desenvolvedores ainda possuírem o código na cabeça, o que ajuda na resolução dos conflitos, a quantidade de alterações nunca é muito grande caso se precise ter o trabalho de resolver conflitos (merge).

Relacionado aos commits freqüentes, há a recomendação de manter o build sempre rápido, diminuindo assim o tempo que os desenvolvedores têm que esperar para voltar ao trabalho, ainda mais quando são muitos os commits feitos diariamente. XP aconselha dez minutos, o que pode parecer muito, mas considerando que um build completo implica em compilar o projeto, rodar todos os testes unitários, empacotar o código gerado, fazer o deploy em um ambiente de testes e rodar os testes de aceitação, é possível perceber que não é tanto assim. É comum se dividir o build em estágios quando esse tempo se torna excessivo, deixando os testes de aceitação para serem executados apenas uma vez ao dia, por exemplo.

Nas metodologias ágeis, o feedback rápido é essencial. Outro mecanismo que suporta esse objetivo é criar os meios para que qualquer um, e não só os desenvolvedores, tenha acesso ao último executável. Isso ajuda muito na hora de fazer uma demonstração do software, e também possibilita, por exemplo, que um dos interessados no software "brinque" com a aplicação, gerando opiniões e sugestões que podem ser incorporadas ao projeto.

Outro benefício do feedback rápido é a possibilidade de qualquer um ver o que está acontecendo com o projeto, pois é importante que todos os envolvidos estejam atentos a sua “saúde”. Assim, a equipe deve conseguir saber se um build está sendo executado no momento e o seu resultado (em especial se ele falhou).

Por último, a integração contínua diz que toda vez que um commit é realizado, o build deve ser executado em uma máquina de integração. Isso serve como garantia de que configurações de ambiente da máquina de um desenvolvedor não façam com que um build que falharia em outro lugar seja bem sucedido. Além disso, essa prática defende o projeto de problemas disciplinares, como por exemplo, o caso em que um desenvolvedor faz o commit sem ter rodado os testes, e acaba mandando para o repositório código “quebrado”.

É para suportar várias das práticas citadas acima (mas não todas) que um servidor de integração contínua como o CruiseControl pode ser utilizado. Um servidor desse tipo nada mais é que uma aplicação responsável por checar e avisar os desenvolvedores sobre o estado do projeto após cada commit. Embora existam outros servidores de integração contínua, como o Continuum da Apache, o CruiseControl foi escolhido para esse artigo por ser bastante maduro e de qualidade indiscutível.

O CruiseControl foi desenvolvido originalmente pela ThoughtWorks, empresa de Martin Fowler. Existem hoje duas versões: uma open source que é mantida pela comunidade após o release inicial da ThoughtWorks, e outra versão comercial, de código fechado, que continua sendo melhorada de forma independente pela empresa. Este artigo é focado na versão open source.

A partir daqui mostraremos como montar um ambiente de integração contínua com o CruiseControl e outras duas ferramentas bastante difundidas na comunidade Java: Subversion para controle de versão, e Maven 2 como ferramenta de build.

Preparando o ambiente

Instalando Subversion, Maven e CruiseControl

Antes de mais nada, vamos criar o ambiente com os três projetos. Para instalar o Subversion siga os seguintes passos:

1.      Baixe a última versão estável para o seu sistema operacional de  ...