Nesta aula, exploraremos o ecossistema de ferramentas de Integração Contínua (CI), fundamentais para automatizar a construção, teste e deployment de software. Vamos comparar três das soluções mais populares — GitHub Actions, GitLab CI e Jenkins —, entender como os pipelines são acionados (trigger-based), discutir critérios para escolha e analisar exemplos conceituais de configuração.

Ao final, você terá uma base sólida para decidir qual ferramenta se adequa melhor ao seu contexto e será capaz de interpretar pipelines básicos em cada uma delas.

GitHub Actions, GitLab CI, Jenkins (panorama)

GitHub Actions é uma plataforma de CI/CD nativa do GitHub, que permite criar workflows diretamente no repositório. Cada workflow é definido em YAML e pode ser acionado por eventos como push, pull request ou agendamento. É altamente integrado com o ecossistema GitHub e oferece uma vasta gama de ações pré-construídas na marketplace.

GitLab CI é parte do GitLab, uma plataforma DevOps completa. Os pipelines são definidos em um arquivo .gitlab-ci.yml na raiz do repositório. Suporta runners próprios ou compartilhados, e é conhecido por sua flexibilidade e integração com todo o ciclo de vida do DevOps (desde planejamento até monitoramento).

Jenkins é a ferramenta de CI/CD mais antiga e madura, baseada em Java. Diferente das anteriores, não é nativa de um sistema de versionamento específico. Oferece alta customização via plugins (mais de 1800), mas requer mais esforço de configuração e manutenção da infraestrutura. É ideal para ambientes complexos e legados.

Trigger-based

O conceito de trigger-based significa que os pipelines são iniciados automaticamente em resposta a eventos específicos, como um commit em um branch, abertura de pull request, criação de tag, ou até mesmo agendamento temporal (cron). Essa abordagem elimina a necessidade de execução manual, garantindo que cada alteração seja validada de forma consistente.

Em GitHub Actions, os triggers são definidos no campo on do workflow YAML. Por exemplo:

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

No GitLab CI, os triggers são configurados no arquivo .gitlab-ci.yml usando palavras-chave como only ou rules. Exemplo:

job:
  script: echo "Hello"
  only:
    - main

Jenkins utiliza triggers como pollSCM (verificação periódica) ou webhook para reação a eventos. Exemplo de trigger via webhook (configurado na interface ou via pipeline como código):

triggers {
  pollSCM('H/5 * * * *')
}

Esses gatilhos garantem que o pipeline seja executado no momento certo, sem intervenção manual, promovendo a integração contínua.

Escolhendo

A escolha da ferramenta de CI depende de vários fatores: ecossistema existente (GitHub vs GitLab), complexidade dos pipelines, necessidade de customização, recursos da equipe e orçamento. GitHub Actions é excelente para projetos open source e times pequenos que já usam GitHub, pela facilidade de uso e integração. GitLab CI é ideal para organizações que desejam uma plataforma única de DevOps, com forte ênfase em segurança e governança. Jenkins é a escolha para ambientes que exigem máxima flexibilidade e já possuem infraestrutura Java, ou quando há necessidade de plugins específicos não disponíveis nas outras ferramentas.

Além disso, considere a facilidade de manutenção: GitHub Actions e GitLab CI são gerenciados (SaaS) ou auto-hospedados com suporte da comunidade, enquanto Jenkins exige administração dedicada. O custo também é relevante: GitHub Actions oferece minutos gratuitos para repositórios públicos e um limite para privados; GitLab CI tem planos gratuitos com limites; Jenkins é gratuito, mas requer servidor próprio. Avalie também a curva de aprendizado: GitHub Actions e GitLab CI são mais intuitivos para quem já conhece YAML, enquanto Jenkins tem uma curva mais íngreme devido à sua arquitetura baseada em plugins e configuração via interface ou Groovy.

Exemplos conceituais

Vamos ver exemplos conceituais de pipelines simples em cada ferramenta, executando etapas de build e teste.

GitHub Actions: Um workflow que é acionado por push na branch main, instala dependências, executa testes e faz o build.

name: CI
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build
        run: npm run build

GitLab CI: Pipeline equivalente, acionado por push na branch main, com estágio de build e teste.

stages:
  - build
  - test
build-job:
  stage: build
  script:
    - npm install
    - npm run build
  only:
    - main
test-job:
  stage: test
  script:
    - npm test
  only:
    - main

Jenkins: Pipeline declarativo em Groovy, com os mesmos passos. O Jenkinsfile é colocado no repositório.

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }
    triggers {
        pollSCM('H/5 * * * *')
    }
}

Esses exemplos mostram a sintaxe de cada ferramenta. Apesar das diferenças, o conceito central é o mesmo: automatizar a verificação do código a cada mudança.

Boas práticas e observações finais

Independente da ferramenta, algumas boas práticas são essenciais: manter os pipelines rápidos (evitando etapas desnecessárias), usar cache para dependências, versionar os arquivos de configuração (YAML ou Jenkinsfile) junto com o código, e garantir que os pipelines sejam reprodutíveis. Além disso, é importante monitorar a saúde dos pipelines e configurar notificações para falhas. Lembre-se de que a CI é a base para a entrega contínua (CD) e, portanto, deve ser robusta e confiável.

Referências

Exercícios

  1. Explique o que significa um pipeline ser "trigger-based" e dê um exemplo de evento que pode acionar um pipeline no GitHub Actions.

    ✓ Resposta: Trigger-based significa que o pipeline é iniciado automaticamente em resposta a um evento, sem intervenção manual. No GitHub Actions, um exemplo é um push para a branch main: o workflow é acionado automaticamente quando um commit é feito nessa branch.
  2. Cite duas diferenças principais entre Jenkins e GitHub Actions.

    ✓ Resposta: 1) Jenkins é uma ferramenta autogerenciada (requer servidor próprio), enquanto GitHub Actions é um serviço SaaS integrado ao GitHub. 2) Jenkins usa plugins e configuração via interface ou Groovy, enquanto GitHub Actions usa workflows YAML e ações pré-construídas.
  3. No GitLab CI, qual arquivo define os pipelines e qual é a extensão? Dê um exemplo de trigger para executar um job apenas na branch main.

    ✓ Resposta: O arquivo é .gitlab-ci.yml. Exemplo de trigger: only: - main dentro de um job.
  4. Considere um cenário onde sua equipe já utiliza GitHub para versionamento e deseja uma solução de CI com mínima configuração. Qual ferramenta você recomendaria e por quê?

    ✓ Resposta: Recomendaria GitHub Actions, pois é nativo do GitHub, não requer configuração adicional de infraestrutura, e possui integração direta com pull requests e issues. Além disso, oferece minutos gratuitos para repositórios públicos e privados (com limites).
  5. Escreva um pipeline conceitual em Jenkins (Jenkinsfile) que tenha dois estágios: "Build" e "Test", e que seja acionado por polling a cada 5 minutos.

    ✓ Resposta:
    pipeline {
        agent any
        stages {
            stage('Build') {
                steps {
                    sh 'echo "Building..."'
                }
            }
            stage('Test') {
                steps {
                    sh 'echo "Testing..."'
                }
            }
        }
        triggers {
            pollSCM('H/5 * * * *')
        }
    }