Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 49 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,48 @@ on:
pull_request:
branches: [main]

# Cancela runs anteriores do mesmo PR ou branch para economizar minutos de CI.
# Em push para main, cada run é independente (group usa o SHA para não cancelar).
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions: {}

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
# ─── Build ────────────────────────────────────────────────────────────────────
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Compilar projeto
run: pnpm build

# ─── Qualidade estática ────────────────────────────────────────────────────
qualidade:
name: Lint e Typecheck
runs-on: ubuntu-latest
needs: build
timeout-minutes: 10
permissions:
contents: read

Expand Down Expand Up @@ -43,6 +75,7 @@ jobs:
name: Testes Unitários
runs-on: ubuntu-latest
needs: qualidade
timeout-minutes: 10
permissions:
contents: read

Expand All @@ -67,6 +100,7 @@ jobs:
name: Testes E2E
runs-on: ubuntu-latest
needs: testes-unitarios
timeout-minutes: 10
permissions:
contents: read

Expand Down Expand Up @@ -120,11 +154,12 @@ jobs:
- name: Testes E2E
run: pnpm exec vitest run src/testes/e2e

# ─── Cobertura (suite completa: unitários + E2E) ───────────────────────────
# ─── Cobertura + Quality Gate (suite completa: unitários + E2E) ───────────
cobertura:
name: Cobertura de Testes
name: Cobertura e Quality Gate
runs-on: ubuntu-latest
needs: testes-e2e
timeout-minutes: 10
permissions:
contents: read

Expand Down Expand Up @@ -175,11 +210,21 @@ jobs:
- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Gerar relatório de cobertura
# O próprio vitest --coverage falha o processo se os thresholds configurados
# em vitest.config.ts não forem atingidos — este é o quality gate explícito.
- name: Gerar relatório de cobertura (quality gate)
run: pnpm test:coverage

- name: Publicar cobertura
- name: Publicar cobertura no Codecov
uses: codecov/codecov-action@v5
with:
files: ./coverage/lcov.info
fail_ci_if_error: false

- name: Upload do relatório de cobertura como artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: relatorio-cobertura-${{ github.run_number }}
path: coverage/
retention-days: 7
291 changes: 291 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
name: Release

on:
push:
tags:
- 'v*.*.*'

permissions: {}

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
# ─── Build ────────────────────────────────────────────────────────────────────
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Compilar projeto
run: pnpm build

# ─── Qualidade estática ────────────────────────────────────────────────────
qualidade:
name: Lint e Typecheck
runs-on: ubuntu-latest
needs: build
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm lint

- name: Typecheck
run: pnpm typecheck

# ─── Testes Unitários ─────────────────────────────────────────────────────
testes-unitarios:
name: Testes Unitários
runs-on: ubuntu-latest
needs: qualidade
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Testes unitários
run: pnpm exec vitest run src/testes/unitarios

# ─── Testes E2E (MongoDB + Redis) ─────────────────────────────────────────
testes-e2e:
name: Testes E2E
runs-on: ubuntu-latest
needs: testes-unitarios
timeout-minutes: 10
permissions:
contents: read

services:
mongodb:
image: mongo:8.0
env:
MONGO_INITDB_ROOT_USERNAME: administrador
MONGO_INITDB_ROOT_PASSWORD: 1qaz2sx12
ports:
- 27017:27017
options: >-
--health-cmd "mongosh --eval 'db.runCommand({ ping: 1 })'"
--health-interval 10s
--health-timeout 5s
--health-retries 5

redis:
image: redis:8
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379

env:
MONGO_URI: mongodb://administrador:1qaz2sx12@localhost:27017/bem-vindo-testes?authSource=admin
REDIS_URL: redis://localhost:6379
NODE_ENV: test
JWT_SECRETO: jwt-secreto-de-teste-com-pelo-menos-32-chars
JWT_EXPIRACAO_ACCESS: 1h
JWT_EXPIRACAO_REFRESH: 7d
PORTA: 3000
TZ: America/Sao_Paulo

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Testes E2E
run: pnpm exec vitest run src/testes/e2e

# ─── Cobertura + Quality Gate ─────────────────────────────────────────────
cobertura:
name: Cobertura e Quality Gate
runs-on: ubuntu-latest
needs: testes-e2e
timeout-minutes: 10
permissions:
contents: read

services:
mongodb:
image: mongo:8.0
env:
MONGO_INITDB_ROOT_USERNAME: administrador
MONGO_INITDB_ROOT_PASSWORD: 1qaz2sx12
ports:
- 27017:27017
options: >-
--health-cmd "mongosh --eval 'db.runCommand({ ping: 1 })'"
--health-interval 10s
--health-timeout 5s
--health-retries 5

redis:
image: redis:8
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379

env:
MONGO_URI: mongodb://administrador:1qaz2sx12@localhost:27017/bem-vindo-testes?authSource=admin
REDIS_URL: redis://localhost:6379
NODE_ENV: test
JWT_SECRETO: jwt-secreto-de-teste-com-pelo-menos-32-chars
JWT_EXPIRACAO_ACCESS: 1h
JWT_EXPIRACAO_REFRESH: 7d
PORTA: 3000
TZ: America/Sao_Paulo

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

- name: Gerar relatório de cobertura (quality gate)
run: pnpm test:coverage

- name: Upload do relatório de cobertura como artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: relatorio-cobertura-${{ github.ref_name }}
path: coverage/
retention-days: 30

# ─── Scan de segurança ────────────────────────────────────────────────────
security-scan:
name: Scan de Segurança
runs-on: ubuntu-latest
needs: cobertura
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências
run: pnpm install --frozen-lockfile

# Falha o pipeline em vulnerabilidades de severidade high ou critical.
- name: Auditoria de dependências
run: pnpm audit --audit-level=high

# ─── Artifact de produção ─────────────────────────────────────────────────
artifact-build:
name: Artifact de Produção
runs-on: ubuntu-latest
needs: security-scan
timeout-minutes: 10
permissions:
contents: read

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Instalar dependências (somente produção)
run: pnpm install --frozen-lockfile --prod

- name: Compilar projeto
run: pnpm build

- name: Upload do artifact de produção
uses: actions/upload-artifact@v4
with:
name: dist-${{ github.ref_name }}
path: dist/
retention-days: 30

# ─── Aprovação manual antes de produção ───────────────────────────────────
aprovacao-producao:
name: Aprovacao para Producao
runs-on: ubuntu-latest
needs: artifact-build
timeout-minutes: 10
environment: producao
permissions:
contents: read

steps:
- name: Release ${{ github.ref_name }} aprovado para producao
run: |
echo "Tag: ${{ github.ref_name }}"
echo "Commit: ${{ github.sha }}"
echo "Aprovado por: ${{ github.actor }}"
echo "Release liberado para producao."
Loading
Loading