# ═══════════════════════════════════════════════════════════════════════════════ # INVENTARIO DE PIPELINES CI/CD - NEXUS WORKSPACE # ═══════════════════════════════════════════════════════════════════════════════ # # Version: 1.0.0 # Fecha: 2026-01-04 # Responsable: @PERFIL_CICD_SPECIALIST # Proposito: Registro centralizado de pipelines y configuraciones CI/CD # # ═══════════════════════════════════════════════════════════════════════════════ version: "1.0.0" fecha_actualizacion: "2026-01-04" responsable: "@PERFIL_CICD_SPECIALIST" # ───────────────────────────────────────────────────────────────────────────────── # PLATAFORMA CI/CD # ───────────────────────────────────────────────────────────────────────────────── plataforma: principal: tipo: "Jenkins" version: "2.4xx LTS" url: "https://jenkins.isem.dev" acceso: metodo: "LDAP/Local" admin: "${JENKINS_ADMIN_USER}" alternativa: tipo: "GitHub Actions" uso: "Proyectos en GitHub, builds de PR" limite: "2000 min/mes (free tier)" registro_imagenes: tipo: "GitHub Container Registry" url: "ghcr.io/isem" alternativa: "Docker Hub" # ───────────────────────────────────────────────────────────────────────────────── # PIPELINES POR PROYECTO # ───────────────────────────────────────────────────────────────────────────────── pipelines: # ═══════════════════════════════════════════════════════════════════════════════ # GAMILIT # ═══════════════════════════════════════════════════════════════════════════════ gamilit: repositorio: "https://github.com/isem/gamilit" tipo_proyecto: "monorepo (apps/backend, apps/frontend)" pipelines: # Pipeline principal - Backend - nombre: "gamilit-backend" tipo: "Jenkins Pipeline" jenkinsfile: "apps/backend/Jenkinsfile" triggers: - tipo: "push" branch: "develop" accion: "build + deploy staging" - tipo: "push" branch: "main" accion: "build + deploy production (manual approval)" - tipo: "pull_request" accion: "build + test only" stages: - nombre: "Checkout" descripcion: "Clonar repositorio" - nombre: "Install" descripcion: "npm ci" - nombre: "Lint" descripcion: "npm run lint" - nombre: "Test" descripcion: "npm run test:cov" - nombre: "Build" descripcion: "npm run build" - nombre: "Docker Build" descripcion: "docker build -t gamilit-backend:${BUILD_NUMBER}" - nombre: "Push Registry" descripcion: "docker push ghcr.io/isem/gamilit-backend" - nombre: "Deploy Staging" descripcion: "SSH + docker-compose up" condicion: "branch == develop" - nombre: "Deploy Production" descripcion: "SSH + docker-compose up" condicion: "branch == main AND manual approval" artifacts: - "coverage/lcov-report/" - "dist/" notificaciones: exito: ["slack:#gamilit-deploys"] fallo: ["slack:#gamilit-deploys", "email:devops@isem.dev"] # Pipeline Frontend - nombre: "gamilit-frontend" tipo: "Jenkins Pipeline" jenkinsfile: "apps/frontend/Jenkinsfile" triggers: - tipo: "push" branch: "develop" - tipo: "push" branch: "main" stages: - nombre: "Checkout" - nombre: "Install" descripcion: "npm ci" - nombre: "Lint" descripcion: "npm run lint" - nombre: "Test" descripcion: "npm run test" - nombre: "Build" descripcion: "npm run build" env: "VITE_API_URL=https://api.gamilit.com" - nombre: "Deploy" descripcion: "rsync to nginx folder" artifacts: - "dist/" # Pipeline Database Migrations - nombre: "gamilit-migrations" tipo: "Jenkins Pipeline" jenkinsfile: "apps/database/Jenkinsfile" triggers: - tipo: "manual" descripcion: "Solo se ejecuta manualmente" stages: - nombre: "Checkout" - nombre: "Backup Database" descripcion: "pg_dump antes de migrar" - nombre: "Run Migrations" descripcion: "npm run migration:run" - nombre: "Verify" descripcion: "npm run migration:status" approval: requerido: true aprobadores: ["tech-lead", "dba"] github_actions: - nombre: "PR Checks" archivo: ".github/workflows/pr-checks.yml" triggers: ["pull_request"] jobs: - "lint" - "test" - "build" # ═══════════════════════════════════════════════════════════════════════════════ # TRADING PLATFORM # ═══════════════════════════════════════════════════════════════════════════════ trading_platform: repositorio: "https://github.com/isem/trading-platform" tipo_proyecto: "monorepo (apps/trading-api, apps/trading-ml, apps/trading-frontend)" pipelines: # API Backend - nombre: "trading-api" tipo: "Jenkins Pipeline" jenkinsfile: "apps/trading-api/Jenkinsfile" triggers: - tipo: "push" branch: "develop" stages: - nombre: "Checkout" - nombre: "Install" - nombre: "Lint" - nombre: "Test" - nombre: "Build" - nombre: "Docker Build" - nombre: "Deploy Staging" # ML Service - nombre: "trading-ml" tipo: "Jenkins Pipeline" jenkinsfile: "apps/trading-ml/Jenkinsfile" triggers: - tipo: "push" branch: "develop" paths: ["apps/trading-ml/**"] stages: - nombre: "Checkout" - nombre: "Setup Python" descripcion: "Python 3.11, virtualenv" - nombre: "Install Dependencies" descripcion: "pip install -r requirements.txt" - nombre: "Lint" descripcion: "ruff check, mypy" - nombre: "Test" descripcion: "pytest --cov" - nombre: "Build Docker" descripcion: "docker build con CUDA support si aplica" - nombre: "Deploy" descripcion: "docker-compose up trading-ml" artifacts: - "coverage/" - "models/" # Frontend - nombre: "trading-frontend" tipo: "Jenkins Pipeline" jenkinsfile: "apps/trading-frontend/Jenkinsfile" stages: - nombre: "Checkout" - nombre: "Install" - nombre: "Lint" - nombre: "Test" - nombre: "Build" - nombre: "Deploy" github_actions: - nombre: "ML Model Training" archivo: ".github/workflows/train-model.yml" triggers: ["workflow_dispatch", "schedule:weekly"] descripcion: "Entrenamiento programado de modelos" # ═══════════════════════════════════════════════════════════════════════════════ # ERP SUITE # ═══════════════════════════════════════════════════════════════════════════════ erp_suite: repositorio: "https://github.com/isem/erp-suite" tipo_proyecto: "suite con verticales" estado: "en desarrollo" pipelines: - nombre: "erp-core" tipo: "Jenkins Pipeline" estado: "planificado" notas: "Pipeline base para el core" - nombre: "erp-vertical-template" tipo: "Jenkins Pipeline" estado: "planificado" notas: "Template para pipelines de verticales" # ───────────────────────────────────────────────────────────────────────────────── # CONFIGURACION DE JENKINS # ───────────────────────────────────────────────────────────────────────────────── jenkins_config: credenciales: - id: "github-token" tipo: "Secret text" descripcion: "Personal Access Token para GitHub" usado_en: ["checkout", "status updates"] - id: "docker-registry" tipo: "Username with password" descripcion: "Credenciales para ghcr.io" usado_en: ["docker push"] - id: "ssh-deploy-key" tipo: "SSH Username with private key" descripcion: "Llave SSH para despliegue" usado_en: ["deploy to servers"] - id: "slack-webhook" tipo: "Secret text" descripcion: "Webhook para notificaciones Slack" usado_en: ["post-build notifications"] - id: "sonar-token" tipo: "Secret text" descripcion: "Token de SonarQube" usado_en: ["code analysis"] shared_libraries: - nombre: "nexus-pipeline-lib" repositorio: "https://github.com/isem/jenkins-shared-lib" descripcion: "Funciones compartidas para pipelines" funciones: - "buildNodeApp()" - "buildPythonApp()" - "deployToServer()" - "notifySlack()" - "dockerBuildPush()" agents: - nombre: "built-in" tipo: "master" labels: ["master"] executors: 2 - nombre: "docker-agent" tipo: "Docker Cloud" image: "jenkins/inbound-agent" labels: ["docker", "linux"] - nombre: "node-agent" tipo: "Docker Cloud" image: "node:20-alpine" labels: ["node", "frontend", "backend"] - nombre: "python-agent" tipo: "Docker Cloud" image: "python:3.11-slim" labels: ["python", "ml"] # ───────────────────────────────────────────────────────────────────────────────── # GITHUB ACTIONS SHARED WORKFLOWS # ───────────────────────────────────────────────────────────────────────────────── github_actions_shared: repositorio: "isem/.github" workflows_reusables: - nombre: "node-ci.yml" descripcion: "CI para proyectos Node.js" inputs: - "node-version" - "working-directory" steps: - "checkout" - "setup-node" - "npm ci" - "npm run lint" - "npm run test" - "npm run build" - nombre: "python-ci.yml" descripcion: "CI para proyectos Python" inputs: - "python-version" - "working-directory" steps: - "checkout" - "setup-python" - "pip install" - "ruff check" - "pytest" - nombre: "docker-build-push.yml" descripcion: "Build y push de imagen Docker" inputs: - "image-name" - "dockerfile-path" - "build-args" # ───────────────────────────────────────────────────────────────────────────────── # QUALITY GATES # ───────────────────────────────────────────────────────────────────────────────── quality_gates: lint: obligatorio: true herramientas: node: "eslint" python: "ruff" umbral: "0 errores" tests: obligatorio: true cobertura_minima: backend: 80 frontend: 70 ml: 75 umbral: "100% tests passing" build: obligatorio: true umbral: "build exitoso" security: herramienta: "Snyk / npm audit" umbral: "0 vulnerabilidades criticas" obligatorio_para: ["produccion"] code_analysis: herramienta: "SonarQube" url: "https://sonar.isem.dev" metricas: - "Bugs: 0" - "Vulnerabilities: 0" - "Code Smells: < 50" - "Coverage: > 80%" - "Duplications: < 3%" # ───────────────────────────────────────────────────────────────────────────────── # AMBIENTES DE DEPLOYMENT # ───────────────────────────────────────────────────────────────────────────────── ambientes: development: descripcion: "Ambiente local de desarrolladores" deploy: "manual (docker-compose up)" datos: "seeds locales" staging: descripcion: "Pre-produccion para QA" url: "*.staging.isem.dev" deploy: "automatico en merge a develop" datos: "copia sanitizada de prod" approval: false production: descripcion: "Ambiente productivo" url: "*.isem.dev, dominios personalizados" deploy: "automatico en merge a main + approval" datos: "datos reales" approval: true aprobadores: ["tech-lead", "product-owner"] # ───────────────────────────────────────────────────────────────────────────────── # ROLLBACK # ───────────────────────────────────────────────────────────────────────────────── rollback: estrategia: "docker image tags" procedimiento: automatico: trigger: "health check failed after deploy" accion: "revert to previous image tag" tiempo_deteccion: "2 minutos" manual: comando: "docker-compose down && docker-compose up -d --pull=always {previous_tag}" script: "/opt/scripts/rollback.sh {project} {version}" historial: retencion_imagenes: "10 ultimas versiones" retencion_backups_db: "7 dias" # ───────────────────────────────────────────────────────────────────────────────── # SECRETOS EN CI/CD # ───────────────────────────────────────────────────────────────────────────────── secretos_cicd: jenkins: almacenamiento: "Jenkins Credentials Store" tipos_permitidos: - "Secret text" - "Username with password" - "SSH Username with private key" - "Certificate" github_actions: almacenamiento: "GitHub Secrets" niveles: - "Repository secrets" - "Environment secrets" - "Organization secrets" politicas: - "Nunca hardcodear secretos en Jenkinsfile o workflows" - "Usar credentialId para inyectar en runtime" - "Rotar secretos trimestralmente" - "Auditar acceso a secretos mensualmente" # ───────────────────────────────────────────────────────────────────────────────── # METRICAS DE CI/CD # ───────────────────────────────────────────────────────────────────────────────── metricas: a_trackear: - nombre: "Build Success Rate" objetivo: "> 95%" calculo: "builds exitosos / total builds" - nombre: "Mean Time to Recovery" objetivo: "< 30 minutos" calculo: "tiempo desde fallo hasta fix desplegado" - nombre: "Deployment Frequency" objetivo: "diario" calculo: "deploys a produccion por semana" - nombre: "Lead Time" objetivo: "< 1 dia" calculo: "commit a produccion" - nombre: "Change Failure Rate" objetivo: "< 5%" calculo: "deploys que requieren rollback" dashboard: "https://jenkins.isem.dev/metrics" # ───────────────────────────────────────────────────────────────────────────────── # REFERENCIAS # ───────────────────────────────────────────────────────────────────────────────── referencias: perfil_responsable: "@PERFIL_CICD_SPECIALIST" production_inventory: "orchestration/inventarios/PRODUCTION-INVENTORY.yml" jenkins_shared_lib: "https://github.com/isem/jenkins-shared-lib" github_workflows: ".github/workflows/" # ═══════════════════════════════════════════════════════════════════════════════ # FIN DE INVENTARIO # ═══════════════════════════════════════════════════════════════════════════════