Merge pull request #280 from Abrahamojobo/feature/realtime-analytics-… #280
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 | ||
|
Check failure on line 1 in .github/workflows/ci.yml
|
||
| on: | ||
| push: | ||
| branches: [main, develop] | ||
| pull_request: | ||
| branches: [main, develop] | ||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
| env: | ||
| NODE_ENV: test | ||
| PORT: "3000" | ||
| API_PREFIX: api | ||
| CORS_ORIGIN: http://localhost:3001 | ||
| DATABASE_URL: postgresql://postgres:[email protected]:5432/propchain_ci?sslmode=disable | ||
| TEST_DATABASE_URL: postgresql://postgres:[email protected]:5432/propchain_ci?sslmode=disable | ||
| E2E_DATABASE_URL: postgresql://postgres:[email protected]:5432/propchain_ci?sslmode=disable | ||
| REDIS_URL: redis://127.0.0.1:6379/0 | ||
| TEST_REDIS_URL: redis://127.0.0.1:6379/0 | ||
| E2E_REDIS_URL: redis://127.0.0.1:6379/0 | ||
| REDIS_HOST: 127.0.0.1 | ||
| REDIS_PORT: "6379" | ||
| REDIS_DB: "0" | ||
| JWT_SECRET: ciJwtSigningKeyAlphaNumericValue0001 | ||
| JWT_REFRESH_SECRET: ciRefreshSigningKeyAlphaNumeric0002 | ||
| ENCRYPTION_KEY: C1EncKeyAlphaNumericValue0000001 | ||
| SESSION_SECRET: ciSessionSigningKeyAlphaNumeric0003 | ||
| EMAIL_FROM: [email protected] | ||
| RPC_URL: http://127.0.0.1:8545 | ||
| PRIVATE_KEY: 0x1111111111111111111111111111111111111111111111111111111111111111 | ||
| STORAGE_PROVIDER: memory | ||
| MOCK_BLOCKCHAIN: "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_DB: propchain_test | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: postgres | ||
| options: >- | ||
| --health-cmd "pg_isready -U postgres -d propchain_test" | ||
| --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: Generate Prisma Client | ||
| run: npx prisma generate | ||
| - name: Apply Prisma Migrations | ||
| run: npx prisma migrate deploy | ||
| - 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_DB: propchain_test | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: postgres | ||
| options: >- | ||
| --health-cmd "pg_isready -U postgres -d propchain_test" | ||
| --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: Generate Prisma Client | ||
| run: npx prisma generate | ||
| - name: Apply Prisma Migrations | ||
| run: npx prisma migrate deploy | ||
| - 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 | ||
| test-migrations: | ||
| name: Migration Safety | ||
| 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 Migration Safety Checks | ||
| run: npm run migrate:test | ||
| build: | ||
| name: Build (Production Target) | ||
| needs: [lint, test-unit, test-migrations] | ||
| 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_DB: propchain_test | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: postgres | ||
| options: >- | ||
| --health-cmd "pg_isready -U postgres -d propchain_test" | ||
| --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: Download Build Artifact | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: build-artifact | ||
| path: dist | ||
| - name: Generate Prisma Client | ||
| run: npx prisma generate | ||
| - name: Apply Prisma Migrations | ||
| run: npx prisma migrate deploy | ||
| - 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:ci > api.log 2>&1 & | ||
| echo $! > api.pid | ||
| - name: Wait for API liveness | ||
| run: | | ||
| for attempt in {1..30}; do | ||
| if curl -fsS http://127.0.0.1:3000/api/v1/health/liveness > /dev/null; then | ||
| exit 0 | ||
| fi | ||
| sleep 2 | ||
| done | ||
| cat api.log | ||
| exit 1 | ||
| - name: Run load tests | ||
| run: npm run loadtest:ci | ||
| env: | ||
| API_URL: http://127.0.0.1:3000 | ||
| HEALTH_PATH: /api/v1/health/liveness | ||
| NODE_ENV: test | ||
| DATABASE_URL: postgresql://postgres:postgres@localhost:5432/propchain_test | ||
| REDIS_URL: redis://localhost:6379 | ||
| - name: Stop API | ||
| if: always() | ||
| run: | | ||
| if [ -f api.pid ]; then | ||
| kill "$(cat api.pid)" || true | ||
| fi | ||
| - name: Upload API logs | ||
| if: failure() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: load-test-api-log | ||
| path: api.log | ||
| - 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, test-migrations, 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 (Blue/Green or Canary): | ||
| # - Implement traffic routing switch | ||
| # - Health checks check | ||