CI/CD
Bob continua cometendo erros toda vez que implanta manualmente—esquece de executar migrações, configura variáveis de ambiente incorretamente e faz push de código para produção antes que passe nos testes. Charlie precisa automatizar o CI/CD: testes automáticos ao fazer push de código, preview automático em pull requests, e implantação automática em produção a partir do branch main, tudo com zero intervenção manual.
1. O Que Você Vai Aprender
- Workflow do GitHub Actions: lint → test → build → deploy
- Verificações de Qualidade de Código: ESLint + Prettier + TypeCheck + Cobertura Vitest
- Gerenciamento de Ambientes: development → staging → production
- Estratégia de Implantação: Blue-Green Deployment + Rolling Updates + Rollback
- Preview Automático de PR do MegaShop + Implantação Automática do main
2. Uma História Real de um Administrador
(1) Dor: Erros frequentes durante a implantação manual
Bob implanta o MegaShop manualmente. Os passos são: 1) Clonar o repositório 2) Executar npm install 3) Executar testes (esqueceu) 4) Build 5) Upload 6) Executar migrações (esqueceu) 7) Reiniciar o serviço. Faltar um único passo causa um problema, resultando em uma média de dois incidentes de implantação por mês.
(2) Uma Solução Usando GitHub Actions CI/CD
O processo completo roda automaticamente a cada push:
# .github/workflows/deploy.yml
on: push
jobs:
test: → lint + typecheck + vitest
build: → npm run build
deploy: → docker compose up -d
(3) Benefícios: Zero trabalho manual + Zero acidentes
Testes, build e implantação totalmente automatizados após o push de código; pull requests geram automaticamente ambientes de preview; merges de código no branch main são implantados automaticamente; incidentes de implantação são reduzidos a zero.
3. Workflows do GitHub Actions
(1) Estágios do Pipeline CI/CD
flowchart LR
A[Push / PR] --> B[Lint + TypeCheck]
B --> C[Testes Unitários]
C --> D[Build]
D --> E{Branch?}
E -->|PR| F[Deploy Preview]
E -->|main| G[Deploy Staging]
G --> H[Smoke Test]
H --> I[Deploy Produção]
I --> J[Health Check]
J --> K[Concluído ✅]
(1) ▶ Exemplo: Um Workflow CI Completo
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npx nuxi typecheck
test:
runs-on: ubuntu-latest
needs: lint
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: megashop_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://test:test@localhost:5432/megashop_test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npx prisma migrate deploy
- run: npm run test:coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npx prisma generate
- run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: nuxt-build
path: .output/
Saída:
CI/CD pipeline loaded
Pipeline status: passed
Tests: 12 passed, 0 failed
4. Controle de Qualidade de Código
(1) Configuração de Controle de Qualidade
(1) ▶ Exemplo: Configuração ESLint + Prettier
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/eslint'],
eslint: {
config: {
stylistic: {
indent: 2,
quotes: 'single',
semi: false
}
}
}
})
Saída:
// Execução bem-sucedida
(2) ▶ Exemplo: Scripts do package.json
{
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "nuxi typecheck",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"validate": "npm run lint && npm run typecheck && npm run test"
}
}
Saída:
{
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "nuxi typecheck",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"validate": "npm run lint && npm run typecheck && npm run test"
}
}
(2) Métricas de Controle de Qualidade
| Métrica | Ferramenta | Limite de Acesso | Descrição |
|---|---|---|---|
| Estilo de Código | ESLint | 0 erros | Estilo de Código Consistente |
| Formatação | Prettier | 0 avisos | Auto-formatação |
| Verificação de Tipos | vue-tsc | 0 erros | Segurança de Tipos TypeScript |
| Testes Unitários | Vitest | ≥ 80% cobertura | Cobertura da Lógica Central |
| Testes E2E | Playwright | Todos Passaram | Validação de Fluxos Críticos |
| Tamanho do Bundle | rollup-plugin | < 200 KB gzip | Prevenir inchaço de tamanho |
5. Gerenciamento Multi-Ambiente
(1) ▶ Exemplo: Arquivo de Configuração de Ambiente
# .env.development
DATABASE_URL=postgresql://dev:dev@localhost:5432/megashop_dev
REDIS_URL=redis://localhost:6379
JWT_ACCESS_SECRET=dev-access-secret
# .env.staging
DATABASE_URL=postgresql://staging:xxx@staging-db.internal:5432/megashop_staging
REDIS_URL=redis://staging-redis.internal:6379
JWT_ACCESS_SECRET=${{ secrets.STAGING_JWT_SECRET }}
# .env.production
DATABASE_URL=postgresql://prod:xxx@prod-db.internal:5432/megashop
REDIS_URL=redis://prod-redis.internal:6379
JWT_ACCESS_SECRET=${{ secrets.PROD_JWT_SECRET }}
(2) ▶ Exemplo: Workflow de Implantação Staging
# .github/workflows/deploy-staging.yml
name: Deploy Staging
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
needs: [lint, test]
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: |
ssh staging-server << 'EOF'
cd /opt/megashop
git pull origin main
docker compose up -d --build
docker compose exec web npx prisma migrate deploy
EOF
- name: Smoke test
run: |
sleep 10
curl -f https://staging.megashop.com/api/products?limit=1 || exit 1
- name: Notify team
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{"text": "Staging deployment failed!"}
Saída:
CONTAINER ID IMAGE STATUS PORTS
abc123 nginx:latest Up 2 hours 0.0.0.0:80->80/tcp
(1) Comparação de Ambientes
| Ambiente | Finalidade | Banco de Dados | Método de Implantação | Permissões de Acesso |
|---|---|---|---|---|
| development | desenvolvimento local | PostgreSQL local | npm run dev | desenvolvedores |
| staging | Teste de Integração | PostgreSQL Independente | Automatizado (push main) | Equipe |
| production | Ambiente de Produção | PostgreSQL de Produção | Automático (tag/release) | Todos os Usuários |
6. Estratégia de Implantação
(1) Comparação de Estratégias de Implantação
| Estratégia | Princípio | Downtime | Velocidade de Rollback | Complexidade |
|---|---|---|---|---|
| Substituição Direta | Desligar e Ligar | 🔴 Sim (5-30 s) | 🟡 Redeploy | 🟢 Simples |
| Blue-Green Deployment | Troca Entre Dois Ambientes | 🟢 Nenhum | 🟢 Troca em Segundos | 🟡 Média |
| Rolling Update | Substituir Instâncias Uma a Uma | 🟢 Nenhum | 🟡 Reverter Uma a Uma | 🟡 Média |
| Canary Release | Validar com Pequena Base de Usuários Primeiro | 🟢 Nenhum | 🟢 Reverter Imediatamente | 🔴 Complexa |
(1) ▶ Exemplo: Script de Blue-Green Deployment
#!/bin/bash
# deploy-blue-green.sh
CURRENT=$(docker compose ps --format '{{.Name}}' | grep -o 'blue\|green' | head -1)
if [ "$CURRENT" = "blue" ]; then
NEXT="green"
else
NEXT="blue"
fi
echo "Deploying to $NEXT environment..."
# Construir e iniciar próximo ambiente
docker compose -f docker-compose.yml -f docker-compose.$NEXT.yml up -d --build
# Aguardar health check
for i in {1..30}; do
if curl -sf http://localhost:3001/health; then
echo "Health check passed"
break
fi
sleep 2
done
# Trocar Nginx para novo ambiente
sed "s/$CURRENT/$NEXT/g" nginx.conf > /tmp/nginx.conf
docker compose exec nginx nginx -s reload
echo "Switched from $CURRENT to $NEXT"
Saída:
CONTAINER ID IMAGE STATUS
abc123 latest Up 2 hours
7. Exemplo Completo: O Processo CI/CD Completo do MegaShop
# .github/workflows/deploy-production.yml
name: Deploy Production
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t megashop:${{ github.sha }} .
- name: Push to registry
run: |
docker tag megashop:${{ github.sha }} ghcr.io/megashop/megashop:latest
echo ${{ secrets.GHCR_TOKEN }} | docker login ghcr.io -u $ --password-stdin
docker push ghcr.io/megashop/megashop:latest
- name: Deploy to production
run: |
ssh prod-server << EOF
cd /opt/megashop
docker pull ghcr.io/megashop/megashop:latest
docker compose up -d --no-build
docker compose exec web npx prisma migrate deploy
EOF
- name: Health check
run: |
for i in {1..10}; do
if curl -sf https://megashop.com/api/health; then exit 0; fi
sleep 5
done
exit 1
- name: Rollback on failure
if: failure()
run: |
ssh prod-server << EOF
cd /opt/megashop
docker compose down
docker tag megashop:previous megashop:latest
docker compose up -d
EOF
❓ Perguntas Frequentes
prisma migrate deploy (que apenas aplica migrações existentes e não cria novas). Durante o desenvolvimento, use prisma migrate dev para criar arquivos de migração e commitá-los no Git.git revert e redeploy. Para Docker, reinicie usando a tag de imagem anterior. Para PM2, use pm2 stop e depois inicie a versão antiga. Para automatizar rollbacks, adicione lógica de tratamento de health checks falhos ao script de implantação.runtimeConfig são apenas server-side. No CI, referencie-os usando ${{ secrets.XXX }}.📖 Resumo
- Implementando um pipeline totalmente automatizado (lint → test → build → deploy) usando GitHub Actions
- Requisitos de Qualidade de Código: ESLint + TypeCheck + Vitest ≥ 80% de cobertura
- Gerenciamento de três ambientes: development (local) → staging (teste de integração) → production (produção)
- Blue-green deployment garante zero downtime; rollback automático quando health check falha
- MegaShop: Preview automático para PRs + staging automático para "main" + implantação automática em produção para "release"
📝 Exercícios
- Exercício Básico (Dificuldade: ⭐): Crie um workflow CI no GitHub Actions que execute automaticamente linting, verificação de tipos e testes quando um commit for feito push.
- Exercício Avançado (Dificuldade ⭐⭐): Adicione implantação automática para staging—quando o branch main receber push, implantar automaticamente no servidor de staging e executar um smoke test após a implantação.
- Desafio (Dificuldade: ⭐⭐⭐): Implemente um script de blue-green deployment + rollback automático—trocar automaticamente de volta para a versão anterior quando um health check falhar
---|



