Continuous Integration (CI) é uma prática de desenvolvimento na qual cada membro da equipe integra suas alterações ao repositório compartilhado pelo menos uma vez ao dia, e cada integração é verificada por uma compilação e testes automatizados. A CI detecta conflitos de código e erros de regressão nos estágios iniciais, reduzindo o custo de corrigi-los. De acordo com o Puppet State of DevOps Report, 2025, equipes com CI corrigem bugs 4 vezes mais rápido do que equipes sem automação.
Principais pontos
Continuous Integration (CI) é uma metodologia de desenvolvimento que automatiza o processo de integração de código de vários contribuidores em uma única base de código. O termo foi introduzido por Martin Fowler no início dos anos 2000 como um conjunto de práticas para prevenir o “inferno da integração” — uma situação em que os desenvolvedores trabalham isolados por semanas e, ao mesclar alterações, surgem inúmeros conflitos que exigem dias de resolução manual.
Sem CI, um desenvolvedor termina uma funcionalidade, tenta mesclar suas alterações no branch main e descobre que colegas modificaram os mesmos arquivos. Resolver conflitos leva horas e frequentemente quebra o código funcional. A CI resolve esse problema impondo a integração várias vezes ao dia: quanto mais frequente a integração, menos conflitos e mais fáceis de resolver. A prática mostra que com a integração diária, a resolução de conflitos leva minutos, enquanto com a integração semanal leva horas.
De acordo com o IBM Systems Sciences Institute, o custo de corrigir um bug na fase de codificação é de $25, na fase de teste $100, e na fase de produção $2.500. A CI desloca a detecção de defeitos o máximo possível para a esquerda (shift left), encontrando erros na fase do commit quando sua correção é praticamente gratuita. Equipes com CI gastam em média 15% do tempo em depuração, contra 35% das equipes sem CI.
Martin Fowler definiu as práticas-chave da CI que permanecem relevantes independentemente da pilha de tecnologia. Seguir esses princípios garante que a CI traga valor em vez de se tornar um fardo burocrático. O desenvolvimento mobile impõe requisitos adicionais, mas o núcleo permanece inalterado.
Todo o código do projeto é armazenado em um único repositório com um sistema de controle de versão unificado (Git). Uma fonte única de verdade elimina a situação em que uma funcionalidade é desenvolvida em um fork e não é sincronizada com a base de código principal por semanas. Em projetos mobile, isso significa que as partes Android, iOS e backend podem estar em um mesmo repositório (monorepositório) ou em repositórios separados com um esquema de versionamento compartilhado.
A compilação do projeto deve ser executada com um único comando. Para Android é ./gradlew assembleDebug, para iOS — xcodebuild ou fastlane build. O script de compilação verifica a reprodutibilidade: a compilação no servidor CI deve produzir o mesmo resultado que na máquina do desenvolvedor. Quaisquer diferenças no ambiente são eliminadas por meio de conteinerização ou IaC (Infrastructure as Code).
Após a compilação, todos os níveis de testes são executados: unitários, de integração e de UI. Se os testes falharem, o commit é considerado inválido. Manter o status verde é uma responsabilidade compartilhada da equipe. Em projetos mobile, os testes rápidos (executados em até 5 minutos por commit) são frequentemente separados dos testes lentos (testes de UI em dispositivos reais, executados com menos frequência).
// Exemplo de teste unitário com relatório compatível com CI
class LoginViewModelTest {
private val repository = mock<AuthRepository>()
private val viewModel = LoginViewModel(repository)
@Test
fun loginWithValidCredentials_success() {
val email = "test@example.com"
val password = "ValidPass123"
whenever(repository.login(email, password))
.thenReturn(Result.success(User("token-xyz")))
val result = viewModel.login(email, password)
assertEquals(LoginState.Success, result)
verify(repository).login(email, password)
}
}
Os resultados da CI são públicos para toda a equipe: todos podem ver qual commit quebrou a compilação. A transparência cria uma cultura de responsabilidade: os desenvolvedores verificam suas alterações antes do push e corrigem a compilação quebrada fora de hora. O servidor CI envia notificações para Slack ou Telegram quando o status da compilação muda.
Um sistema CI completo consiste em vários componentes que interagem entre si. Cada componente é responsável por sua parte do pipeline: desde a ativação até o relatório. Entender a arquitetura da CI ajuda a diagnosticar problemas e otimizar o desempenho.
O componente central que gerencia a fila de compilações, a alocação de recursos e a publicação de resultados. Um servidor CI pode ser baseado em nuvem (GitHub Actions, GitLab CI, CircleCI) ou auto-hospedado (Jenkins, TeamCity). O servidor monitora as alterações no repositório via webhook ou polling e aciona o pipeline a cada push ou pull request.
Os runners são máquinas virtuais ou físicas que executam as tarefas de compilação. Na CI em nuvem, os runners são fornecidos pelo provedor e cobrados pelo tempo de uso. Runners auto-hospedados são instalados na própria infraestrutura e exigem manutenção. Compilações iOS precisam de runners macOS, compilações Android precisam de Linux ou Windows.
Após a compilação, o sistema CI salva os artefatos (APK, IPA, relatórios de teste) em armazenamento — eles ficam disponíveis para download e implantação. O cache de dependências (cache do Gradle, cache do CocoaPods) entre execuções acelera as compilações subsequentes em 3 a 5 vezes.
| Componente | Finalidade | Exemplo |
|---|---|---|
| Servidor CI | Orquestração de compilações | Jenkins, GitHub Actions |
| Runner | Execução de tarefas | Runner macOS para iOS |
| Repositório | Armazenamento de código | GitHub, GitLab |
| Armazenamento de artefatos | Armazenamento de artefatos | AWS S3, Artifactory |
| Notificação | Notificação da equipe | Slack, Telegram, email |
O desenvolvimento mobile tem requisitos especiais para CI que diferem de projetos web ou backend. Longos tempos de compilação (3–15 minutos para Android, 5–20 minutos para iOS), múltiplos tipos de artefatos (APK, AAB, IPA), necessidade de assinatura e ofuscação — tudo isso requer configuração personalizada do pipeline de CI.
Uma CI típica para Android inclui: linting (ktlint, detekt) e análise estática, testes unitários com JUnit e MockK, compilação de APK/AAB debug e release, testes instrumentados em emulador dentro da CI e publicação de artefatos. O cache do Gradle acelera compilações repetidas — sem ele, cada compilação baixa as dependências do zero, perdendo 3–5 minutos.
A CI para iOS requer um runner macOS para compilar código Swift/Objective-C. O pipeline inclui: instalação de dependências CocoaPods ou SPM, SwiftLint para verificação de estilo, testes unitários com XCTest, compilação de IPA, assinatura de código via Fastlane match e upload para o TestFlight. Um runner auto-hospedado em Mac mini ou Mac em um data center é uma alternativa aos runners macOS em nuvem.
Flutter e React Native compilam em builds nativos para ambas as plataformas. A CI deve oferecer suporte a dois runners: Linux para compilações Android e macOS para compilações iOS. A estratégia ideal é um pipeline dividido: compilação Android em um runner Linux, compilação iOS em um runner macOS, após o qual ambos os artefatos são combinados em uma única versão.
A escolha de uma ferramenta CI depende do tamanho da equipe, do desempenho necessário, do orçamento e da pilha de tecnologia. Abaixo está uma comparação das soluções populares com foco no desenvolvimento mobile. Soluções auto-hospedadas oferecem controle, mas exigem administração; soluções em nuvem oferecem conveniência, mas limitam a configuração.
Gratuito para repositórios públicos (2000 minutos/mês). GitHub Actions oferece um ecossistema de ações prontas para Android (gradle/actions) e iOS (apple-actions). A desvantagem é que runners macOS estão disponíveis apenas em planos pagos. Ideal para projetos de código aberto e pequenas equipes que já usam GitHub.
Um servidor CI auto-hospedado de código aberto. Jenkins é configurado via Groovy Pipeline, suporta centenas de plugins e funciona em qualquer hardware. Requer um engenheiro DevOps para instalação e manutenção. Popular no segmento empresarial onde o controle da infraestrutura é crítico.
CI/CD integrado no GitLab com arquitetura de runners aberta. GitLab CI permite usar seus próprios runners (incluindo macOS) no plano gratuito. A configuração YAML é mais poderosa que o GitHub Actions, mas mais difícil de aprender. Adequado para equipes que usam GitLab como plataforma única de DevOps.
Uma CI em nuvem focada em velocidade. CircleCI suporta imagens Docker, macOS e Android, e armazena dependências em cache automaticamente. O preço é baseado em créditos — mais caro que o GitHub Actions para equipes pequenas, mas mais rápido devido a runners otimizados. Recomendado para projetos de produção com requisitos de velocidade.
Vamos considerar a configuração de CI para um projeto Android usando GitHub Actions. O pipeline realiza análise estática, compilação e testes em cada push e pull request para o branch main. A configuração mínima leva 15 minutos e não requer serviços externos.
name: Android CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
- run: ./gradlew ktlintCheck detekt
unit-tests:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew testDebugUnitTest
- uses: actions/upload-artifact@v4
with:
name: test-results
path: app/build/reports/tests/
O pipeline consiste em dois jobs paralelos: lint (realiza análise estática) e unit-tests (depende de lint — se o linting falhar, os testes não são executados). O job unit-tests faz upload do relatório de teste como um artefato — a equipe pode revisá-lo na interface do GitHub Actions sem baixar arquivos localmente.
Para evitar falhas de CI devido a erros triviais, configure um hook pre-push no Git ou uma tarefa Gradle que execute as mesmas verificações localmente. Por exemplo: ./gradlew ktlintCheck detekt testDebugUnitTest. Se as verificações locais levarem mais de 3 minutos, divida-as em rápidas (linter) e lentas (testes), executando as rápidas antes de cada commit e as lentas apenas antes do push.
Perguntas frequentes
CI foca na integração e verificação do código (compilação + testes), enquanto CD adiciona automação de implantação. A CI garante que o código está correto; a CD garante que esse código correto possa ser entregue aos usuários. A CI é um pré-requisito para a CD, mas a CD sem CI não funciona.
A frequência mínima é uma vez ao dia por desenvolvedor. A prática ideal é fazer push no repositório ao concluir cada unidade lógica de trabalho (a cada 1–4 horas). Quanto mais frequente a integração, menos conflitos e mais fáceis de resolver. Se mais de 2 dias passarem entre integrações, você não está usando CI.
Para Android, GitHub Actions (gratuito, fácil de configurar) ou GitLab CI (próprios runners) são ideais. Para iOS, CircleCI (melhor suporte macOS) ou Bitrise (CI especializada para projetos mobile). Para projetos multiplataforma, GitLab CI com dois runners (Linux + macOS).
Sim, mas com ressalvas. Testes de UI são lentos (10–30 minutos) e instáveis (flaky). A estratégia ideal: executar testes rápidos (unitários + integração) a cada push, e testes de UI em pull requests, à noite ou antes de um release. Use Device Farm ou emuladores na CI para testes de UI.
Métricas de CI eficaz: tempo de compilação inferior a 15 minutos, porcentagem de compilações verdes superior a 85%, tempo médio de recuperação após falha inferior a 30 minutos. Se a compilação falha com frequência, a CI não está ajudando, mas atrapalhando. Revise os testes: remova testes flaky, otimize dependências, reduza o tempo de compilação.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também