UNPKG

backend-mcp

Version:

Generador automático de backends con Node.js, Express, Prisma y módulos configurables. Servidor MCP compatible con npx para agentes IA. Soporta PostgreSQL, MySQL, MongoDB y SQLite.

1,258 lines (1,072 loc) 32.3 kB
# 📦 Módulo cicd **Versión:** 1.0.0 **Categoría:** devops **Descripción:** Módulo avanzado de CI/CD con soporte para múltiples proveedores y pipelines complejos ## 📊 Estado del Módulo | Componente | Estado | |------------|--------| | Script de inicialización | Disponible | | Templates | Faltante | | Ejemplos | Faltante | ## 🔗 Dependencias ### Requeridas - `docker` - `git` ### Opcionales - `kubernetes` - `terraform` - `ansible` ## 🤖 Triggers para IA Este módulo se activa automáticamente cuando se detectan las siguientes palabras clave: - **undefined**: undefined - **undefined**: undefined - **undefined**: undefined ## ✨ Características - Multi-provider CI/CD (GitHub, GitLab, Jenkins, Azure DevOps) - Advanced pipeline configuration - Blue-green deployments - Canary releases - Infrastructure as Code - Monitoring and alerting integration - Security scanning - Performance testing ## 📖 Documentación Completa # CI/CD Module Comprehensive Continuous Integration and Continuous Deployment module for MCP Backend framework. ## Features - 🚀 Multi-platform CI/CD pipelines - 🔧 Automated testing and quality gates - 📦 Automated builds and deployments - 🔒 Security scanning and compliance - 📊 Performance testing integration - 🌐 Multi-environment deployments - 🔄 Blue-green and canary deployments - 📈 Monitoring and rollback capabilities - 🛡️ Infrastructure as Code - 📝 Automated documentation ## Supported Platforms - GitHub Actions - GitLab CI/CD - Azure DevOps - Jenkins - CircleCI - AWS CodePipeline - Google Cloud Build ## Configuration ### Environment Variables **General CI/CD Configuration:** - `CI_ENVIRONMENT` - Current environment (development, staging, production) - `BUILD_NUMBER` - Build number from CI system - `GIT_COMMIT` - Git commit hash - `GIT_BRANCH` - Git branch name - `CI_REGISTRY` - Container registry URL - `CI_REGISTRY_USER` - Registry username - `CI_REGISTRY_PASSWORD` - Registry password **Deployment Configuration:** - `DEPLOY_STRATEGY` - Deployment strategy (rolling, blue-green, canary) - `DEPLOY_TIMEOUT` - Deployment timeout in seconds (default: 600) - `ROLLBACK_ENABLED` - Enable automatic rollback (default: true) - `HEALTH_CHECK_URL` - Health check endpoint for deployment validation **Security Configuration:** - `SECURITY_SCAN_ENABLED` - Enable security scanning (default: true) - `VULNERABILITY_THRESHOLD` - Maximum allowed vulnerability level - `CODE_QUALITY_GATE` - Minimum code quality score - `SONAR_TOKEN` - SonarQube authentication token **Notification Configuration:** - `SLACK_WEBHOOK_URL` - Slack webhook for notifications - `TEAMS_WEBHOOK_URL` - Microsoft Teams webhook - `EMAIL_NOTIFICATIONS` - Email addresses for notifications ## GitHub Actions ### Main Workflow ```yaml # .github/workflows/ci-cd.yml name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main] release: types: [published] env: NODE_VERSION: '18' REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: test: name: Test runs-on: ubuntu-latest services: postgres: image: postgres:15 env: POSTGRES_PASSWORD: postgres POSTGRES_DB: test_db options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 redis: image: redis:7 options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 6379:6379 steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run linting run: npm run lint - name: Run type checking run: npm run type-check - name: Run unit tests run: npm run test:unit env: NODE_ENV: test - name: Run integration tests run: npm run test:integration env: NODE_ENV: test DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db REDIS_URL: redis://localhost:6379 - name: Run E2E tests run: npm run test:e2e env: NODE_ENV: test DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db REDIS_URL: redis://localhost:6379 - name: Generate coverage report run: npm run test:coverage - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: file: ./coverage/lcov.info flags: unittests name: codecov-umbrella security: name: Security Scan runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run security audit run: npm audit --audit-level moderate - name: Run Snyk security scan uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high - name: Run CodeQL analysis uses: github/codeql-action/init@v2 with: languages: javascript - name: Perform CodeQL analysis uses: github/codeql-action/analyze@v2 quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run SonarCloud scan uses: SonarSource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build: name: Build runs-on: ubuntu-latest needs: [test, security, quality] outputs: image: ${{ steps.image.outputs.image }} digest: ${{ steps.build.outputs.digest }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image id: build uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - name: Output image id: image run: | echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}" >> $GITHUB_OUTPUT deploy-staging: name: Deploy to Staging runs-on: ubuntu-latest needs: build if: github.ref == 'refs/heads/develop' environment: name: staging url: https://staging.example.com steps: - name: Checkout code uses: actions/checkout@v4 - name: Deploy to staging run: | echo "Deploying ${{ needs.build.outputs.image }} to staging" # Add your staging deployment logic here - name: Run smoke tests run: | echo "Running smoke tests against staging" # Add your smoke test logic here - name: Notify deployment uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} channel: '#deployments' webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} deploy-production: name: Deploy to Production runs-on: ubuntu-latest needs: build if: github.event_name == 'release' environment: name: production url: https://api.example.com steps: - name: Checkout code uses: actions/checkout@v4 - name: Deploy to production run: | echo "Deploying ${{ needs.build.outputs.image }} to production" # Add your production deployment logic here - name: Run health checks run: | echo "Running health checks against production" # Add your health check logic here - name: Notify deployment uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} channel: '#deployments' webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} ``` ### Reusable Workflows ```yaml # .github/workflows/test.yml name: Test on: workflow_call: inputs: node-version: required: false type: string default: '18' environment: required: false type: string default: 'test' secrets: DATABASE_URL: required: true REDIS_URL: required: true jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm test env: NODE_ENV: ${{ inputs.environment }} DATABASE_URL: ${{ secrets.DATABASE_URL }} REDIS_URL: ${{ secrets.REDIS_URL }} ``` ```yaml # .github/workflows/deploy.yml name: Deploy on: workflow_call: inputs: environment: required: true type: string image: required: true type: string strategy: required: false type: string default: 'rolling' secrets: DEPLOY_TOKEN: required: true KUBECONFIG: required: true jobs: deploy: runs-on: ubuntu-latest environment: ${{ inputs.environment }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup kubectl uses: azure/setup-kubectl@v3 with: version: 'latest' - name: Configure kubectl run: | echo "${{ secrets.KUBECONFIG }}" | base64 -d > kubeconfig export KUBECONFIG=kubeconfig - name: Deploy application run: | kubectl set image deployment/myapp myapp=${{ inputs.image }} kubectl rollout status deployment/myapp --timeout=600s - name: Verify deployment run: | kubectl get pods -l app=myapp kubectl get services ``` ## GitLab CI/CD ```yaml # .gitlab-ci.yml stages: - test - security - build - deploy-staging - deploy-production variables: NODE_VERSION: "18" DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: "/certs" REGISTRY: $CI_REGISTRY IMAGE_NAME: $CI_PROJECT_PATH # Test stage test:unit: stage: test image: node:$NODE_VERSION services: - postgres:15 - redis:7 variables: POSTGRES_DB: test_db POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres DATABASE_URL: postgresql://postgres:postgres@postgres:5432/test_db REDIS_URL: redis://redis:6379 before_script: - npm ci script: - npm run lint - npm run type-check - npm run test:unit - npm run test:integration coverage: '/Lines\s*:\s*(\d+\.?\d*)%/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage/cobertura-coverage.xml junit: junit.xml paths: - coverage/ expire_in: 1 week test:e2e: stage: test image: node:$NODE_VERSION services: - postgres:15 - redis:7 variables: POSTGRES_DB: test_db POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres DATABASE_URL: postgresql://postgres:postgres@postgres:5432/test_db REDIS_URL: redis://redis:6379 before_script: - npm ci script: - npm run test:e2e artifacts: when: always paths: - test-results/ expire_in: 1 week # Security stage security:audit: stage: security image: node:$NODE_VERSION before_script: - npm ci script: - npm audit --audit-level moderate - npx snyk test --severity-threshold=high allow_failure: false security:sast: stage: security include: - template: Security/SAST.gitlab-ci.yml security:dependency: stage: security include: - template: Security/Dependency-Scanning.gitlab-ci.yml security:container: stage: security include: - template: Security/Container-Scanning.gitlab-ci.yml dependencies: - build:docker # Build stage build:docker: stage: build image: docker:latest services: - docker:dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - | docker build \ --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ --build-arg VCS_REF=$CI_COMMIT_SHA \ --build-arg VERSION=$CI_COMMIT_TAG \ -t $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA \ -t $REGISTRY/$IMAGE_NAME:latest . - docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHA - docker push $REGISTRY/$IMAGE_NAME:latest only: - main - develop - tags # Deploy stages deploy:staging: stage: deploy-staging image: alpine/helm:latest environment: name: staging url: https://staging.example.com before_script: - kubectl config use-context $KUBE_CONTEXT_STAGING script: - | helm upgrade --install myapp-staging ./helm/myapp \ --namespace staging \ --set image.repository=$REGISTRY/$IMAGE_NAME \ --set image.tag=$CI_COMMIT_SHA \ --set environment=staging \ --wait --timeout=10m - kubectl rollout status deployment/myapp-staging -n staging after_script: - curl -f https://staging.example.com/health || exit 1 only: - develop deploy:production: stage: deploy-production image: alpine/helm:latest environment: name: production url: https://api.example.com before_script: - kubectl config use-context $KUBE_CONTEXT_PRODUCTION script: - | helm upgrade --install myapp ./helm/myapp \ --namespace production \ --set image.repository=$REGISTRY/$IMAGE_NAME \ --set image.tag=$CI_COMMIT_SHA \ --set environment=production \ --wait --timeout=15m - kubectl rollout status deployment/myapp -n production after_script: - curl -f https://api.example.com/health || exit 1 when: manual only: - tags ``` ## Azure DevOps ```yaml # azure-pipelines.yml trigger: branches: include: - main - develop tags: include: - v* pool: vmImage: 'ubuntu-latest' variables: nodeVersion: '18' dockerRegistryServiceConnection: 'myregistry' imageRepository: 'myapp' containerRegistry: 'myregistry.azurecr.io' dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile' tag: '$(Build.BuildId)' stages: - stage: Test displayName: 'Test Stage' jobs: - job: Test displayName: 'Run Tests' steps: - task: NodeTool@0 inputs: versionSpec: $(nodeVersion) displayName: 'Install Node.js' - script: | npm ci npm run lint npm run type-check npm run test:unit displayName: 'Install dependencies and run tests' - task: PublishTestResults@2 inputs: testResultsFormat: 'JUnit' testResultsFiles: 'junit.xml' mergeTestResults: true displayName: 'Publish test results' - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: 'Cobertura' summaryFileLocation: 'coverage/cobertura-coverage.xml' displayName: 'Publish code coverage' - stage: Security displayName: 'Security Stage' dependsOn: Test jobs: - job: SecurityScan displayName: 'Security Scan' steps: - task: NodeTool@0 inputs: versionSpec: $(nodeVersion) displayName: 'Install Node.js' - script: | npm ci npm audit --audit-level moderate displayName: 'Run security audit' - stage: Build displayName: 'Build Stage' dependsOn: Security jobs: - job: Build displayName: 'Build Docker Image' steps: - task: Docker@2 displayName: 'Build and push Docker image' inputs: command: 'buildAndPush' repository: $(imageRepository) dockerfile: $(dockerfilePath) containerRegistry: $(dockerRegistryServiceConnection) tags: | $(tag) latest - stage: DeployStaging displayName: 'Deploy to Staging' dependsOn: Build condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop')) jobs: - deployment: DeployStaging displayName: 'Deploy to Staging' environment: 'staging' strategy: runOnce: deploy: steps: - task: KubernetesManifest@0 displayName: 'Deploy to Kubernetes' inputs: action: 'deploy' kubernetesServiceConnection: 'staging-k8s' namespace: 'staging' manifests: | k8s/deployment.yml k8s/service.yml containers: '$(containerRegistry)/$(imageRepository):$(tag)' - stage: DeployProduction displayName: 'Deploy to Production' dependsOn: Build condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v')) jobs: - deployment: DeployProduction displayName: 'Deploy to Production' environment: 'production' strategy: runOnce: deploy: steps: - task: KubernetesManifest@0 displayName: 'Deploy to Kubernetes' inputs: action: 'deploy' kubernetesServiceConnection: 'production-k8s' namespace: 'production' manifests: | k8s/deployment.yml k8s/service.yml containers: '$(containerRegistry)/$(imageRepository):$(tag)' ``` ## Jenkins Pipeline ```groovy // Jenkinsfile pipeline { agent any environment { NODE_VERSION = '18' DOCKER_REGISTRY = 'myregistry.com' IMAGE_NAME = 'myapp' KUBECONFIG = credentials('kubeconfig') } stages { stage('Checkout') { steps { checkout scm } } stage('Setup') { steps { script { def nodeHome = tool name: "Node-${NODE_VERSION}", type: 'nodejs' env.PATH = "${nodeHome}/bin:${env.PATH}" } sh 'npm ci' } } stage('Test') { parallel { stage('Unit Tests') { steps { sh 'npm run test:unit' } post { always { publishTestResults testResultsPattern: 'junit.xml' publishCoverageGoberturaReports 'coverage/cobertura-coverage.xml' } } } stage('Integration Tests') { steps { sh 'npm run test:integration' } } stage('Lint') { steps { sh 'npm run lint' } } stage('Type Check') { steps { sh 'npm run type-check' } } } } stage('Security') { parallel { stage('Dependency Audit') { steps { sh 'npm audit --audit-level moderate' } } stage('SAST Scan') { steps { script { def scannerHome = tool 'SonarQubeScanner' withSonarQubeEnv('SonarQube') { sh "${scannerHome}/bin/sonar-scanner" } } } } } } stage('Build') { when { anyOf { branch 'main' branch 'develop' tag pattern: 'v\\d+\\.\\d+\\.\\d+', comparator: 'REGEXP' } } steps { script { def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER}") docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-credentials') { image.push() image.push('latest') } } } } stage('Deploy to Staging') { when { branch 'develop' } steps { script { sh """ helm upgrade --install myapp-staging ./helm/myapp \ --namespace staging \ --set image.repository=${DOCKER_REGISTRY}/${IMAGE_NAME} \ --set image.tag=${env.BUILD_NUMBER} \ --set environment=staging \ --wait --timeout=10m """ } } } stage('Deploy to Production') { when { tag pattern: 'v\\d+\\.\\d+\\.\\d+', comparator: 'REGEXP' } steps { input message: 'Deploy to production?', ok: 'Deploy' script { sh """ helm upgrade --install myapp ./helm/myapp \ --namespace production \ --set image.repository=${DOCKER_REGISTRY}/${IMAGE_NAME} \ --set image.tag=${env.BUILD_NUMBER} \ --set environment=production \ --wait --timeout=15m """ } } } } post { always { cleanWs() } success { slackSend( channel: '#deployments', color: 'good', message: " Pipeline succeeded for ${env.JOB_NAME} - ${env.BUILD_NUMBER}" ) } failure { slackSend( channel: '#deployments', color: 'danger', message: " Pipeline failed for ${env.JOB_NAME} - ${env.BUILD_NUMBER}" ) } } } ``` ## Deployment Strategies ### Blue-Green Deployment ```yaml # scripts/blue-green-deploy.yml apiVersion: v1 kind: ConfigMap metadata: name: blue-green-deploy data: deploy.sh: | #!/bin/bash set -e NAMESPACE=${1:-default} IMAGE=${2} CURRENT_COLOR=$(kubectl get service myapp -n $NAMESPACE -o jsonpath='{.spec.selector.color}' || echo "blue") NEW_COLOR=$([ "$CURRENT_COLOR" = "blue" ] && echo "green" || echo "blue") echo "Current color: $CURRENT_COLOR" echo "Deploying to: $NEW_COLOR" # Deploy new version kubectl set image deployment/myapp-$NEW_COLOR myapp=$IMAGE -n $NAMESPACE kubectl rollout status deployment/myapp-$NEW_COLOR -n $NAMESPACE --timeout=600s # Health check kubectl run health-check --rm -i --restart=Never --image=curlimages/curl -- \ curl -f http://myapp-$NEW_COLOR:3000/health # Switch traffic kubectl patch service myapp -n $NAMESPACE -p '{"spec":{"selector":{"color":"'$NEW_COLOR'"}}}' echo "Deployment completed. Traffic switched to $NEW_COLOR" # Optional: Scale down old version after delay sleep 300 kubectl scale deployment myapp-$CURRENT_COLOR --replicas=0 -n $NAMESPACE ``` ### Canary Deployment ```yaml # scripts/canary-deploy.yml apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: name: myapp-canary spec: replicas: 10 strategy: canary: steps: - setWeight: 10 - pause: {duration: 2m} - setWeight: 20 - pause: {duration: 2m} - setWeight: 50 - pause: {duration: 2m} - setWeight: 80 - pause: {duration: 2m} analysis: templates: - templateName: success-rate args: - name: service-name value: myapp trafficRouting: nginx: stableService: myapp-stable canaryService: myapp-canary annotationPrefix: nginx.ingress.kubernetes.io selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 3000 livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 3000 initialDelaySeconds: 5 periodSeconds: 5 ``` ## Monitoring and Observability ### Pipeline Monitoring ```typescript // scripts/pipeline-monitor.ts import { Prometheus } from 'prom-client'; import { WebhookClient } from 'discord.js'; class PipelineMonitor { private metrics = { buildDuration: new Prometheus.Histogram({ name: 'pipeline_build_duration_seconds', help: 'Duration of pipeline builds', labelNames: ['branch', 'status'] }), deploymentFrequency: new Prometheus.Counter({ name: 'pipeline_deployments_total', help: 'Total number of deployments', labelNames: ['environment', 'status'] }), testCoverage: new Prometheus.Gauge({ name: 'pipeline_test_coverage_percent', help: 'Test coverage percentage', labelNames: ['branch'] }) }; async recordBuild(branch: string, duration: number, status: string) { this.metrics.buildDuration .labels(branch, status) .observe(duration); } async recordDeployment(environment: string, status: string) { this.metrics.deploymentFrequency .labels(environment, status) .inc(); } async recordCoverage(branch: string, coverage: number) { this.metrics.testCoverage .labels(branch) .set(coverage); } async sendAlert(message: string, severity: 'info' | 'warning' | 'error') { const webhook = new WebhookClient({ url: process.env.DISCORD_WEBHOOK_URL! }); const color = { info: 0x00ff00, warning: 0xffff00, error: 0xff0000 }[severity]; await webhook.send({ embeds: [{ title: 'Pipeline Alert', description: message, color, timestamp: new Date().toISOString() }] }); } } export const pipelineMonitor = new PipelineMonitor(); ``` ### Quality Gates ```typescript // scripts/quality-gates.ts interface QualityGate { name: string; threshold: number; operator: 'gt' | 'lt' | 'gte' | 'lte' | 'eq'; } class QualityGateChecker { private gates: QualityGate[] = [ { name: 'test_coverage', threshold: 80, operator: 'gte' }, { name: 'code_smells', threshold: 10, operator: 'lte' }, { name: 'vulnerabilities', threshold: 0, operator: 'eq' }, { name: 'bugs', threshold: 0, operator: 'eq' }, { name: 'duplicated_lines_density', threshold: 3, operator: 'lte' } ]; async checkGates(metrics: Record<string, number>): Promise<boolean> { const results = []; for (const gate of this.gates) { const value = metrics[gate.name]; const passed = this.evaluateCondition(value, gate.threshold, gate.operator); results.push({ gate: gate.name, value, threshold: gate.threshold, operator: gate.operator, passed }); console.log(`Quality Gate: ${gate.name} = ${value} ${gate.operator} ${gate.threshold}: ${passed ? 'PASS' : 'FAIL'}`); } const allPassed = results.every(r => r.passed); if (!allPassed) { const failedGates = results.filter(r => !r.passed); throw new Error(`Quality gates failed: ${failedGates.map(g => g.gate).join(', ')}`); } return true; } private evaluateCondition(value: number, threshold: number, operator: string): boolean { switch (operator) { case 'gt': return value > threshold; case 'lt': return value < threshold; case 'gte': return value >= threshold; case 'lte': return value <= threshold; case 'eq': return value === threshold; default: return false; } } } export const qualityGateChecker = new QualityGateChecker(); ``` ## Testing ```typescript // tests/cicd.test.ts import { execSync } from 'child_process'; import { readFileSync } from 'fs'; import yaml from 'js-yaml'; describe('CI/CD Configuration Tests', () => { it('should have valid GitHub Actions workflow', () => { const workflow = readFileSync('.github/workflows/ci-cd.yml', 'utf8'); const parsed = yaml.load(workflow); expect(parsed).toHaveProperty('on'); expect(parsed).toHaveProperty('jobs'); expect(parsed.jobs).toHaveProperty('test'); expect(parsed.jobs).toHaveProperty('build'); }); it('should have valid Dockerfile', () => { expect(() => { execSync('docker build --dry-run .', { stdio: 'pipe' }); }).not.toThrow(); }); it('should have valid Kubernetes manifests', () => { const deployment = readFileSync('k8s/deployment.yml', 'utf8'); const parsed = yaml.load(deployment); expect(parsed.kind).toBe('Deployment'); expect(parsed.spec.template.spec.containers).toHaveLength(1); }); it('should have valid Helm chart', () => { expect(() => { execSync('helm lint ./helm/myapp', { stdio: 'pipe' }); }).not.toThrow(); }); }); ``` ## Dependencies - Docker 20.10+ - Kubernetes 1.20+ - Helm 3.0+ - Node.js 18+ - Git 2.30+ ## Integration - Integrates with all modules for comprehensive testing - Supports multiple deployment platforms - Provides monitoring and alerting capabilities - Includes security scanning and compliance checks - Supports Infrastructure as Code ## Best Practices 1. **Pipeline as Code**: Store all CI/CD configuration in version control 2. **Security First**: Include security scanning in every pipeline 3. **Quality Gates**: Enforce quality standards before deployment 4. **Monitoring**: Monitor pipeline performance and success rates 5. **Rollback Strategy**: Always have a rollback plan 6. **Environment Parity**: Keep environments as similar as possible 7. **Automated Testing**: Test everything automatically 8. **Documentation**: Document deployment processes and runbooks ## License MIT ## 🔗 Enlaces - [Volver al índice de módulos](./README.md) - [Documentación principal](../README.md) - [Código fuente](../../modules/cicd/)