Claude Code Plugins

Community-maintained marketplace

Feedback

deployment-automation

@Tek-Fly/print-craft-ai
0
0

Expertise in CI/CD pipelines, automated deployments, and release management

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name deployment-automation
version 1.0.0
description Expertise in CI/CD pipelines, automated deployments, and release management
author PrintCraft AI Team
tags deployment, ci/cd, automation, devops

Deployment Automation Skill

Overview

This skill provides comprehensive deployment automation capabilities including CI/CD pipeline design, multi-environment deployments, rollback strategies, and release orchestration for PrintCraft AI.

Core Competencies

1. CI/CD Pipeline Design

GitHub Actions Workflow

# .github/workflows/main-pipeline.yml
name: PrintCraft AI - Main Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  release:
    types: [created]

env:
  FLUTTER_VERSION: '3.16.0'
  NODE_VERSION: '18'
  DOCKER_BUILDKIT: 1

jobs:
  # Detect what changed
  changes:
    runs-on: ubuntu-latest
    outputs:
      flutter: ${{ steps.filter.outputs.flutter }}
      backend: ${{ steps.filter.outputs.backend }}
      infrastructure: ${{ steps.filter.outputs.infrastructure }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            flutter:
              - 'apps/pod-app/**'
              - 'packages/@appyfly/ui/**'
            backend:
              - 'services/**'
              - 'packages/@appyfly/core/**'
            infrastructure:
              - 'infrastructure/**'
              - '.github/workflows/**'

  # Quality gates
  quality-checks:
    needs: changes
    runs-on: ubuntu-latest
    strategy:
      matrix:
        check: [lint, test, security, sonar]
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup environment
        uses: ./.github/actions/setup-environment
        with:
          flutter: ${{ needs.changes.outputs.flutter }}
          node: ${{ needs.changes.outputs.backend }}
      
      - name: Run ${{ matrix.check }}
        run: |
          case "${{ matrix.check }}" in
            lint)
              ./scripts/lint-all.sh
              ;;
            test)
              ./scripts/test-all.sh --coverage
              ;;
            security)
              ./scripts/security-scan.sh
              ;;
            sonar)
              ./scripts/sonar-analysis.sh
              ;;
          esac

  # Build artifacts
  build:
    needs: [changes, quality-checks]
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: android
            artifact: apk
          - os: macos-latest
            target: ios
            artifact: ipa
          - os: ubuntu-latest
            target: backend
            artifact: docker
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Build ${{ matrix.target }}
        uses: ./.github/actions/build-${{ matrix.target }}
        with:
          version: ${{ github.run_number }}
          
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.target }}-${{ github.sha }}
          path: build/outputs/${{ matrix.artifact }}

  # Deploy to environments
  deploy:
    needs: build
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [staging, production]
    environment:
      name: ${{ matrix.environment }}
      url: ${{ steps.deploy.outputs.url }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Download artifacts
        uses: actions/download-artifact@v3
        
      - name: Deploy to ${{ matrix.environment }}
        id: deploy
        uses: ./.github/actions/deploy
        with:
          environment: ${{ matrix.environment }}
          version: ${{ github.sha }}
          token: ${{ secrets.DEPLOY_TOKEN }}

Reusable Workflows

# .github/workflows/reusable-flutter-build.yml
name: Flutter Build

on:
  workflow_call:
    inputs:
      platform:
        required: true
        type: string
      environment:
        required: true
        type: string
    secrets:
      signing_key:
        required: true
      signing_password:
        required: true

jobs:
  build:
    runs-on: ${{ inputs.platform == 'ios' && 'macos-latest' || 'ubuntu-latest' }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          cache: true
      
      - name: Get dependencies
        working-directory: apps/pod-app
        run: |
          flutter pub get
          flutter pub run build_runner build --delete-conflicting-outputs
      
      - name: Configure signing
        env:
          SIGNING_KEY: ${{ secrets.signing_key }}
          SIGNING_PASSWORD: ${{ secrets.signing_password }}
        run: |
          echo "$SIGNING_KEY" | base64 -d > signing.key
          ./scripts/configure-signing.sh ${{ inputs.platform }}
      
      - name: Build ${{ inputs.platform }}
        working-directory: apps/pod-app
        run: |
          flutter build ${{ inputs.platform }} \
            --release \
            --dart-define=ENVIRONMENT=${{ inputs.environment }} \
            --build-number=${{ github.run_number }}
      
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          name: ${{ inputs.platform }}-build
          path: apps/pod-app/build/

2. Multi-Environment Deployment

Environment Configuration

// deployment/environments.ts
export interface Environment {
  name: string;
  type: 'development' | 'staging' | 'production';
  config: EnvironmentConfig;
  infrastructure: InfrastructureConfig;
  deployment: DeploymentConfig;
}

export const environments: Record<string, Environment> = {
  development: {
    name: 'development',
    type: 'development',
    config: {
      apiUrl: 'http://localhost:3000',
      features: {
        debugMode: true,
        hotReload: true,
        mockData: true,
      },
    },
    infrastructure: {
      provider: 'local',
      resources: {
        cpu: '2',
        memory: '4Gi',
      },
    },
    deployment: {
      strategy: 'direct',
      healthCheck: {
        enabled: false,
      },
    },
  },
  
  staging: {
    name: 'staging',
    type: 'staging',
    config: {
      apiUrl: 'https://staging-api.appyfly.com',
      features: {
        debugMode: false,
        hotReload: false,
        mockData: false,
      },
    },
    infrastructure: {
      provider: 'aws',
      region: 'us-east-1',
      cluster: 'printcraft-staging',
      resources: {
        cpu: '1',
        memory: '2Gi',
        replicas: 2,
      },
    },
    deployment: {
      strategy: 'rolling',
      healthCheck: {
        enabled: true,
        path: '/health',
        interval: 30,
        timeout: 10,
        retries: 3,
      },
      rollback: {
        automatic: true,
        threshold: 0.5,
      },
    },
  },
  
  production: {
    name: 'production',
    type: 'production',
    config: {
      apiUrl: 'https://api.appyfly.com',
      features: {
        debugMode: false,
        hotReload: false,
        mockData: false,
      },
    },
    infrastructure: {
      provider: 'aws',
      region: 'us-east-1',
      cluster: 'printcraft-production',
      resources: {
        cpu: '2',
        memory: '4Gi',
        replicas: 5,
        autoscaling: {
          enabled: true,
          minReplicas: 3,
          maxReplicas: 20,
          targetCPU: 70,
        },
      },
    },
    deployment: {
      strategy: 'canary',
      canary: {
        steps: [5, 25, 50, 100],
        interval: 300, // 5 minutes
        analysis: {
          metrics: ['error_rate', 'latency_p95', 'success_rate'],
          thresholds: {
            error_rate: 0.01,
            latency_p95: 200,
            success_rate: 0.99,
          },
        },
      },
      healthCheck: {
        enabled: true,
        path: '/health',
        interval: 10,
        timeout: 5,
        retries: 3,
      },
      rollback: {
        automatic: true,
        threshold: 0.01,
      },
    },
  },
};

Deployment Scripts

#!/bin/bash
# scripts/deploy.sh

set -euo pipefail

# Parse arguments
ENVIRONMENT=$1
VERSION=$2
COMPONENT=${3:-all}

# Load environment configuration
source ./scripts/load-env.sh $ENVIRONMENT

# Functions
log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $@"
}

deploy_backend() {
  log "Deploying backend services to $ENVIRONMENT..."
  
  # Update Kubernetes manifests
  kubectl set image deployment/api-gateway \
    api-gateway=$REGISTRY/api-gateway:$VERSION \
    -n $NAMESPACE
  
  kubectl set image deployment/generation-service \
    generation=$REGISTRY/generation:$VERSION \
    -n $NAMESPACE
  
  # Wait for rollout
  kubectl rollout status deployment/api-gateway -n $NAMESPACE
  kubectl rollout status deployment/generation-service -n $NAMESPACE
  
  log "Backend deployment completed"
}

deploy_flutter() {
  log "Deploying Flutter app to $ENVIRONMENT..."
  
  case $ENVIRONMENT in
    staging)
      # Deploy to Firebase App Distribution
      firebase appdistribution:distribute \
        build/app/outputs/flutter-apk/app-release.apk \
        --app $FIREBASE_APP_ID \
        --groups "internal-testers"
      ;;
    production)
      # Deploy to app stores
      fastlane deploy_production
      ;;
  esac
  
  log "Flutter deployment completed"
}

health_check() {
  log "Running health checks..."
  
  local max_attempts=30
  local attempt=0
  
  while [ $attempt -lt $max_attempts ]; do
    if curl -f -s "$HEALTH_CHECK_URL" > /dev/null; then
      log "Health check passed"
      return 0
    fi
    
    attempt=$((attempt + 1))
    log "Health check attempt $attempt/$max_attempts failed, retrying..."
    sleep 10
  done
  
  log "Health check failed after $max_attempts attempts"
  return 1
}

rollback() {
  log "Rolling back deployment..."
  
  kubectl rollout undo deployment/api-gateway -n $NAMESPACE
  kubectl rollout undo deployment/generation-service -n $NAMESPACE
  
  log "Rollback completed"
}

# Main deployment flow
main() {
  log "Starting deployment to $ENVIRONMENT (version: $VERSION)"
  
  # Pre-deployment checks
  ./scripts/pre-deploy-checks.sh $ENVIRONMENT
  
  # Create deployment record
  DEPLOYMENT_ID=$(./scripts/create-deployment-record.sh $ENVIRONMENT $VERSION)
  
  # Deploy components
  case $COMPONENT in
    backend)
      deploy_backend
      ;;
    flutter)
      deploy_flutter
      ;;
    all)
      deploy_backend
      deploy_flutter
      ;;
  esac
  
  # Health check
  if health_check; then
    log "Deployment successful"
    ./scripts/update-deployment-record.sh $DEPLOYMENT_ID "succeeded"
  else
    log "Deployment failed, initiating rollback"
    rollback
    ./scripts/update-deployment-record.sh $DEPLOYMENT_ID "failed"
    exit 1
  fi
  
  # Post-deployment tasks
  ./scripts/post-deploy.sh $ENVIRONMENT $VERSION
}

main

3. Container Orchestration

Kubernetes Manifests

# k8s/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-gateway
  labels:
    app: api-gateway
    version: v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-gateway
  template:
    metadata:
      labels:
        app: api-gateway
        version: v1
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "3000"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: api-gateway
      containers:
      - name: api-gateway
        image: ghcr.io/tek-fly/api-gateway:latest
        ports:
        - containerPort: 3000
          name: http
        env:
        - name: NODE_ENV
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: environment
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-url
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health/live
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 15"]

Helm Charts

# helm/printcraft/values.yaml
global:
  environment: production
  domain: api.appyfly.com
  imageRegistry: ghcr.io/tek-fly
  imagePullPolicy: IfNotPresent

apiGateway:
  enabled: true
  replicaCount: 3
  image:
    repository: api-gateway
    tag: latest
  
  resources:
    requests:
      memory: "256Mi"
      cpu: "250m"
    limits:
      memory: "512Mi"
      cpu: "500m"
  
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70
    targetMemoryUtilizationPercentage: 80
  
  ingress:
    enabled: true
    className: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
      nginx.ingress.kubernetes.io/rate-limit: "100"
    hosts:
      - host: api.appyfly.com
        paths:
          - path: /
            pathType: Prefix
    tls:
      - secretName: api-tls
        hosts:
          - api.appyfly.com

generationService:
  enabled: true
  replicaCount: 2
  image:
    repository: generation-service
    tag: latest
  
  resources:
    requests:
      memory: "1Gi"
      cpu: "500m"
      nvidia.com/gpu: 1
    limits:
      memory: "2Gi"
      cpu: "1000m"
      nvidia.com/gpu: 1
  
  nodeSelector:
    gpu: "true"
  
  tolerations:
    - key: gpu
      operator: Equal
      value: "true"
      effect: NoSchedule

postgresql:
  enabled: true
  auth:
    postgresPassword: "changeme"
    database: printcraft
  primary:
    persistence:
      enabled: true
      size: 100Gi
  metrics:
    enabled: true

4. Deployment Strategies

Blue-Green Deployment

export class BlueGreenDeployment {
  async deploy(
    service: string,
    newVersion: string
  ): Promise<DeploymentResult> {
    // Get current active environment
    const activeEnv = await this.getActiveEnvironment(service);
    const inactiveEnv = activeEnv === 'blue' ? 'green' : 'blue';
    
    log(`Deploying ${service}:${newVersion} to ${inactiveEnv}`);
    
    // Deploy to inactive environment
    await this.deployToEnvironment(service, newVersion, inactiveEnv);
    
    // Health check
    const healthy = await this.waitForHealthy(service, inactiveEnv);
    if (!healthy) {
      throw new Error(`Health check failed for ${service} in ${inactiveEnv}`);
    }
    
    // Run smoke tests
    const testsPassed = await this.runSmokeTests(service, inactiveEnv);
    if (!testsPassed) {
      throw new Error(`Smoke tests failed for ${service} in ${inactiveEnv}`);
    }
    
    // Switch traffic
    await this.switchTraffic(service, inactiveEnv);
    
    // Monitor for errors
    const monitoring = await this.monitorDeployment(service, {
      duration: 300, // 5 minutes
      errorThreshold: 0.01,
    });
    
    if (monitoring.errorRate > monitoring.errorThreshold) {
      log(`Error rate exceeded threshold, rolling back`);
      await this.switchTraffic(service, activeEnv);
      throw new Error(`Deployment failed due to high error rate`);
    }
    
    // Mark deployment as successful
    await this.markEnvironmentActive(service, inactiveEnv);
    
    return {
      service,
      version: newVersion,
      environment: inactiveEnv,
      status: 'success',
    };
  }
}

Canary Deployment

export class CanaryDeployment {
  async deploy(
    service: string,
    newVersion: string,
    config: CanaryConfig
  ): Promise<DeploymentResult> {
    const deploymentId = uuid();
    
    // Deploy canary
    await this.deployCanary(service, newVersion, deploymentId);
    
    // Progressive rollout
    for (const percentage of config.steps) {
      log(`Rolling out to ${percentage}% of traffic`);
      
      // Adjust traffic split
      await this.adjustTrafficSplit(service, deploymentId, percentage);
      
      // Wait for stabilization
      await this.sleep(config.stepDuration);
      
      // Analyze metrics
      const analysis = await this.analyzeCanary(service, deploymentId, {
        metrics: config.metrics,
        thresholds: config.thresholds,
        duration: config.analysisWindow,
      });
      
      if (!analysis.passed) {
        log(`Canary analysis failed at ${percentage}%`);
        await this.rollbackCanary(service, deploymentId);
        throw new Error(`Canary failed: ${analysis.reason}`);
      }
    }
    
    // Promote canary
    await this.promoteCanary(service, deploymentId);
    
    return {
      service,
      version: newVersion,
      deploymentId,
      status: 'success',
    };
  }
  
  private async analyzeCanary(
    service: string,
    deploymentId: string,
    config: AnalysisConfig
  ): Promise<AnalysisResult> {
    const metrics = await this.collectMetrics(service, {
      deploymentId,
      duration: config.duration,
      metrics: config.metrics,
    });
    
    const baseline = await this.getBaselineMetrics(service, config.duration);
    
    // Compare metrics
    const analysis: AnalysisResult = {
      passed: true,
      metrics: {},
    };
    
    for (const metric of config.metrics) {
      const current = metrics[metric];
      const base = baseline[metric];
      const threshold = config.thresholds[metric];
      
      const degradation = (current - base) / base;
      
      analysis.metrics[metric] = {
        baseline: base,
        current: current,
        degradation: degradation,
        passed: Math.abs(degradation) <= threshold,
      };
      
      if (!analysis.metrics[metric].passed) {
        analysis.passed = false;
        analysis.reason = `${metric} degraded by ${(degradation * 100).toFixed(2)}%`;
      }
    }
    
    return analysis;
  }
}

5. Rollback Mechanisms

Automated Rollback

export class RollbackManager {
  async monitorAndRollback(
    deployment: Deployment
  ): Promise<void> {
    const startTime = Date.now();
    const config = deployment.rollbackConfig;
    
    while (Date.now() - startTime < config.monitoringWindow) {
      const metrics = await this.collectMetrics(deployment);
      
      // Check error rate
      if (metrics.errorRate > config.errorThreshold) {
        await this.triggerRollback(deployment, 'High error rate');
        break;
      }
      
      // Check latency
      if (metrics.latencyP95 > config.latencyThreshold) {
        await this.triggerRollback(deployment, 'High latency');
        break;
      }
      
      // Check success rate
      if (metrics.successRate < config.successThreshold) {
        await this.triggerRollback(deployment, 'Low success rate');
        break;
      }
      
      await this.sleep(config.checkInterval);
    }
  }
  
  private async triggerRollback(
    deployment: Deployment,
    reason: string
  ): Promise<void> {
    log(`Triggering rollback for ${deployment.id}: ${reason}`);
    
    // Notify stakeholders
    await this.notifyRollback(deployment, reason);
    
    // Execute rollback
    switch (deployment.type) {
      case 'kubernetes':
        await this.rollbackKubernetes(deployment);
        break;
      case 'lambda':
        await this.rollbackLambda(deployment);
        break;
      case 'ecs':
        await this.rollbackECS(deployment);
        break;
    }
    
    // Verify rollback
    const success = await this.verifyRollback(deployment);
    
    if (!success) {
      await this.escalateRollbackFailure(deployment);
    }
  }
  
  private async rollbackKubernetes(
    deployment: Deployment
  ): Promise<void> {
    const cmd = `kubectl rollout undo deployment/${deployment.name} -n ${deployment.namespace}`;
    await exec(cmd);
    
    // Wait for rollout to complete
    const statusCmd = `kubectl rollout status deployment/${deployment.name} -n ${deployment.namespace}`;
    await exec(statusCmd);
  }
}

6. Release Coordination

Release Manager

export class ReleaseManager {
  async createRelease(
    version: string,
    components: Component[]
  ): Promise<Release> {
    const release: Release = {
      id: uuid(),
      version,
      components,
      status: 'pending',
      createdAt: new Date(),
    };
    
    // Validate release
    await this.validateRelease(release);
    
    // Create release branch
    await this.createReleaseBranch(version);
    
    // Generate changelog
    release.changelog = await this.generateChangelog(version);
    
    // Build all components
    const builds = await Promise.all(
      components.map(c => this.buildComponent(c, version))
    );
    
    release.artifacts = builds.map(b => b.artifact);
    
    // Create release record
    await this.saveRelease(release);
    
    return release;
  }
  
  async deployRelease(
    releaseId: string,
    environment: string
  ): Promise<void> {
    const release = await this.getRelease(releaseId);
    
    // Pre-deployment checks
    await this.runPreDeploymentChecks(release, environment);
    
    // Deploy in order
    for (const component of release.components) {
      await this.deployComponent(component, environment, {
        version: release.version,
        waitForReady: true,
      });
    }
    
    // Post-deployment verification
    await this.runPostDeploymentTests(release, environment);
    
    // Update release status
    await this.updateReleaseStatus(releaseId, {
      status: 'deployed',
      environment,
      deployedAt: new Date(),
    });
  }
}

Automation Tools

1. Deployment CLI

#!/usr/bin/env node
// tools/deploy-cli.ts

import { Command } from 'commander';
import { DeploymentManager } from './deployment-manager';

const program = new Command();
const deploymentManager = new DeploymentManager();

program
  .name('printcraft-deploy')
  .description('PrintCraft AI Deployment CLI')
  .version('1.0.0');

program
  .command('deploy <component> <version>')
  .description('Deploy a component')
  .option('-e, --environment <env>', 'Target environment', 'staging')
  .option('-s, --strategy <strategy>', 'Deployment strategy', 'rolling')
  .option('--dry-run', 'Perform a dry run')
  .action(async (component, version, options) => {
    try {
      console.log(`Deploying ${component}:${version} to ${options.environment}`);
      
      if (options.dryRun) {
        const plan = await deploymentManager.planDeployment(
          component,
          version,
          options
        );
        console.log('Deployment plan:', JSON.stringify(plan, null, 2));
      } else {
        const result = await deploymentManager.deploy(
          component,
          version,
          options
        );
        console.log('Deployment result:', result);
      }
    } catch (error) {
      console.error('Deployment failed:', error);
      process.exit(1);
    }
  });

program
  .command('rollback <component>')
  .description('Rollback a component')
  .option('-e, --environment <env>', 'Target environment', 'staging')
  .action(async (component, options) => {
    try {
      console.log(`Rolling back ${component} in ${options.environment}`);
      const result = await deploymentManager.rollback(component, options);
      console.log('Rollback result:', result);
    } catch (error) {
      console.error('Rollback failed:', error);
      process.exit(1);
    }
  });

program.parse();

2. Pre-deployment Checks

#!/bin/bash
# scripts/pre-deploy-checks.sh

set -e

ENVIRONMENT=$1
CHECKS_PASSED=true

log() {
  echo "[PRE-DEPLOY] $@"
}

check_dependencies() {
  log "Checking dependencies..."
  
  # Check kubectl
  if ! command -v kubectl &> /dev/null; then
    log "ERROR: kubectl not found"
    return 1
  fi
  
  # Check helm
  if ! command -v helm &> /dev/null; then
    log "ERROR: helm not found"
    return 1
  fi
  
  # Check cloud CLI
  case $ENVIRONMENT in
    staging|production)
      if ! command -v aws &> /dev/null; then
        log "ERROR: AWS CLI not found"
        return 1
      fi
      ;;
  esac
  
  log "Dependencies check passed"
  return 0
}

check_cluster_access() {
  log "Checking cluster access..."
  
  if ! kubectl cluster-info &> /dev/null; then
    log "ERROR: Cannot access Kubernetes cluster"
    return 1
  fi
  
  log "Cluster access confirmed"
  return 0
}

check_resources() {
  log "Checking resource availability..."
  
  # Check node resources
  local nodes=$(kubectl get nodes -o json)
  local available_cpu=$(echo "$nodes" | jq -r '.items[].status.allocatable.cpu' | sed 's/[^0-9]//g' | awk '{sum+=$1} END {print sum}')
  local available_memory=$(echo "$nodes" | jq -r '.items[].status.allocatable.memory' | sed 's/[^0-9]//g' | awk '{sum+=$1} END {print sum/1024/1024}')
  
  log "Available CPU: ${available_cpu}m"
  log "Available Memory: ${available_memory}Mi"
  
  if [ "$available_cpu" -lt 2000 ]; then
    log "WARNING: Low CPU availability"
  fi
  
  if [ "$available_memory" -lt 4096 ]; then
    log "WARNING: Low memory availability"
  fi
  
  return 0
}

check_database_migrations() {
  log "Checking pending database migrations..."
  
  local pending=$(kubectl exec -n $NAMESPACE deployment/api-gateway -- \
    npm run migrations:pending --silent)
  
  if [ -n "$pending" ]; then
    log "WARNING: Pending migrations detected:"
    echo "$pending"
    log "Run migrations before deployment"
    return 1
  fi
  
  log "No pending migrations"
  return 0
}

# Run all checks
if ! check_dependencies; then
  CHECKS_PASSED=false
fi

if ! check_cluster_access; then
  CHECKS_PASSED=false
fi

if ! check_resources; then
  CHECKS_PASSED=false
fi

if [ "$ENVIRONMENT" != "development" ]; then
  if ! check_database_migrations; then
    CHECKS_PASSED=false
  fi
fi

if [ "$CHECKS_PASSED" = true ]; then
  log "All pre-deployment checks passed"
  exit 0
else
  log "Pre-deployment checks failed"
  exit 1
fi

Monitoring & Observability

Deployment Metrics

export class DeploymentMetrics {
  private prometheus = new PrometheusClient();
  
  recordDeployment(deployment: Deployment): void {
    // Deployment counter
    this.prometheus.counter('deployments_total', {
      component: deployment.component,
      environment: deployment.environment,
      status: deployment.status,
    }).inc();
    
    // Deployment duration
    this.prometheus.histogram('deployment_duration_seconds', {
      component: deployment.component,
      environment: deployment.environment,
    }).observe(deployment.duration);
    
    // Deployment gauge
    this.prometheus.gauge('deployment_info', {
      component: deployment.component,
      environment: deployment.environment,
      version: deployment.version,
    }).set(1);
  }
  
  recordRollback(rollback: Rollback): void {
    this.prometheus.counter('rollbacks_total', {
      component: rollback.component,
      environment: rollback.environment,
      reason: rollback.reason,
    }).inc();
  }
}

Best Practices

1. Deployment Checklist

deployment_checklist:
  pre_deployment:
    - dependency_updates
    - security_scanning
    - performance_testing
    - database_migrations
    - configuration_review
    
  deployment:
    - health_checks
    - progressive_rollout
    - monitoring_alerts
    - error_tracking
    - performance_monitoring
    
  post_deployment:
    - smoke_tests
    - user_acceptance
    - performance_validation
    - security_verification
    - documentation_update

2. Emergency Procedures

export class EmergencyProcedures {
  static readonly procedures = {
    complete_outage: [
      'Activate incident response team',
      'Switch to disaster recovery site',
      'Notify stakeholders',
      'Begin root cause analysis',
    ],
    
    data_corruption: [
      'Stop all write operations',
      'Identify extent of corruption',
      'Restore from last known good backup',
      'Verify data integrity',
    ],
    
    security_breach: [
      'Isolate affected systems',
      'Reset all credentials',
      'Audit access logs',
      'Notify security team',
    ],
  };
}

This skill ensures reliable, automated deployments for PrintCraft AI across all environments.