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
Markdown
# 📦 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/)