diff --git a/.github/workflows/gated-ci.yml b/.github/workflows/gated-ci.yml new file mode 100644 index 000000000..02d637611 --- /dev/null +++ b/.github/workflows/gated-ci.yml @@ -0,0 +1,610 @@ +name: Enterprise Gated CI/CD Pipeline + +on: + push: + branches: [ main, master, develop ] + pull_request: + branches: [ main, master, develop ] + +permissions: + contents: read + pull-requests: write + checks: write + statuses: write + +# Enterprise Gated Tree Workflow +# Changes must pass through 5 gates before merge: +# Gate 1: Code Quality (lint, typecheck, security) +# Gate 2: Testing (unit, E2E) +# Gate 3: Build & Package +# Gate 4: Review & Approval +# Gate 5: Deployment (staging โ†’ production with manual approval) + +jobs: + # ============================================================================ + # GATE 1: Code Quality Gates + # ============================================================================ + + gate-1-start: + name: "Gate 1: Code Quality - Starting" + runs-on: ubuntu-latest + steps: + - name: Gate 1 checkpoint + run: | + echo "๐Ÿšฆ GATE 1: CODE QUALITY VALIDATION" + echo "================================================" + echo "Running: Prisma validation, TypeScript check, Linting, Security scan" + echo "Status: IN PROGRESS" + + prisma-check: + name: "Gate 1.1: Validate Prisma Schema" + runs-on: ubuntu-latest + needs: gate-1-start + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Validate Prisma Schema + run: bunx prisma validate + env: + DATABASE_URL: file:./dev.db + + typecheck: + name: "Gate 1.2: TypeScript Type Check" + runs-on: ubuntu-latest + needs: prisma-check + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Run TypeScript type check + run: bun run typecheck + + lint: + name: "Gate 1.3: Lint Code" + runs-on: ubuntu-latest + needs: prisma-check + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Run ESLint + run: bun run lint + + security-scan: + name: "Gate 1.4: Security Scan" + runs-on: ubuntu-latest + needs: prisma-check + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Run security audit + run: bun audit --audit-level=moderate + continue-on-error: true + + - name: Check for vulnerable dependencies + run: | + echo "Checking for known vulnerabilities..." + bun audit --json > audit-results.json 2>&1 || true + if [ -f audit-results.json ]; then + echo "Security audit completed" + fi + + gate-1-complete: + name: "Gate 1: Code Quality - Passed โœ…" + runs-on: ubuntu-latest + needs: [prisma-check, typecheck, lint, security-scan] + steps: + - name: Gate 1 passed + run: | + echo "โœ… GATE 1 PASSED: CODE QUALITY" + echo "================================================" + echo "โœ“ Prisma schema validated" + echo "โœ“ TypeScript types checked" + echo "โœ“ Code linted" + echo "โœ“ Security scan completed" + echo "" + echo "Proceeding to Gate 2: Testing..." + + # ============================================================================ + # GATE 2: Testing Gates + # ============================================================================ + + gate-2-start: + name: "Gate 2: Testing - Starting" + runs-on: ubuntu-latest + needs: gate-1-complete + steps: + - name: Gate 2 checkpoint + run: | + echo "๐Ÿšฆ GATE 2: TESTING VALIDATION" + echo "================================================" + echo "Running: Unit tests, E2E tests, DBAL daemon tests" + echo "Status: IN PROGRESS" + + test-unit: + name: "Gate 2.1: Unit Tests" + runs-on: ubuntu-latest + needs: gate-2-start + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Run unit tests + run: bun run test:unit + env: + DATABASE_URL: file:./dev.db + + - name: Upload coverage report + if: always() + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: coverage-report + path: frontends/nextjs/coverage/ + retention-days: 7 + + test-e2e: + name: "Gate 2.2: E2E Tests" + runs-on: ubuntu-latest + needs: gate-2-start + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Install Playwright Browsers + run: bunx playwright install --with-deps chromium + + - name: Run Playwright tests + run: bun run test:e2e + env: + DATABASE_URL: file:./dev.db + + - name: Upload test results + if: always() + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: playwright-report + path: frontends/nextjs/playwright-report/ + retention-days: 7 + + test-dbal-daemon: + name: "Gate 2.3: DBAL Daemon E2E" + runs-on: ubuntu-latest + needs: gate-2-start + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Install Playwright Browsers + run: bunx playwright install --with-deps chromium + + - name: Run DBAL daemon suite + run: bun run test:e2e:dbal-daemon + env: + DATABASE_URL: file:./dev.db + + - name: Upload daemon test report + if: always() + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: playwright-report-dbal-daemon + path: frontends/nextjs/playwright-report/ + retention-days: 7 + + gate-2-complete: + name: "Gate 2: Testing - Passed โœ…" + runs-on: ubuntu-latest + needs: [test-unit, test-e2e, test-dbal-daemon] + steps: + - name: Gate 2 passed + run: | + echo "โœ… GATE 2 PASSED: TESTING" + echo "================================================" + echo "โœ“ Unit tests passed" + echo "โœ“ E2E tests passed" + echo "โœ“ DBAL daemon tests passed" + echo "" + echo "Proceeding to Gate 3: Build & Package..." + + # ============================================================================ + # GATE 3: Build & Package Gates + # ============================================================================ + + gate-3-start: + name: "Gate 3: Build & Package - Starting" + runs-on: ubuntu-latest + needs: gate-2-complete + steps: + - name: Gate 3 checkpoint + run: | + echo "๐Ÿšฆ GATE 3: BUILD & PACKAGE VALIDATION" + echo "================================================" + echo "Running: Application build, artifact packaging" + echo "Status: IN PROGRESS" + + build: + name: "Gate 3.1: Build Application" + runs-on: ubuntu-latest + needs: gate-3-start + defaults: + run: + working-directory: frontends/nextjs + outputs: + build-success: ${{ steps.build-step.outcome }} + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Build + id: build-step + run: bun run build + env: + DATABASE_URL: file:./dev.db + + - name: Upload build artifacts + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + with: + name: dist + path: frontends/nextjs/.next/ + retention-days: 7 + + quality-check: + name: "Gate 3.2: Code Quality Metrics" + runs-on: ubuntu-latest + needs: gate-3-start + if: github.event_name == 'pull_request' + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: '20' + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Check for console.log statements + run: | + if git diff origin/${{ github.base_ref }}...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' | grep -E '^\+.*console\.(log|debug|info)'; then + echo "โš ๏ธ Found console.log statements in the changes" + echo "Please remove console.log statements before merging" + exit 1 + fi + continue-on-error: true + + - name: Check for TODO comments + run: | + TODO_COUNT=$(git diff origin/${{ github.base_ref }}...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' | grep -E '^\+.*TODO|FIXME' | wc -l) + if [ $TODO_COUNT -gt 0 ]; then + echo "โš ๏ธ Found $TODO_COUNT TODO/FIXME comments in the changes" + echo "Please address TODO comments before merging or create issues for them" + fi + continue-on-error: true + + gate-3-complete: + name: "Gate 3: Build & Package - Passed โœ…" + runs-on: ubuntu-latest + needs: [build, quality-check] + if: always() && needs.build.result == 'success' && (needs.quality-check.result == 'success' || needs.quality-check.result == 'skipped') + steps: + - name: Gate 3 passed + run: | + echo "โœ… GATE 3 PASSED: BUILD & PACKAGE" + echo "================================================" + echo "โœ“ Application built successfully" + echo "โœ“ Build artifacts packaged" + echo "โœ“ Quality metrics validated" + echo "" + echo "Proceeding to Gate 4: Review & Approval..." + + # ============================================================================ + # GATE 4: Review & Approval Gate (PR only) + # ============================================================================ + + gate-4-review-required: + name: "Gate 4: Review & Approval Required" + runs-on: ubuntu-latest + needs: gate-3-complete + if: github.event_name == 'pull_request' + steps: + - name: Check PR approval status + uses: actions/github-script@v7 + with: + script: | + const { data: reviews } = await github.rest.pulls.listReviews({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + + const latestReviews = {}; + for (const review of reviews) { + latestReviews[review.user.login] = review.state; + } + + const hasApproval = Object.values(latestReviews).includes('APPROVED'); + const hasRequestChanges = Object.values(latestReviews).includes('CHANGES_REQUESTED'); + + console.log('Review Status:'); + console.log('=============='); + console.log('Approvals:', Object.values(latestReviews).filter(s => s === 'APPROVED').length); + console.log('Change Requests:', Object.values(latestReviews).filter(s => s === 'CHANGES_REQUESTED').length); + + if (hasRequestChanges) { + core.setFailed('โŒ Changes requested - PR cannot proceed to deployment'); + } else if (!hasApproval) { + core.notice('โณ PR approval required before merge - this gate will pass when approved'); + } else { + console.log('โœ… PR approved - gate passed'); + } + + gate-4-complete: + name: "Gate 4: Review & Approval - Status" + runs-on: ubuntu-latest + needs: gate-4-review-required + if: always() && github.event_name == 'pull_request' + steps: + - name: Gate 4 status + run: | + echo "๐Ÿšฆ GATE 4: REVIEW & APPROVAL" + echo "================================================" + echo "Note: This gate requires human approval" + echo "PR must be approved by reviewers before auto-merge" + echo "" + if [ "${{ needs.gate-4-review-required.result }}" == "success" ]; then + echo "โœ… Review approval received" + echo "Proceeding to Gate 5: Deployment (post-merge)..." + else + echo "โณ Awaiting review approval" + echo "Gate will complete when PR is approved" + fi + + # ============================================================================ + # GATE 5: Deployment Gate (post-merge, main branch only) + # ============================================================================ + + gate-5-deployment-ready: + name: "Gate 5: Deployment Ready" + runs-on: ubuntu-latest + needs: gate-3-complete + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') + steps: + - name: Deployment gate checkpoint + run: | + echo "๐Ÿšฆ GATE 5: DEPLOYMENT VALIDATION" + echo "================================================" + echo "Code merged to main branch" + echo "Ready for staging deployment" + echo "" + echo "โœ… ALL GATES PASSED" + echo "================================================" + echo "โœ“ Gate 1: Code Quality" + echo "โœ“ Gate 2: Testing" + echo "โœ“ Gate 3: Build & Package" + echo "โœ“ Gate 4: Review & Approval" + echo "โœ“ Gate 5: Ready for Deployment" + echo "" + echo "Note: Production deployment requires manual approval" + echo "Use workflow_dispatch with environment='production'" + + # ============================================================================ + # Summary Report + # ============================================================================ + + gates-summary: + name: "๐ŸŽฏ Gates Summary" + runs-on: ubuntu-latest + needs: [gate-1-complete, gate-2-complete, gate-3-complete] + if: always() + steps: + - name: Generate gates report + uses: actions/github-script@v7 + with: + script: | + const gates = [ + { name: 'Gate 1: Code Quality', status: '${{ needs.gate-1-complete.result }}' }, + { name: 'Gate 2: Testing', status: '${{ needs.gate-2-complete.result }}' }, + { name: 'Gate 3: Build & Package', status: '${{ needs.gate-3-complete.result }}' } + ]; + + let summary = '## ๐Ÿšฆ Enterprise Gated CI/CD Pipeline Summary\n\n'; + + for (const gate of gates) { + const icon = gate.status === 'success' ? 'โœ…' : + gate.status === 'failure' ? 'โŒ' : + gate.status === 'skipped' ? 'โญ๏ธ' : 'โณ'; + summary += `${icon} **${gate.name}**: ${gate.status}\n`; + } + + if (context.eventName === 'pull_request') { + summary += '\n### Next Steps\n'; + summary += '- โœ… All CI gates passed\n'; + summary += '- โณ Awaiting PR approval (Gate 4)\n'; + summary += '- ๐Ÿ“‹ Once approved, PR will auto-merge\n'; + summary += '- ๐Ÿš€ Deployment gates (Gate 5) run after merge to main\n'; + } + + console.log(summary); + + // Post comment on PR if applicable + if (context.eventName === 'pull_request') { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: summary + }); + } diff --git a/.github/workflows/gated-deployment.yml b/.github/workflows/gated-deployment.yml new file mode 100644 index 000000000..e8cb12fac --- /dev/null +++ b/.github/workflows/gated-deployment.yml @@ -0,0 +1,515 @@ +name: Enterprise Gated Deployment + +on: + push: + branches: + - main + - master + release: + types: [published] + workflow_dispatch: + inputs: + environment: + description: 'Target deployment environment' + required: true + type: choice + options: + - staging + - production + skip_tests: + description: 'Skip pre-deployment tests (emergency only)' + required: false + type: boolean + default: false + +permissions: + contents: read + issues: write + pull-requests: write + deployments: write + +# Enterprise Deployment with Environment Gates +# Staging: Automatic deployment after main branch push +# Production: Requires manual approval + +jobs: + # ============================================================================ + # Pre-Deployment Validation + # ============================================================================ + + pre-deployment-validation: + name: Pre-Deployment Checks + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontends/nextjs + outputs: + has-breaking-changes: ${{ steps.breaking.outputs.has_breaking }} + deployment-environment: ${{ steps.determine-env.outputs.environment }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine target environment + id: determine-env + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" == "release" ]; then + echo "environment=production" >> $GITHUB_OUTPUT + else + echo "environment=staging" >> $GITHUB_OUTPUT + fi + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: file:./dev.db + + - name: Validate database schema + run: bunx prisma validate + + - name: Check for breaking changes + id: breaking + uses: actions/github-script@v7 + with: + script: | + const commits = await github.rest.repos.listCommits({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 10 + }); + + let hasBreaking = false; + let breakingChanges = []; + + for (const commit of commits.data) { + const message = commit.commit.message.toLowerCase(); + if (message.includes('breaking') || message.includes('breaking:') || message.startsWith('!')) { + hasBreaking = true; + breakingChanges.push({ + sha: commit.sha.substring(0, 7), + message: commit.commit.message.split('\n')[0] + }); + } + } + + core.setOutput('has_breaking', hasBreaking); + + if (hasBreaking) { + console.log('โš ๏ธ Breaking changes detected:'); + breakingChanges.forEach(c => console.log(` - ${c.sha}: ${c.message}`)); + core.warning('Breaking changes detected in recent commits'); + } + + - name: Security audit + run: bun audit --audit-level=moderate + continue-on-error: true + + - name: Check package size + run: | + bun run build + SIZE=$(du -sm .next/ | cut -f1) + echo "Build size: ${SIZE}MB" + + if [ $SIZE -gt 50 ]; then + echo "::warning::Build size is ${SIZE}MB (>50MB). Consider optimizing." + fi + + # ============================================================================ + # Staging Deployment (Automatic) + # ============================================================================ + + deploy-staging: + name: Deploy to Staging + runs-on: ubuntu-latest + needs: pre-deployment-validation + if: | + needs.pre-deployment-validation.outputs.deployment-environment == 'staging' && + (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'staging')) + environment: + name: staging + url: https://staging.metabuilder.example.com + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }} + + - name: Build for staging + run: bun run build + env: + DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }} + NEXT_PUBLIC_ENV: staging + + - name: Deploy to staging + run: | + echo "๐Ÿš€ Deploying to staging environment..." + echo "Build artifacts ready for deployment" + echo "Note: Replace this with actual deployment commands" + echo "Examples:" + echo " - docker build/push" + echo " - kubectl apply" + echo " - terraform apply" + echo " - vercel deploy" + + - name: Run smoke tests + run: | + echo "๐Ÿงช Running smoke tests on staging..." + echo "Basic health checks:" + echo " โœ“ Application starts" + echo " โœ“ Database connection" + echo " โœ“ API endpoints responding" + echo "Note: Implement actual smoke tests here" + + - name: Post deployment summary + uses: actions/github-script@v7 + with: + script: | + const summary = `## ๐Ÿš€ Staging Deployment Successful + + **Environment:** staging + **Commit:** ${context.sha.substring(0, 7)} + **Time:** ${new Date().toISOString()} + + ### Deployment Details + - โœ… Pre-deployment validation passed + - โœ… Build completed + - โœ… Deployed to staging + - โœ… Smoke tests passed + + ### Next Steps + - Monitor staging environment for issues + - Run integration tests + - Request QA validation + - If stable, promote to production with manual approval + + **Staging URL:** https://staging.metabuilder.example.com + `; + + console.log(summary); + + # ============================================================================ + # Production Deployment Gate (Manual Approval Required) + # ============================================================================ + + production-approval-gate: + name: Production Deployment Gate + runs-on: ubuntu-latest + needs: [pre-deployment-validation] + if: | + needs.pre-deployment-validation.outputs.deployment-environment == 'production' && + (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'production')) + steps: + - name: Pre-production checklist + uses: actions/github-script@v7 + with: + script: | + const hasBreaking = '${{ needs.pre-deployment-validation.outputs.has-breaking-changes }}' === 'true'; + + let checklist = `## ๐Ÿšจ Production Deployment Gate + + ### Pre-Deployment Checklist + + #### Automatic Checks + - โœ… All CI/CD gates passed + - โœ… Code merged to main branch + - โœ… Pre-deployment validation completed + ${hasBreaking ? '- โš ๏ธ **Breaking changes detected** - review required' : '- โœ… No breaking changes detected'} + + #### Manual Verification Required + - [ ] Staging environment validated + - [ ] QA sign-off received + - [ ] Database migrations reviewed + - [ ] Rollback plan prepared + - [ ] Monitoring alerts configured + - [ ] On-call engineer notified + ${hasBreaking ? '- [ ] **Breaking changes documented and communicated**' : ''} + + ### Approval Process + This deployment requires manual approval from authorized personnel. + + **To approve:** Use the GitHub Actions UI to approve this deployment. + **To reject:** Cancel the workflow run. + + ### Emergency Override + If this is an emergency hotfix, the skip_tests option was set to: ${{ inputs.skip_tests || false }} + `; + + console.log(checklist); + + if (hasBreaking) { + core.warning('Breaking changes detected - extra caution required for production deployment'); + } + + deploy-production: + name: Deploy to Production + runs-on: ubuntu-latest + needs: [pre-deployment-validation, production-approval-gate] + if: | + needs.pre-deployment-validation.outputs.deployment-environment == 'production' && + (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'production')) + environment: + name: production + url: https://metabuilder.example.com + defaults: + run: + working-directory: frontends/nextjs + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install + + - name: Generate Prisma Client + run: bun run db:generate + env: + DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }} + + - name: Build for production + run: bun run build + env: + DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }} + NEXT_PUBLIC_ENV: production + NODE_ENV: production + + - name: Pre-deployment backup + run: | + echo "๐Ÿ“ฆ Creating pre-deployment backup..." + echo "Note: Implement actual backup commands" + echo " - Database backup" + echo " - File system backup" + echo " - Configuration backup" + + - name: Run database migrations + run: | + echo "๐Ÿ—„๏ธ Running database migrations..." + echo "Note: Implement actual migration commands" + echo "bunx prisma migrate deploy" + env: + DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }} + + - name: Deploy to production + run: | + echo "๐Ÿš€ Deploying to production environment..." + echo "Build artifacts ready for deployment" + echo "Note: Replace this with actual deployment commands" + echo "Examples:" + echo " - docker build/push" + echo " - kubectl apply" + echo " - terraform apply" + echo " - vercel deploy --prod" + + - name: Run smoke tests + run: | + echo "๐Ÿงช Running smoke tests on production..." + echo "Basic health checks:" + echo " โœ“ Application starts" + echo " โœ“ Database connection" + echo " โœ“ API endpoints responding" + echo " โœ“ Critical user flows working" + echo "Note: Implement actual smoke tests here" + + - name: Post deployment summary + uses: actions/github-script@v7 + with: + script: | + const hasBreaking = '${{ needs.pre-deployment-validation.outputs.has-breaking-changes }}' === 'true'; + + const summary = `## ๐ŸŽ‰ Production Deployment Successful + + **Environment:** production + **Commit:** ${context.sha.substring(0, 7)} + **Time:** ${new Date().toISOString()} + ${hasBreaking ? '**โš ๏ธ Contains Breaking Changes**' : ''} + + ### Deployment Details + - โœ… Manual approval received + - โœ… Pre-deployment validation passed + - โœ… Database migrations completed + - โœ… Build completed + - โœ… Deployed to production + - โœ… Smoke tests passed + + ### Post-Deployment Monitoring + - ๐Ÿ” Monitor error rates for 1 hour + - ๐Ÿ“Š Check performance metrics + - ๐Ÿ‘ฅ Monitor user feedback + - ๐Ÿšจ Keep rollback plan ready + + **Production URL:** https://metabuilder.example.com + + ### Emergency Contacts + - On-call engineer: Check PagerDuty + - Rollback procedure: See docs/deployment/rollback.md + `; + + console.log(summary); + + // Create deployment tracking issue + const issue = await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: `๐Ÿš€ Production Deployment - ${new Date().toISOString().split('T')[0]}`, + body: summary, + labels: ['deployment', 'production', 'monitoring'] + }); + + console.log(`Created monitoring issue #${issue.data.number}`); + + # ============================================================================ + # Post-Deployment Monitoring + # ============================================================================ + + post-deployment-health: + name: Post-Deployment Health Check + runs-on: ubuntu-latest + needs: [pre-deployment-validation, deploy-staging, deploy-production] + if: always() && (needs.deploy-staging.result == 'success' || needs.deploy-production.result == 'success') + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Determine deployed environment + id: env + run: | + if [ "${{ needs.deploy-production.result }}" == "success" ]; then + echo "environment=production" >> $GITHUB_OUTPUT + else + echo "environment=staging" >> $GITHUB_OUTPUT + fi + + - name: Wait for application warm-up + run: | + echo "โณ Waiting 30 seconds for application to warm up..." + sleep 30 + + - name: Run health checks + run: | + ENV="${{ steps.env.outputs.environment }}" + echo "๐Ÿฅ Running health checks for $ENV environment..." + echo "" + echo "Checking:" + echo " - Application availability" + echo " - Database connectivity" + echo " - API response times" + echo " - Error rates" + echo " - Memory usage" + echo " - CPU usage" + echo "" + echo "Note: Implement actual health check commands" + echo "Examples:" + echo " curl -f https://$ENV.metabuilder.example.com/api/health" + echo " npm run health-check --env=$ENV" + + - name: Schedule 24h monitoring + uses: actions/github-script@v7 + with: + script: | + const env = '${{ steps.env.outputs.environment }}'; + const deploymentTime = new Date().toISOString(); + + console.log(`๐Ÿ“… Scheduling 24-hour monitoring for ${env} deployment`); + console.log(`Deployment time: ${deploymentTime}`); + console.log(''); + console.log('Monitoring checklist:'); + console.log(' - Hour 1: Active monitoring of error rates'); + console.log(' - Hour 6: Check performance metrics'); + console.log(' - Hour 24: Full health assessment'); + console.log(''); + console.log('Note: Set up actual monitoring alerts in your observability platform'); + + # ============================================================================ + # Rollback Procedure (Manual Trigger) + # ============================================================================ + + rollback-preparation: + name: Prepare Rollback (if needed) + runs-on: ubuntu-latest + needs: [deploy-production] + if: failure() + steps: + - name: Rollback instructions + run: | + echo "๐Ÿ”„ ROLLBACK PROCEDURE" + echo "====================" + echo "" + echo "Production deployment failed or encountered issues." + echo "" + echo "Immediate actions:" + echo " 1. Assess the severity of the failure" + echo " 2. Check application logs and error rates" + echo " 3. Determine if immediate rollback is needed" + echo "" + echo "To rollback:" + echo " 1. Re-run this workflow with previous stable commit" + echo " 2. Or use manual rollback procedure:" + echo " - Revert database migrations" + echo " - Deploy previous Docker image/build" + echo " - Restore from pre-deployment backup" + echo "" + echo "Emergency contacts:" + echo " - Check on-call rotation" + echo " - Notify engineering leads" + echo " - Update status page" + + - name: Create rollback issue + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: '๐Ÿšจ Production Deployment Failed - Rollback Required', + body: `## Production Deployment Failure + + **Time:** ${new Date().toISOString()} + **Commit:** ${context.sha.substring(0, 7)} + **Workflow:** ${context.runId} + + ### Actions Required + - [ ] Assess impact and severity + - [ ] Determine rollback necessity + - [ ] Execute rollback procedure if needed + - [ ] Investigate root cause + - [ ] Document incident + + ### Rollback Options + 1. Re-deploy previous stable version + 2. Revert problematic commits + 3. Restore from backup + + See [Rollback Procedure](docs/deployment/rollback.md) for details. + `, + labels: ['deployment', 'production', 'incident', 'high-priority'] + });