Continuous Integration

Depois de alguns posts sobre assuntos relacionados a Service Oriented Architecture, vou tratar de um assunto muito importante que ultimamente tem recebido atenção, porém ainda é muito negligenciado na maioria das empresas:

Continuous Integration, ou integração contínua, é uma prática de desenvolvimento de software onde os membros da equipe integram seu trabalho frequentemente, geralmente cada desenvolvedor integra ao menos uma vez por dia. Cada integração é verificada por uma ferramenta de build automatizado[1] (incluindo testes) com a finalidade de detectar erros de integração o mais rápido possível, economizando assim o custo de correção nas fases posteriores do projeto, que é muito mais alto.

A partir da definição acima, podemos identificar algumas áreas:

Configuration Management ou Gerência de Configuração;

Software Testing ou Testes de Software;

Build and Integration / Build Management ou Construção e Integração / Gerência de Construção;

Definições

Trunk: tronco ou pasta principal de um repositório;

Branch: ramo ou pasta secundária de um repositório. É criado a partir de uma cópia de determinada revisão (versão) do trunk;

Merge: é a ‘mescla’ de duas versões do mesmo arquivo. Ocorre quando o mesmo arquivo é alterado no Trunk e no Branch e essas alterações precisam ser unificadas;

Configuration Management

Por mais absurdo que possa parecer, existem empresas que ainda perdem códigos fonte de sistemas por não possuirem uma ferramenta de controle de versão. Infelizmente já vi este cenário algumas vezes. Esse é o primeiro ponto a ser tratado para implantação de CI.

Depois de implantado, é necessário estabelecer politicas de permissão de acesso, criação de repositórios, projetos, branchs, tags, etc. Neste ponto é indicado o uso da seguinte estratégia para gerenciamento de branches:

Considerando que um ponto crítico no controle de versão é o Merge, deve-se tentar evitar ao máximo o uso de branches, desta forma, o número de Merges é significativamente reduzido. Para isso sugere-se o uso do Trunk para desenvolvimento e, assim que o código for promovido para produção, um branch é criado. Este branch deve ser fechado no próximo deploy, quando um novo branch de produção é criado. Desta forma, a única ocorrência de Merge será na correção de bugs no código de produção, que é corrigido no branch. Depois de corrigido, o Merge para o Trunk deve ser feito o mais rápido possível, para minimizar a ocorrência de conflitos.

branchStrategy

Em projetos SOA, este tópico é um pouco mais delicado, considerando que o código fonte normalmente são arquivos XML gerados pela IDE. Não existe Merge para este tipo de arquivo! Neste caso, se o artefato alterado na correção NÃO tiver sido alterado no Trunk, é feito um overide and commit do Branch para o Trunk. Caso contrário a correção deve ser re-implementada no Trunk.

Software Testing

Acredito que ainda não é comum encontrarmos projetos novos com uma boa cobertura de testes de unidade. É fundamental que a equipe possa trabalhar protegida por uma boa cobertura de testes de unidade automatizados. Sem isso qualquer alteração um pouco mais complexa torna-se um desafio cercado de riscos, inibindo refactoring e promovendo soluções paliativas (vulgo gambiarra). Com isso acaba sendo inevitável o aumento da complexidade do código. O tópico Testes unitários incentivam o refactoring deste post trata isso com mais detalhes.

Em projetos maiores, como é o caso de projetos SOA, eles são praticamente indispensáveis devido a complexidade do ambiente. Quanto mais rápido um erro é identificado e isolado, menos tempo/esforço é gasto pelas equipes de diversas áreas/parceiros.

Build and Integration

Finalmente, após estar com a ferramenta de controle de versão e alguma cobertura nos testes de unidade automatizados, pode-se investir na automatização do build e deploy.

Neste momento um servidor de build é implantado com o objetivo de fazer o checkout do projeto, compilar, executar os testes de unidade automatizados, realizar o deploy e executar os testes integrados. Desta forma é possível identificar de maneira rápida quando o código presente no controle de versão foi ‘quebrado’.

É importante ressaltar que o tema foi abordado de forma bastante superficial, e que esta ordem sugerida seria a mais intuitiva, porém cada caso é um caso, é preciso analisar qual ação/ferramenta irá gerar mais retorno.