A Integração Contínua (Continuous Integration, CI) é uma prática essencial no desenvolvimento de software moderno. Este artigo tem como objetivo explicar o que é CI e apresentar as melhores práticas para implementá-la eficazmente.
O que é Integração Contínua
A Integração Contínua é uma boa prática de desenvolvimento de software de DevOps em que as alterações de código são integradas ao repositório principal de forma frequente, geralmente várias vezes ao dia. Em outras palavras, podemos dizer que as alterações de código são juntadas com o que já existe no repositório do serviço.
O objetivo é detectar erros rapidamente, permitindo que eles sejam corrigidos mais facilmente. A cultura DevOps é fortemente orientada a filosofia de falhar rápido e corrigir rápido. Além do mais, a fase de desenvolvimento é o melhor lugar para se falhar, tendo em vista que seus clientes não sofrem nenhum impacto.
A Integração Contínua é uma boa prática de desenvolvimento de software de DevOps em que as alterações de código são integradas ao repositório principal de forma frequente, geralmente várias vezes ao dia. Em outras palavras, podemos dizer que as alterações de código são juntadas com o que já existe no repositório do serviço.
O objetivo é detectar erros rapidamente, permitindo que eles sejam corrigidos mais facilmente. A cultura DevOps é fortemente orientada a filosofia de falhar rápido e corrigir rápido. Além do mais, a fase de desenvolvimento é o melhor lugar para se falhar, tendo em vista que seus clientes não sofrem nenhum impacto.
Benefícios da CI
Os benefícios da CI são vários, mas podemos destacar os seguintes:
- Detecção precoce de erros: uma boa prática para implantar uma CI eficiente é executar testes automatizados após cada integração, onde erros são identificados rapidamente. Esse é um excelente lugar para se executar diversos testes, sejam eles unitários, componentes ou até fim-a-fim dependendo do padrão implementado;
- Redução de conflitos de integração: integrações frequentes reduzem a complexidade e os conflitos que podem ocorrer quando diversas alterações são combinadas. Em times grandes, um dos grandes problemas que temos é a sobreposição e/ou mudanças em trechos do código que podem impactar as novas funcionalidades que estão sendo desenvolvidas. A CI frequente é uma grande aliada para evitar horas e horas durante o merge de código;
- Aumento da qualidade do software: testes automáticos, ferramentas de segurança de código (como gitleaks, trufflehog e Snyk) e boas regras de boas práticas (como linters) garantem que o código integrado atenda aos padrões de qualidade estabelecidos.
Exemplos
A CI (Integração Contínua) de cada aplicação é muito particular, variando de projeto para projeto e da maturidade que os times que estão gerenciando esse processo possuem. De qualquer forma, podemos pensar em alguns exemplos bem genéricos de CI para discutirmos.
Lembrando que a forma de construir as pipelines varia de acordo com a ferramenta de pipelines que está em uso. Nesse nosso exemplo, estamos usando uma aplicação feita em Python, cujo objetivo é o de rodar os testes disponíveis para garantir que o código novo não quebre nada pré existente e disponível no repositório.
CI no GitHub
name: CI Pipeline
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
pytest
Para CI no GitHub, o segmento on: push: branches: – main define que a pipeline será acionada por commits na branch main, enquanto que pull_request: branches: – main específica que também será acionada por pull requests para a mesma branch. No job build, que roda na última versão do Ubuntu (runs-on: ubuntu-latest), as etapas (steps) incluem: Checkout repository usando actions/checkout@v2 para acessar o código, configuração do Python com actions/setup-python@v2, instalação de dependências com pip, e execução de testes com pytest. Estas etapas ilustram a automação e organização das tarefas dentro da pipeline.
CI no Azure DevOps
trigger:
branches:
include:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
- script: |
python -m pip install --upgrade pip
pip install -r requirements.txt
displayName: 'Install dependencies'
- script: |
pytest
displayName: 'Run tests'
Na CI com Azure DevOps, o YAML especifica que a pipeline será acionada por commits na branch main usando o trigger branches: include: – main. A pipeline é executada em um ambiente Ubuntu (vmImage: ‘ubuntu-latest’). Dentro dos steps, o primeiro passo é configurar a versão do Python (UsePythonVersion@0), seguido pela instalação de dependências com pip, e finaliza executando testes com pytest. Cada script e tarefa é claramente rotulada (por exemplo, displayName: ‘Install dependencies’), facilitando a identificação de cada etapa na pipeline.
Melhores práticas
Implementar CI de forma eficiente requer seguir algumas práticas para garantir qualidade e total integridade do código existente. Abaixo estão as principais recomendações:
Automatização dos testes
- Testes Unitários: cada integração deve disparar uma suíte de testes unitários para verificar a funcionalidade básica do código, a menor unidade possível do que foi escrito pelo desenvolvedor;
- Testes de Integração: além dos testes unitários, é importante incluir testes de integração para garantir que diferentes partes do sistema funcionam juntas, como uma integração com banco de dados.
Build automatizado
- Scripts de build: utilize scripts de build para automatizar a compilação do código, executando o que o próprio desenvolvedor faria se estivesse testando sua funcionalidade localmente, garantindo que o processo seja reproduzível e consistente;
- Ambiente de build limpo: cada build deve ocorrer em um ambiente limpo para evitar dependências de estado de builds anteriores.
Integração Frequente
- Commits frequentes: desenvolvedores devem fazer commits frequentes de pequenas mudanças. Isso facilita a identificação de problemas e a integração de código com a estratégia de CI, pois o código estará constantemente sendo testado;
- Branches curtas: utilize branches curtas e de vida curta (short lived branch) para minimizar conflitos de integração e facilitar a revisão de código, quebrando assim códigos grandes e complexos em pequenas entregas consistentes.
Feedback rápido
- Notificações: configure notificações como mensagens no Slack, Discord ou até mesmo envio de emails, para informar os desenvolvedores imediatamente após a falha de um build ou teste;
- Relatórios detalhados: algumas soluções como Harness.io ou Azure DevOps disponibilizam visualizações e relatórios detalhados sobre as falhas para facilitar a investigação rápida de problemas.
Ambiente de CI saudável e cultura de colaboração
- Monitoramento: monitore continuamente o ambiente de CI para identificar gargalos e problemas de desempenho. À medida que o código se torna complexo é necessário revisar toda a estrutura de CI que é executada, garantindo assim uma boa performance de suas validações;
- Revisão de código: incentive a prática de revisão de código para melhorar a qualidade e compartilhar conhecimento entre a equipe;
- Documentação: documente as práticas de CI e os procedimentos de build e teste para garantir que todos os membros da equipe estejam alinhados.
Acelere sua carreira conosco
A Mentoria Next Level DevOps é um programa de mentoria de 12 meses com encontros semanais ao vivo, com um grupo seleto e restrito, onde estaremos do seu lado para mantê-lo relevante e atualizado no mercado de tecnologia, aprendendo e implementando as melhores práticas e ferramentas de DevOps.
Clique aqui para entrar na prioridade pela melhor oferta de lançamento
Considerações finais
A Integração Contínua é uma das práticas fundamentais que ajuda a melhorar a qualidade do software e a eficiência do time de desenvolvimento. Seguindo as melhores práticas descritas neste artigo, equipes de desenvolvimento podem aproveitar ao máximo os benefícios, resultando em entregas de software mais rápidas e com grande qualidade.