Merge pull request #170 from Ardecrownn/feature/observability-enhance… #228
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| setup: | |
| name: Setup & Cache | |
| runs-on: ubuntu-latest | |
| outputs: | |
| node-version: ${{ steps.setup-node.outputs.node-version }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| id: setup-node | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Generate Prisma Client | |
| run: npx prisma generate | |
| - name: Cache Prisma Client | |
| uses: actions/cache@v4 | |
| id: cache-prisma | |
| with: | |
| path: node_modules/.prisma | |
| key: ${{ runner.os }}-prisma-${{ hashFiles('prisma/schema.prisma') }} | |
| lint: | |
| name: Linting | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint | |
| run: npm run lint | |
| test-unit: | |
| name: Unit Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run Unit Tests | |
| run: npm run test:unit | |
| env: | |
| NODE_ENV: test | |
| test-integration: | |
| name: Integration Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_USER: postgres | |
| POSTGRES_DB: propchain_test | |
| 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@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Wait for services | |
| run: | | |
| timeout 60 bash -c 'until nc -z localhost 5432; do sleep 1; done' | |
| timeout 60 bash -c 'until nc -z localhost 6379; do sleep 1; done' | |
| - name: Run Integration Tests | |
| run: npm run test:integration | |
| env: | |
| NODE_ENV: test | |
| DATABASE_URL: postgresql://postgres:postgres@localhost:5432/propchain_test | |
| REDIS_URL: redis://localhost:6379 | |
| test-e2e: | |
| name: E2E Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_USER: postgres | |
| POSTGRES_DB: propchain_test | |
| 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@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Wait for services | |
| run: | | |
| timeout 60 bash -c 'until nc -z localhost 5432; do sleep 1; done' | |
| timeout 60 bash -c 'until nc -z localhost 6379; do sleep 1; done' | |
| - name: Run E2E Tests | |
| run: npm run test:e2e | |
| env: | |
| NODE_ENV: test | |
| DATABASE_URL: postgresql://postgres:postgres@localhost:5432/propchain_test | |
| REDIS_URL: redis://localhost:6379 | |
| test-security: | |
| name: Security Tests | |
| needs: setup | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run Security Tests | |
| run: npm run test:security | |
| env: | |
| NODE_ENV: test | |
| build: | |
| name: Build (Production Target) | |
| needs: [lint, test-unit] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Generate Prisma Client | |
| run: npx prisma generate | |
| - name: Build Application | |
| run: npm run build | |
| - name: Upload Build Artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifact | |
| path: dist/ | |
| retention-days: 1 | |
| observability-test: | |
| name: Observability Tests | |
| needs: build | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_USER: postgres | |
| POSTGRES_DB: propchain_test | |
| 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 | |
| jaeger: | |
| image: jaegertracing/all-in-one:latest | |
| options: >- | |
| --health-cmd "wget --no-verbose --tries=1 --spider http://localhost:16686" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 16686:16686 | |
| - 4317:4317 | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Download Build Artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: build-artifact | |
| path: dist | |
| - name: Wait for services | |
| run: | | |
| timeout 60 bash -c 'until nc -z localhost 5432; do sleep 1; done' | |
| timeout 60 bash -c 'until nc -z localhost 6379; do sleep 1; done' | |
| timeout 60 bash -c 'until nc -z localhost 16686; do sleep 1; done' | |
| - name: Start Application | |
| run: | | |
| npm run start & | |
| sleep 30 | |
| - name: Test Observability Endpoints | |
| run: | | |
| curl -f http://localhost:3000/observability/health || exit 1 | |
| curl -f http://localhost:3000/observability/metrics/current || exit 1 | |
| curl -f http://localhost:3000/metrics || exit 1 | |
| curl -f http://localhost:3000/observability/tracing/status || exit 1 | |
| - name: Test Metrics Collection | |
| run: | | |
| # Test that metrics are being collected | |
| response=$(curl -s http://localhost:3000/metrics) | |
| if [[ $response == *"http_request_duration_seconds"* ]]; then | |
| echo "✅ HTTP metrics found" | |
| else | |
| echo "❌ HTTP metrics not found" | |
| exit 1 | |
| fi | |
| if [[ $response == *"system_cpu_usage_percent"* ]]; then | |
| echo "✅ System metrics found" | |
| else | |
| echo "❌ System metrics not found" | |
| exit 1 | |
| fi | |
| env: | |
| NODE_ENV: test | |
| DATABASE_URL: postgresql://postgres:postgres@localhost:5432/propchain_test | |
| REDIS_URL: redis://localhost:6379 | |
| OTEL_SERVICE_NAME: propchain-backend-test | |
| OTEL_EXPORTER_OTLP_ENDPOINT: http://localhost:4317 | |
| METRICS_ENABLED: true | |
| PERFORMANCE_MONITORING_ENABLED: true | |
| load-test: | |
| name: Load Testing | |
| needs: build | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:15 | |
| env: | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_USER: postgres | |
| POSTGRES_DB: propchain_test | |
| 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@v5 | |
| with: | |
| node-version: 20 | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Install k6 | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gnupg2 software-properties-common | |
| sudo wget -q -O - https://dl.k6.io/key.gpg | sudo apt-key add - | |
| echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list | |
| sudo apt-get update | |
| sudo apt-get install -y k6 | |
| - name: Wait for services | |
| run: | | |
| timeout 60 bash -c 'until nc -z localhost 5432; do sleep 1; done' | |
| timeout 60 bash -c 'until nc -z localhost 6379; do sleep 1; done' | |
| - name: Start API in background | |
| run: | | |
| npm run start & | |
| sleep 30 | |
| - name: Run load tests | |
| run: npm run loadtest:ci | |
| env: | |
| API_URL: http://localhost:3000 | |
| NODE_ENV: test | |
| DATABASE_URL: postgresql://postgres:postgres@localhost:5432/propchain_test | |
| REDIS_URL: redis://localhost:6379 | |
| - name: Upload k6 results | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: k6-results | |
| path: artifacts/k6-results.json | |
| deploy-staging: | |
| name: Deploy to Staging | |
| needs: [build, test-integration, test-e2e, test-security, observability-test] | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') | |
| runs-on: ubuntu-latest | |
| environment: staging | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Download Build Artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: build-artifact | |
| path: dist | |
| - name: Deploy to Staging Server | |
| run: echo "🚀 Deploying to staging environment... (Placeholder)" | |
| # Actual deployment logic would go here: | |
| # - npm run deploy:staging | |
| # - scp -r dist/* user@staging-host:/var/www/propchain | |
| # - heroku/deploy-action@v5 | |
| # - aws ecs update-service... | |
| deploy-production: | |
| name: Deploy to Production | |
| needs: [deploy-staging] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: production | |
| url: https://api.propchain.com | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: Download Build Artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: build-artifact | |
| path: dist | |
| - name: Run Production Migrations | |
| run: echo "🛠 Running production database migrations... (Placeholder)" | |
| # run: npx prisma migrate deploy | |
| - name: Deploy to Production Cluster | |
| run: echo "🚀 Deploying to production environment... (Blue/Green Strategy Placeholder)" | |
| # Actual deployment strategy logic (Blue/Green or Canary): | |
| # - Implement traffic routing switch | |
| # - Health checks check |