CI para Node.js com GitHub Actions
CI (Integração Contínua) para Node.js executa automaticamente testes, lint e verificação de tipos a cada pull request — impedindo que código quebrado entre no branch principal. Com GitHub Actions, o setup é declarativo em YAML e não exige servidor externo.
Workflow de CI completo para Node.js
Pipeline que roda em cada pull request e push:
yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
ci:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['20', '22'] # testar em múltiplas versões
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Instalar dependências
run: npm ci
- name: TypeScript check
run: npx tsc --noEmit
- name: ESLint
run: npx eslint src/ --ext .ts,.tsx --max-warnings 0
- name: Testes unitários com cobertura
run: npm test -- --coverage --coverageReporters=text --coverageReporters=lcov
- name: Upload cobertura para Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage/lcov.info
- name: Build
run: npm run buildCI com banco de dados (PostgreSQL como service)
Para testes de integração que precisam de banco de dados real:
yaml
jobs:
ci-with-db:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Rodar migrações de teste
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdb
run: npx prisma migrate deploy
- name: Testes de integração
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
NODE_ENV: test
run: npm run test:integrationDica
services no GitHub Actions sobe containers Docker como dependências do job. O health check options garante que o PostgreSQL está pronto antes dos testes começarem.
Configurar ESLint e Prettier no CI
Garanta que lint e formatação são verificados automaticamente:
bash
# package.json — scripts necessários
{
"scripts": {
"lint": "eslint src/ --ext .ts,.tsx",
"lint:fix": "eslint src/ --ext .ts,.tsx --fix",
"format:check": "prettier --check src/",
"format": "prettier --write src/",
"typecheck": "tsc --noEmit",
"test": "jest",
"test:integration": "jest --testPathPattern=integration",
"test:coverage": "jest --coverage"
}
}
# .github/workflows/ci.yml — verificar tudo:
- name: Verificar formatação (Prettier)
run: npm run format:check
- name: Lint (ESLint)
run: npm run lint
- name: Type check (TypeScript)
run: npm run typecheck
# Dica: use husky + lint-staged para rodar antes do commit local:
# npm install -D husky lint-staged
# npx husky initComentar cobertura de testes no PR
Adicione um comentário automático com a cobertura de testes em cada pull request:
yaml
- name: Testes com cobertura
run: npm test -- --coverage --json --outputFile=coverage/jest-results.json
- name: Comentar cobertura no PR
uses: ArtiomTr/jest-coverage-report-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
test-script: npm test
annotations: all
threshold: 80 # falhar se cobertura < 80%
# Ou com geração manual do comentário:
- name: Ler cobertura
id: coverage
run: |
COVERAGE=$(cat coverage/coverage-summary.json | python3 -c "
import sys,json
data = json.load(sys.stdin)
print(data['total']['lines']['pct'])
")
echo "lines=$COVERAGE" >> $GITHUB_OUTPUT
- name: Comentar no PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `📊 Cobertura de testes: **${{ steps.coverage.outputs.lines }}%**`
})Otimizar tempo do CI com cache e paralelismo
Reduza o tempo de execução do CI com estratégias de otimização:
yaml
jobs:
# Rodar lint, typecheck e build em paralelo (sem dependência entre si)
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22', cache: 'npm' }
- run: npm ci
- run: npm run lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22', cache: 'npm' }
- run: npm ci
- run: npm run typecheck
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22', cache: 'npm' }
- run: npm ci
- run: npm test
# Deploy só roda se lint, typecheck E test passarem
deploy:
needs: [lint, typecheck, test]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy para VPS
run: echo "Deploy aqui..."$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.