Nos últimos tempos tenho continuado a explorar a integração contínua tentando tornar a sua utilização, ou melhor, configuração, o mais simples e eficaz possível. Até ao momento identifiquei alguns pontos importantes que me parecem importantes, pelo menos no contexto do meu ambiente de trabalho.

Scripts de Build

É essencial criar alguns templates para os scripts de build, para evitar o reinventar da roda a cada projecto. Comecei por seguir as recomendações de algumas pessoas e partir o script em dois. Um script inicial (de bootstrap), lançado pelo CruiseControl.Net e que é igual para todos os projectos: no essencial faz o get das sources, limpa a pasta de build e lança o script específico do projecto. A vantagem desta estrutura é que o próprio script do projecto é versionado e monitorizado, pelo que quando fazemos alterações no script, o processo de build é automaticamente despoletado.

O script do projecto também é bastante semelhante para os projectos que me interessam, de modo que também este pode ser partido. Como base, o build compila a solução, executa os testes unitários, faz code coverage, documenta as assemblies, faz análise estática do código e versiona as assemblies. Estes passos deverão ser comuns a todos os projectos, pelo que também é possível realizar algum refactoring por aqui...

Adicionalmente, faço uso intensivo das propriedades, à semelhança da utilização de constantes no código. Deste modo, não é preciso andar a procurar no código as diversas directorias envolvidas no processo, por exemplo, ao mesmo tempo que evito a duplicação.

Estrutura de directorias

Regra geral é conveniente manter estruturas de directorias normalizadas, por razões conhecidas de todos. Com processos de build/integração contínua, podemos considerar esta regra essencial, para manter o processo de configuração o mais simples possível. Eu considero existirem quatro pastas de base: Solução, que contém o código e afins do sistema (a Solução no Visual Studio .Net); Configurações de Build, que contém todos os ficheiros de configuração das aplicações utilizadas no processo de build ou auxiliares ao desenvolvimento; Build, onde é realizado o build; Documentação, onde se mantém a documentação do projecto.

Eventualmente, podem-se considerar outras, como uma pasta com utilitários, por exemplo.

Versionamento

Um dos problemas recorrentes no desenvolvimento é o versionamento e a luta contínua para manter a sua consistência. Pode ser dado um passo importante nesta questão se incluirmos o versionamento no build. Num processo de build podemos definir uma versão e aplicá-la nas labels do SourceSafe (ou outro sistema) e nas assemblies. O esquema que montei baseia-se em dois pontos principais: o CruiseControl.net gera a versão e aplica-a ao projecto no SourceSafe; o Nant recebe a versão do CC.Net, e antes de realizar a compilação cria um AssemblyInfo.cs comum a todas as assemblies para manter a consistência das versões. Graças aos mecanismos de extensibilidade do CC.Net, criei uma classe que gera a versão de acordo com as minhas regras, pelo que agora consigo em qualquer momento associar as assemblies à versão da solução que os geraram, sem qualquer acção manual da minha parte.

À medida que for identificando mais (alguns já o estão, mas ainda não estão consolidados na minha cabeça), tentarei incluí-los aqui no ContraCorrente.

Como podem verificar a prática de build está intimamente ligada às disciplinas de Configuration Management, nomeadamente o controlo de versões. Além disso os processo de build são peças centrais da disciplina de Release Management. Para saber mais sobre estas disciplinas, consultem o site www.cmcrossroads.com.

Já agora, no evento PontoNet dia 15 de Outubro no Tagus, vou fazer uma apresentação sobre integração contínua. Dêem lá um salto, quanto mais não seja para dar apoio moral e para, se houver oportunidade, contarem as vossas experiências. Também estou totalmente aberto aos vossos conselhos.