CI/CD desmistificado: automatizando testes e deploys com GitHub Actions
1. O que é CI/CD e por que automatizar?
Integração Contínua (CI) e Entrega Contínua (CD) são práticas fundamentais no desenvolvimento moderno de software. CI consiste em integrar alterações de código em um repositório compartilhado várias vezes ao dia, executando testes automatizados para validar cada mudança. CD vai além, automatizando o processo de deploy para ambientes de produção ou staging após a aprovação dos testes.
Os benefícios práticos são significativos. A redução de erros manuais ocorre porque tarefas repetitivas como build, teste e deploy são executadas por scripts, eliminando a inconsistência humana. O feedback rápido permite que desenvolvedores identifiquem problemas minutos após um commit, não dias depois. Deploys confiáveis garantem que apenas código testado chegue à produção.
Diferente de ferramentas tradicionais como Jenkins (que requer servidores dedicados) ou GitLab CI (que precisa de runners próprios), o GitHub Actions é nativo da plataforma GitHub. Isso elimina a necessidade de infraestrutura externa, integra-se perfeitamente com pull requests e oferece 2000 minutos gratuitos por mês para contas pessoais.
2. Primeiros passos com GitHub Actions
Um workflow no GitHub Actions é composto por:
- Eventos: gatilhos que iniciam o workflow (push, pull_request, schedule)
- Jobs: unidades de trabalho executadas em runners (máquinas virtuais)
- Steps: comandos individuais dentro de um job
- Runners: servidores que executam os jobs (ubuntu-latest, windows-latest, macos-latest)
Para criar seu primeiro workflow, crie o diretório .github/workflows/ no repositório e adicione um arquivo YAML. Exemplo básico:
name: CI Básico
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Saudacao
run: echo "Workflow iniciado com sucesso!"
Os gatilhos comuns incluem: push (qualquer commit), pull_request (abertura/sincronização de PR), schedule (execução agendada via cron) e workflow_dispatch (execução manual pela interface).
3. Automatizando testes com CI
A configuração de jobs de teste varia conforme a linguagem. Exemplo para Node.js:
name: Testes Node.js
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
steps:
- uses: actions/checkout@v4
- name: Usar Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
Para Python, a matriz permite testar em diferentes versões e sistemas operacionais:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install pytest
- run: pytest
Serviços externos como bancos de dados podem ser configurados via services:
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: senha_teste
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- run: npm test
4. Estratégias de deploy automatizado (CD)
O deploy contínuo envia automaticamente para produção após testes bem-sucedidos. O deploy manual com aprovação usa ambientes (environments) que exigem revisão humana antes de prosseguir.
Exemplo de deploy para GitHub Pages:
name: Deploy para GitHub Pages
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- name: Build
run: npm ci && npm run build
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './dist'
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
Para deploy via SSH em servidor próprio:
- name: Deploy via SSH
uses: easingthemes/ssh-deploy@v4
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
remote-host: ${{ secrets.REMOTE_HOST }}
remote-user: ${{ secrets.REMOTE_USER }}
source: './dist/'
target: '/var/www/html/'
Segredos (secrets) são configurados em Settings > Secrets and variables > Actions do repositório.
5. Otimização de workflows e boas práticas
Reutilização de código com actions reutilizáveis:
# .github/actions/setup-node/action.yml
name: 'Setup Node'
description: 'Configura Node.js com cache'
inputs:
node-version:
required: true
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci
shell: bash
Cache de dependências acelera execuções:
- uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Tratamento de falhas com notificações:
- name: Notificar falha
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: '{"text":"Workflow falhou em ${{ github.repository }}"}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
6. Monitoramento e manutenção contínua
Os logs de execução são acessíveis na aba "Actions" do repositório. Artefatos (arquivos gerados durante o workflow) podem ser baixados via interface. O status de execução aparece nos commits e pull requests.
Alertas podem ser configurados para Slack, Discord ou e-mail. Exemplo com Discord:
- name: Notificar Discord
if: failure()
uses: Ilshidur/action-discord@master
with:
args: 'Workflow falhou em {{ EVENT_PAYLOAD.repository.full_name }}'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
Manter actions de terceiros atualizadas é crucial. Use o Dependabot para atualizar automaticamente:
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
7. CI/CD no contexto do desenvolvimento 100% na nuvem
O GitHub Actions integra-se nativamente com GitHub Codespaces. Ao abrir um codespace, o ambiente de desenvolvimento já está configurado com as mesmas ferramentas do CI. O Gitpod também oferece integração, permitindo testar workflows antes do push.
Para testar workflows localmente, use a ferramenta act:
# Instalação
curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Executar workflow localmente
act push
O fluxo completo na nuvem funciona assim: desenvolvedor faz commit no GitHub Codespaces ou Gitpod → gatilho do workflow → testes automáticos → deploy para produção. Tudo sem sair do navegador.
Referências
- Documentação oficial do GitHub Actions — Guia completo sobre workflows, runners, eventos e boas práticas
- GitHub Actions Marketplace — Catálogo de actions pré-construídas para deploy, teste, notificação e mais
- Tutorial: CI/CD com Node.js e GitHub Actions — Passo a passo para configurar testes em projetos Node.js
- Guia de deploy contínuo com GitHub Actions — Estratégias de deploy, ambientes e proteção de branches
- Repositório oficial do act (teste local de workflows) — Ferramenta para executar GitHub Actions localmente sem push
- Blog: Otimizando workflows com cache e matrizes — Dicas avançadas de performance e organização
- Documentação do Dependabot para GitHub Actions — Como manter actions de terceiros atualizadas automaticamente