@odvi/create-dtt-framework 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/commands/create.d.ts.map +1 -1
  2. package/dist/commands/create.js +16 -13
  3. package/dist/commands/create.js.map +1 -1
  4. package/package.json +3 -2
  5. package/template/.env.example +103 -0
  6. package/template/components.json +22 -0
  7. package/template/docs/framework/01-overview.md +289 -0
  8. package/template/docs/framework/02-techstack.md +503 -0
  9. package/template/docs/framework/api-layer.md +681 -0
  10. package/template/docs/framework/clerk-authentication.md +649 -0
  11. package/template/docs/framework/cli-installation.md +564 -0
  12. package/template/docs/framework/deployment/ci-cd.md +907 -0
  13. package/template/docs/framework/deployment/digitalocean.md +991 -0
  14. package/template/docs/framework/deployment/domain-setup.md +972 -0
  15. package/template/docs/framework/deployment/environment-variables.md +863 -0
  16. package/template/docs/framework/deployment/monitoring.md +927 -0
  17. package/template/docs/framework/deployment/production-checklist.md +649 -0
  18. package/template/docs/framework/deployment/vercel.md +791 -0
  19. package/template/docs/framework/environment-variables.md +658 -0
  20. package/template/docs/framework/health-check-system.md +582 -0
  21. package/template/docs/framework/implementation.md +559 -0
  22. package/template/docs/framework/snowflake-integration.md +591 -0
  23. package/template/docs/framework/state-management.md +615 -0
  24. package/template/docs/framework/supabase-integration.md +581 -0
  25. package/template/docs/framework/testing-guide.md +544 -0
  26. package/template/docs/framework/what-did-i-miss.md +526 -0
  27. package/template/drizzle.config.ts +12 -0
  28. package/template/next.config.js +21 -0
  29. package/template/postcss.config.js +5 -0
  30. package/template/prettier.config.js +4 -0
  31. package/template/public/favicon.ico +0 -0
  32. package/template/src/app/(auth)/layout.tsx +4 -0
  33. package/template/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +10 -0
  34. package/template/src/app/(auth)/sign-up/[[...sign-up]]/page.tsx +10 -0
  35. package/template/src/app/(dashboard)/dashboard/page.tsx +8 -0
  36. package/template/src/app/(dashboard)/health/page.tsx +16 -0
  37. package/template/src/app/(dashboard)/layout.tsx +17 -0
  38. package/template/src/app/api/[[...route]]/route.ts +11 -0
  39. package/template/src/app/api/debug-files/route.ts +33 -0
  40. package/template/src/app/api/webhooks/clerk/route.ts +112 -0
  41. package/template/src/app/layout.tsx +28 -0
  42. package/template/src/app/page.tsx +12 -0
  43. package/template/src/app/providers.tsx +20 -0
  44. package/template/src/components/layouts/navbar.tsx +14 -0
  45. package/template/src/components/shared/loading-spinner.tsx +6 -0
  46. package/template/src/components/ui/badge.tsx +46 -0
  47. package/template/src/components/ui/button.tsx +62 -0
  48. package/template/src/components/ui/card.tsx +92 -0
  49. package/template/src/components/ui/collapsible.tsx +33 -0
  50. package/template/src/components/ui/scroll-area.tsx +58 -0
  51. package/template/src/components/ui/sheet.tsx +139 -0
  52. package/template/src/config/__tests__/env.test.ts +166 -0
  53. package/template/src/config/__tests__/site.test.ts +46 -0
  54. package/template/src/config/env.ts +36 -0
  55. package/template/src/config/site.ts +10 -0
  56. package/template/src/env.js +44 -0
  57. package/template/src/features/__tests__/health-check-config.test.ts +142 -0
  58. package/template/src/features/__tests__/health-check-types.test.ts +201 -0
  59. package/template/src/features/documentation/components/doc-sidebar.tsx +109 -0
  60. package/template/src/features/documentation/components/doc-viewer.tsx +70 -0
  61. package/template/src/features/documentation/index.tsx +92 -0
  62. package/template/src/features/documentation/utils/doc-loader.ts +177 -0
  63. package/template/src/features/health-check/components/health-dashboard.tsx +363 -0
  64. package/template/src/features/health-check/config.ts +72 -0
  65. package/template/src/features/health-check/index.ts +4 -0
  66. package/template/src/features/health-check/stores/health-store.ts +14 -0
  67. package/template/src/features/health-check/types.ts +18 -0
  68. package/template/src/hooks/__tests__/use-debounce.test.tsx +28 -0
  69. package/template/src/hooks/queries/use-health-checks.ts +16 -0
  70. package/template/src/hooks/utils/use-debounce.ts +20 -0
  71. package/template/src/lib/__tests__/utils.test.ts +52 -0
  72. package/template/src/lib/__tests__/validators.test.ts +114 -0
  73. package/template/src/lib/nextbank/client.ts +37 -0
  74. package/template/src/lib/snowflake/client.ts +53 -0
  75. package/template/src/lib/supabase/admin.ts +7 -0
  76. package/template/src/lib/supabase/client.ts +7 -0
  77. package/template/src/lib/supabase/server.ts +23 -0
  78. package/template/src/lib/utils.ts +6 -0
  79. package/template/src/lib/validators.ts +9 -0
  80. package/template/src/middleware.ts +22 -0
  81. package/template/src/server/api/index.ts +22 -0
  82. package/template/src/server/api/middleware/auth.ts +19 -0
  83. package/template/src/server/api/middleware/logger.ts +4 -0
  84. package/template/src/server/api/routes/health/clerk.ts +214 -0
  85. package/template/src/server/api/routes/health/database.ts +117 -0
  86. package/template/src/server/api/routes/health/edge-functions.ts +75 -0
  87. package/template/src/server/api/routes/health/framework.ts +45 -0
  88. package/template/src/server/api/routes/health/index.ts +102 -0
  89. package/template/src/server/api/routes/health/nextbank.ts +67 -0
  90. package/template/src/server/api/routes/health/snowflake.ts +83 -0
  91. package/template/src/server/api/routes/health/storage.ts +163 -0
  92. package/template/src/server/api/routes/users.ts +95 -0
  93. package/template/src/server/db/index.ts +17 -0
  94. package/template/src/server/db/queries/users.ts +8 -0
  95. package/template/src/server/db/schema/__tests__/health-checks.test.ts +31 -0
  96. package/template/src/server/db/schema/__tests__/users.test.ts +46 -0
  97. package/template/src/server/db/schema/health-checks.ts +11 -0
  98. package/template/src/server/db/schema/index.ts +2 -0
  99. package/template/src/server/db/schema/users.ts +16 -0
  100. package/template/src/server/db/schema.ts +26 -0
  101. package/template/src/stores/__tests__/ui-store.test.ts +87 -0
  102. package/template/src/stores/ui-store.ts +14 -0
  103. package/template/src/styles/globals.css +129 -0
  104. package/template/src/test/mocks/clerk.ts +35 -0
  105. package/template/src/test/mocks/snowflake.ts +28 -0
  106. package/template/src/test/mocks/supabase.ts +37 -0
  107. package/template/src/test/setup.ts +69 -0
  108. package/template/src/test/utils/test-helpers.ts +158 -0
  109. package/template/src/types/index.ts +14 -0
  110. package/template/tsconfig.json +43 -0
  111. package/template/vitest.config.ts +44 -0
@@ -0,0 +1,907 @@
1
+ # DTT Framework - CI/CD Setup Guide
2
+
3
+ ## Overview
4
+
5
+ This guide provides comprehensive instructions for setting up Continuous Integration and Continuous Deployment (CI/CD) for the DTT Framework using GitHub Actions. It covers automated testing, deployment, preview deployments, and branch protection rules.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [GitHub Actions Setup](#github-actions-setup)
12
+ 2. [Automated Testing](#automated-testing)
13
+ 3. [Automated Deployment](#automated-deployment)
14
+ 4. [Preview Deployments](#preview-deployments)
15
+ 5. [Branch Protection Rules](#branch-protection-rules)
16
+ 6. [Advanced CI/CD Patterns](#advanced-cicd-patterns)
17
+
18
+ ---
19
+
20
+ ## GitHub Actions Setup
21
+
22
+ ### Prerequisites
23
+
24
+ Before setting up CI/CD, ensure you have:
25
+
26
+ - **GitHub Repository**: Your code should be hosted on GitHub
27
+ - **Vercel Account**: For Vercel deployments
28
+ - **Vercel Token**: For authentication
29
+ - **Environment Variables**: Configured in GitHub Secrets
30
+
31
+ ### Step 1: Create GitHub Workflows Directory
32
+
33
+ ```bash
34
+ # Create workflows directory
35
+ mkdir -p .github/workflows
36
+ ```
37
+
38
+ ### Step 2: Get Vercel Credentials
39
+
40
+ #### Get Vercel Token
41
+
42
+ ```bash
43
+ # Install Vercel CLI
44
+ pnpm add -g vercel
45
+
46
+ # Login to Vercel
47
+ vercel login
48
+
49
+ # Get your token
50
+ vercel token create
51
+ # Copy the token and save it
52
+ ```
53
+
54
+ #### Get Project IDs
55
+
56
+ ```bash
57
+ # Link your project
58
+ vercel link
59
+
60
+ # Get project ID
61
+ cat .vercel/project.json
62
+ # Copy the "projectId" and "orgId"
63
+ ```
64
+
65
+ ### Step 3: Configure GitHub Secrets
66
+
67
+ 1. Go to **Repository** → **Settings** → **Secrets and variables** → **Actions**
68
+ 2. Add the following secrets:
69
+
70
+ | Secret Name | Description | Example |
71
+ |-------------|-------------|---------|
72
+ | `VERCEL_TOKEN` | Vercel authentication token | `xxx` |
73
+ | `VERCEL_ORG_ID` | Vercel organization ID | `team_xxx` |
74
+ | `VERCEL_PROJECT_ID` | Vercel project ID | `prj_xxx` |
75
+ | `DATABASE_URL` | Database connection string | `postgresql://...` |
76
+ | `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` | Clerk publishable key | `pk_live_xxx` |
77
+ | `CLERK_SECRET_KEY` | Clerk secret key | `sk_live_xxx` |
78
+ | `CLERK_WEBHOOK_SECRET` | Clerk webhook secret | `whsec_xxx` |
79
+ | `NEXT_PUBLIC_SUPABASE_URL` | Supabase URL | `https://xxx.supabase.co` |
80
+ | `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase anon key | `eyJxxx` |
81
+ | `SUPABASE_SERVICE_ROLE_KEY` | Supabase service role key | `eyJxxx` |
82
+
83
+ ---
84
+
85
+ ## Automated Testing
86
+
87
+ ### Step 1: Create Test Workflow
88
+
89
+ Create `.github/workflows/test.yml`:
90
+
91
+ ```yaml
92
+ name: Test
93
+
94
+ on:
95
+ push:
96
+ branches: [main, develop]
97
+ pull_request:
98
+ branches: [main, develop]
99
+
100
+ jobs:
101
+ test:
102
+ runs-on: ubuntu-latest
103
+
104
+ steps:
105
+ - name: Checkout code
106
+ uses: actions/checkout@v4
107
+
108
+ - name: Setup Node.js
109
+ uses: actions/setup-node@v4
110
+ with:
111
+ node-version: '20'
112
+ cache: 'pnpm'
113
+
114
+ - name: Install pnpm
115
+ uses: pnpm/action-setup@v2
116
+ with:
117
+ version: 10
118
+
119
+ - name: Install dependencies
120
+ run: pnpm install --frozen-lockfile
121
+
122
+ - name: Run linting
123
+ run: pnpm lint
124
+
125
+ - name: Run type checking
126
+ run: pnpm type-check
127
+
128
+ - name: Run unit tests
129
+ run: pnpm test:unit
130
+
131
+ - name: Run integration tests
132
+ run: pnpm test:integration
133
+ env:
134
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
135
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
136
+ CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
137
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
138
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
139
+ SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
140
+
141
+ - name: Upload coverage reports
142
+ uses: codecov/codecov-action@v4
143
+ with:
144
+ file: ./coverage/lcov.info
145
+ flags: unittests
146
+ name: codecov-umbrella
147
+ ```
148
+
149
+ ### Step 2: Configure Test Scripts
150
+
151
+ Add test scripts to `package.json`:
152
+
153
+ ```json
154
+ {
155
+ "scripts": {
156
+ "lint": "eslint . --ext .ts,.tsx",
157
+ "type-check": "tsc --noEmit",
158
+ "test": "vitest",
159
+ "test:unit": "vitest run --coverage",
160
+ "test:integration": "vitest run --config vitest.integration.config.ts",
161
+ "test:watch": "vitest"
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Step 3: Test Workflow Features
167
+
168
+ | Feature | Description |
169
+ |---------|-------------|
170
+ | **Triggered on push** | Runs on every push to main/develop |
171
+ | **Triggered on PR** | Runs on every pull request |
172
+ | **Linting** | Checks code style |
173
+ | **Type checking** | Verifies TypeScript types |
174
+ | **Unit tests** | Runs unit tests |
175
+ | **Integration tests** | Runs integration tests |
176
+ | **Coverage upload** | Uploads coverage to Codecov |
177
+
178
+ ---
179
+
180
+ ## Automated Deployment
181
+
182
+ ### Step 1: Create Production Deployment Workflow
183
+
184
+ Create `.github/workflows/deploy-production.yml`:
185
+
186
+ ```yaml
187
+ name: Deploy to Production
188
+
189
+ on:
190
+ push:
191
+ branches: [main]
192
+ workflow_dispatch:
193
+
194
+ jobs:
195
+ deploy:
196
+ runs-on: ubuntu-latest
197
+
198
+ steps:
199
+ - name: Checkout code
200
+ uses: actions/checkout@v4
201
+
202
+ - name: Setup Node.js
203
+ uses: actions/setup-node@v4
204
+ with:
205
+ node-version: '20'
206
+ cache: 'pnpm'
207
+
208
+ - name: Install pnpm
209
+ uses: pnpm/action-setup@v2
210
+ with:
211
+ version: 10
212
+
213
+ - name: Install dependencies
214
+ run: pnpm install --frozen-lockfile
215
+
216
+ - name: Run tests
217
+ run: pnpm test
218
+ env:
219
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
220
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
221
+ CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
222
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
223
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
224
+ SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
225
+
226
+ - name: Build application
227
+ run: pnpm build
228
+ env:
229
+ NEXT_PUBLIC_APP_URL: ${{ secrets.NEXT_PUBLIC_APP_URL }}
230
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
231
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
232
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
233
+
234
+ - name: Deploy to Vercel Production
235
+ uses: amondnet/vercel-action@v25
236
+ with:
237
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
238
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
239
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
240
+ vercel-args: '--prod'
241
+ working-directory: ./
242
+
243
+ - name: Run database migrations
244
+ run: pnpm db:push
245
+ env:
246
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
247
+
248
+ - name: Notify deployment status
249
+ if: always()
250
+ uses: 8398a7/action-slack@v3
251
+ with:
252
+ status: ${{ job.status }}
253
+ text: 'Production deployment ${{ job.status }}'
254
+ webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
255
+ ```
256
+
257
+ ### Step 2: Create Staging Deployment Workflow
258
+
259
+ Create `.github/workflows/deploy-staging.yml`:
260
+
261
+ ```yaml
262
+ name: Deploy to Staging
263
+
264
+ on:
265
+ push:
266
+ branches: [develop]
267
+ workflow_dispatch:
268
+
269
+ jobs:
270
+ deploy:
271
+ runs-on: ubuntu-latest
272
+
273
+ steps:
274
+ - name: Checkout code
275
+ uses: actions/checkout@v4
276
+
277
+ - name: Setup Node.js
278
+ uses: actions/setup-node@v4
279
+ with:
280
+ node-version: '20'
281
+ cache: 'pnpm'
282
+
283
+ - name: Install pnpm
284
+ uses: pnpm/action-setup@v2
285
+ with:
286
+ version: 10
287
+
288
+ - name: Install dependencies
289
+ run: pnpm install --frozen-lockfile
290
+
291
+ - name: Run tests
292
+ run: pnpm test
293
+ env:
294
+ DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
295
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.STAGING_CLERK_PUBLISHABLE_KEY }}
296
+ CLERK_SECRET_KEY: ${{ secrets.STAGING_CLERK_SECRET_KEY }}
297
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.STAGING_SUPABASE_URL }}
298
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.STAGING_SUPABASE_ANON_KEY }}
299
+ SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.STAGING_SUPABASE_SERVICE_ROLE_KEY }}
300
+
301
+ - name: Build application
302
+ run: pnpm build
303
+ env:
304
+ NEXT_PUBLIC_APP_URL: ${{ secrets.STAGING_APP_URL }}
305
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.STAGING_CLERK_PUBLISHABLE_KEY }}
306
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.STAGING_SUPABASE_URL }}
307
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.STAGING_SUPABASE_ANON_KEY }}
308
+
309
+ - name: Deploy to Vercel Staging
310
+ uses: amondnet/vercel-action@v25
311
+ with:
312
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
313
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
314
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
315
+ vercel-args: '--scope=your-team'
316
+ working-directory: ./
317
+
318
+ - name: Run database migrations
319
+ run: pnpm db:push
320
+ env:
321
+ DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
322
+
323
+ - name: Run smoke tests
324
+ run: pnpm test:smoke
325
+ env:
326
+ STAGING_URL: ${{ secrets.STAGING_APP_URL }}
327
+ ```
328
+
329
+ ### Step 3: Deployment Workflow Features
330
+
331
+ | Feature | Production | Staging |
332
+ |---------|------------|---------|
333
+ | **Trigger** | Push to main | Push to develop |
334
+ | **Manual trigger** | Yes | Yes |
335
+ | **Run tests** | Yes | Yes |
336
+ | **Build** | Yes | Yes |
337
+ | **Deploy** | Vercel --prod | Vercel preview |
338
+ | **Migrations** | Yes | Yes |
339
+ | **Smoke tests** | Optional | Yes |
340
+ | **Notifications** | Yes | Optional |
341
+
342
+ ---
343
+
344
+ ## Preview Deployments
345
+
346
+ ### Step 1: Create Preview Deployment Workflow
347
+
348
+ Create `.github/workflows/deploy-preview.yml`:
349
+
350
+ ```yaml
351
+ name: Deploy Preview
352
+
353
+ on:
354
+ pull_request:
355
+ types: [opened, synchronize, reopened]
356
+
357
+ jobs:
358
+ deploy-preview:
359
+ runs-on: ubuntu-latest
360
+
361
+ steps:
362
+ - name: Checkout code
363
+ uses: actions/checkout@v4
364
+
365
+ - name: Setup Node.js
366
+ uses: actions/setup-node@v4
367
+ with:
368
+ node-version: '20'
369
+ cache: 'pnpm'
370
+
371
+ - name: Install pnpm
372
+ uses: pnpm/action-setup@v2
373
+ with:
374
+ version: 10
375
+
376
+ - name: Install dependencies
377
+ run: pnpm install --frozen-lockfile
378
+
379
+ - name: Run tests
380
+ run: pnpm test
381
+ env:
382
+ DATABASE_URL: ${{ secrets.DATABASE_URL }}
383
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
384
+ CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
385
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
386
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
387
+ SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }}
388
+
389
+ - name: Build application
390
+ run: pnpm build
391
+ env:
392
+ NEXT_PUBLIC_APP_URL: https://preview-${{ github.event.number }}.your-app.com
393
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY }}
394
+ NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
395
+ NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
396
+
397
+ - name: Deploy to Vercel Preview
398
+ id: vercel
399
+ uses: amondnet/vercel-action@v25
400
+ with:
401
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
402
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
403
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
404
+ vercel-args: '--scope=your-team'
405
+ working-directory: ./
406
+
407
+ - name: Comment PR with preview URL
408
+ uses: actions/github-script@v7
409
+ with:
410
+ script: |
411
+ github.rest.issues.createComment({
412
+ issue_number: context.issue.number,
413
+ owner: context.repo.owner,
414
+ repo: context.repo.repo,
415
+ body: `🚀 Preview deployment ready!\n\nURL: ${{ steps.vercel.outputs.preview-url }}`
416
+ })
417
+ ```
418
+
419
+ ### Step 2: Configure Preview Deployments in Vercel
420
+
421
+ 1. Go to **Settings** → **Git**
422
+ 2. Enable **"Preview Deployments"**
423
+ 3. Configure preview branch settings:
424
+ - **Branch**: `*` (all branches)
425
+ - **Environment**: Preview
426
+ - **Automatic**: Yes
427
+
428
+ ### Step 3: Preview Deployment Features
429
+
430
+ | Feature | Description |
431
+ |---------|-------------|
432
+ | **Auto-created** | Created for every PR |
433
+ | **Unique URL** | Each PR gets unique URL |
434
+ | **Auto-comment** | URL posted to PR |
435
+ | **Auto-deleted** | Deleted when PR closes |
436
+ | **Environment** | Uses preview environment variables |
437
+
438
+ ---
439
+
440
+ ## Branch Protection Rules
441
+
442
+ ### Step 1: Configure Branch Protection
443
+
444
+ 1. Go to **Repository** → **Settings** → **Branches**
445
+ 2. Click **"Add rule"**
446
+ 3. Enter branch name pattern: `main`
447
+ 4. Configure protection rules:
448
+
449
+ ### Required Branch Protection Settings
450
+
451
+ | Setting | Value | Description |
452
+ |---------|-------|-------------|
453
+ | **Require pull request** | ✅ Yes | Require PR before merging |
454
+ | **Require approvals** | ✅ Yes | Minimum 1 approval |
455
+ | **Dismiss stale approvals** | ✅ Yes | Re-approve on new commits |
456
+ | **Require status checks** | ✅ Yes | Require CI to pass |
457
+ | **Require branches to be up to date** | ✅ Yes | Must be up to date with main |
458
+ | **Do not allow bypassing** | ✅ Yes | Enforce rules for all users |
459
+ | **Require signed commits** | Optional | Require GPG signatures |
460
+ | **Include administrators** | ✅ Yes | Apply rules to admins |
461
+ | **Allow force pushes** | ❌ No | Prevent force pushes |
462
+ | **Allow deletions** | ❌ No | Prevent branch deletion |
463
+
464
+ ### Step 2: Configure Required Status Checks
465
+
466
+ Add the following required checks:
467
+
468
+ | Check Name | Description |
469
+ |-------------|-------------|
470
+ | `Test` | Unit and integration tests |
471
+ | `Lint` | Code linting |
472
+ | `Type Check` | TypeScript type checking |
473
+ | `Build` | Application build |
474
+
475
+ ### Step 3: Configure Branch Protection via API
476
+
477
+ Use GitHub CLI to configure branch protection:
478
+
479
+ ```bash
480
+ # Install GitHub CLI
481
+ # https://cli.github.com/
482
+
483
+ # Authenticate
484
+ gh auth login
485
+
486
+ # Configure branch protection
487
+ gh api repos/:owner/:repo/branches/main/protection \
488
+ --method PUT \
489
+ -H "Accept: application/vnd.github+json" \
490
+ -f required_status_checks='{
491
+ "strict": true,
492
+ "contexts": ["Test", "Lint", "Type Check", "Build"]
493
+ }' \
494
+ -f enforce_admins=true \
495
+ -f required_pull_request_reviews='{
496
+ "required_approving_review_count": 1,
497
+ "dismiss_stale_reviews": true,
498
+ "require_code_owner_reviews": false
499
+ }' \
500
+ -f restrictions=null \
501
+ -f allow_force_pushes=false \
502
+ -f allow_deletions=false
503
+ ```
504
+
505
+ ### Step 4: Branch Protection Best Practices
506
+
507
+ | Practice | Description |
508
+ |-----------|-------------|
509
+ | **Require PRs** | All changes go through PRs |
510
+ | **Require approvals** | At least one review required |
511
+ | **Require CI** | All checks must pass |
512
+ | **Keep up to date** | PRs must be up to date |
513
+ | **No force pushes** | Prevent history rewrites |
514
+ | **No deletions** | Prevent accidental deletion |
515
+
516
+ ---
517
+
518
+ ## Advanced CI/CD Patterns
519
+
520
+ ### Pattern 1: Monorepo Support
521
+
522
+ For monorepo setups using Turborepo:
523
+
524
+ ```yaml
525
+ name: Monorepo CI
526
+
527
+ on:
528
+ push:
529
+ branches: [main]
530
+ pull_request:
531
+
532
+ jobs:
533
+ ci:
534
+ runs-on: ubuntu-latest
535
+ steps:
536
+ - uses: actions/checkout@v4
537
+
538
+ - name: Setup Node.js
539
+ uses: actions/setup-node@v4
540
+ with:
541
+ node-version: '20'
542
+
543
+ - name: Install pnpm
544
+ uses: pnpm/action-setup@v2
545
+ with:
546
+ version: 10
547
+
548
+ - name: Install Turborepo
549
+ run: pnpm add -g turbo
550
+
551
+ - name: Install dependencies
552
+ run: pnpm install
553
+
554
+ - name: Run affected tests
555
+ run: turbo test --filter=[HEAD~1]
556
+
557
+ - name: Run affected builds
558
+ run: turbo build --filter=[HEAD~1]
559
+ ```
560
+
561
+ ### Pattern 2: Multi-Environment Deployment
562
+
563
+ Deploy to multiple environments:
564
+
565
+ ```yaml
566
+ name: Multi-Environment Deploy
567
+
568
+ on:
569
+ push:
570
+ branches: [main, develop, staging]
571
+
572
+ jobs:
573
+ deploy:
574
+ runs-on: ubuntu-latest
575
+ steps:
576
+ - uses: actions/checkout@v4
577
+
578
+ - name: Setup Node.js
579
+ uses: actions/setup-node@v4
580
+ with:
581
+ node-version: '20'
582
+
583
+ - name: Install pnpm
584
+ uses: pnpm/action-setup@v2
585
+ with:
586
+ version: 10
587
+
588
+ - name: Install dependencies
589
+ run: pnpm install
590
+
591
+ - name: Build
592
+ run: pnpm build
593
+
594
+ - name: Deploy to Production
595
+ if: github.ref == 'refs/heads/main'
596
+ uses: amondnet/vercel-action@v25
597
+ with:
598
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
599
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
600
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
601
+ vercel-args: '--prod'
602
+
603
+ - name: Deploy to Staging
604
+ if: github.ref == 'refs/heads/staging'
605
+ uses: amondnet/vercel-action@v25
606
+ with:
607
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
608
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
609
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
610
+
611
+ - name: Deploy to Development
612
+ if: github.ref == 'refs/heads/develop'
613
+ uses: amondnet/vercel-action@v25
614
+ with:
615
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
616
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
617
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
618
+ ```
619
+
620
+ ### Pattern 3: Database Migration Workflow
621
+
622
+ Separate workflow for database migrations:
623
+
624
+ ```yaml
625
+ name: Database Migrations
626
+
627
+ on:
628
+ workflow_dispatch:
629
+ inputs:
630
+ environment:
631
+ description: 'Environment to migrate'
632
+ required: true
633
+ default: 'production'
634
+ type: choice
635
+ options:
636
+ - production
637
+ - staging
638
+ - development
639
+
640
+ jobs:
641
+ migrate:
642
+ runs-on: ubuntu-latest
643
+ steps:
644
+ - uses: actions/checkout@v4
645
+
646
+ - name: Setup Node.js
647
+ uses: actions/setup-node@v4
648
+ with:
649
+ node-version: '20'
650
+
651
+ - name: Install pnpm
652
+ uses: pnpm/action-setup@v2
653
+ with:
654
+ version: 10
655
+
656
+ - name: Install dependencies
657
+ run: pnpm install
658
+
659
+ - name: Run migrations
660
+ run: pnpm db:push
661
+ env:
662
+ DATABASE_URL: ${{ secrets[format('{0}_DATABASE_URL', github.event.inputs.environment)] }}
663
+ ```
664
+
665
+ ### Pattern 4: Rollback Workflow
666
+
667
+ Automated rollback workflow:
668
+
669
+ ```yaml
670
+ name: Rollback Deployment
671
+
672
+ on:
673
+ workflow_dispatch:
674
+ inputs:
675
+ commit_sha:
676
+ description: 'Commit SHA to rollback to'
677
+ required: true
678
+ environment:
679
+ description: 'Environment to rollback'
680
+ required: true
681
+ default: 'production'
682
+ type: choice
683
+ options:
684
+ - production
685
+ - staging
686
+
687
+ jobs:
688
+ rollback:
689
+ runs-on: ubuntu-latest
690
+ steps:
691
+ - uses: actions/checkout@v4
692
+ with:
693
+ ref: ${{ github.event.inputs.commit_sha }}
694
+
695
+ - name: Setup Node.js
696
+ uses: actions/setup-node@v4
697
+ with:
698
+ node-version: '20'
699
+
700
+ - name: Install pnpm
701
+ uses: pnpm/action-setup@v2
702
+ with:
703
+ version: 10
704
+
705
+ - name: Install dependencies
706
+ run: pnpm install
707
+
708
+ - name: Build
709
+ run: pnpm build
710
+
711
+ - name: Deploy rollback
712
+ uses: amondnet/vercel-action@v25
713
+ with:
714
+ vercel-token: ${{ secrets.VERCEL_TOKEN }}
715
+ vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
716
+ vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
717
+ vercel-args: '--prod'
718
+
719
+ - name: Notify rollback
720
+ uses: 8398a7/action-slack@v3
721
+ with:
722
+ status: 'success'
723
+ text: 'Rollback to ${{ github.event.inputs.commit_sha }} completed'
724
+ webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
725
+ ```
726
+
727
+ ### Pattern 5: Scheduled Maintenance Workflow
728
+
729
+ Scheduled health checks and maintenance:
730
+
731
+ ```yaml
732
+ name: Scheduled Maintenance
733
+
734
+ on:
735
+ schedule:
736
+ - cron: '0 2 * * *' # Daily at 2 AM UTC
737
+ workflow_dispatch:
738
+
739
+ jobs:
740
+ health-check:
741
+ runs-on: ubuntu-latest
742
+ steps:
743
+ - name: Check production health
744
+ run: |
745
+ response=$(curl -s -o /dev/null -w "%{http_code}" https://your-app.com/api/health)
746
+ if [ $response -ne 200 ]; then
747
+ echo "Health check failed!"
748
+ exit 1
749
+ fi
750
+
751
+ - name: Check database connection
752
+ run: |
753
+ psql ${{ secrets.DATABASE_URL }} -c "SELECT 1"
754
+
755
+ - name: Run database backups
756
+ run: |
757
+ pg_dump ${{ secrets.DATABASE_URL }} > backup_$(date +%Y%m%d).sql
758
+
759
+ - name: Notify maintenance status
760
+ if: always()
761
+ uses: 8398a7/action-slack@v3
762
+ with:
763
+ status: ${{ job.status }}
764
+ text: 'Scheduled maintenance ${{ job.status }}'
765
+ webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
766
+ ```
767
+
768
+ ---
769
+
770
+ ## CI/CD Best Practices
771
+
772
+ ### 1. Use Caching
773
+
774
+ Cache dependencies to speed up builds:
775
+
776
+ ```yaml
777
+ - name: Setup Node.js
778
+ uses: actions/setup-node@v4
779
+ with:
780
+ node-version: '20'
781
+ cache: 'pnpm'
782
+ ```
783
+
784
+ ### 2. Parallel Jobs
785
+
786
+ Run tests in parallel:
787
+
788
+ ```yaml
789
+ jobs:
790
+ test:
791
+ runs-on: ubuntu-latest
792
+ strategy:
793
+ matrix:
794
+ node-version: [18, 20]
795
+ steps:
796
+ - uses: actions/checkout@v4
797
+ - name: Setup Node.js
798
+ uses: actions/setup-node@v4
799
+ with:
800
+ node-version: ${{ matrix.node-version }}
801
+ ```
802
+
803
+ ### 3. Conditional Deployments
804
+
805
+ Only deploy on specific conditions:
806
+
807
+ ```yaml
808
+ - name: Deploy
809
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
810
+ uses: amondnet/vercel-action@v25
811
+ ```
812
+
813
+ ### 4. Artifact Upload
814
+
815
+ Upload build artifacts:
816
+
817
+ ```yaml
818
+ - name: Upload build artifacts
819
+ uses: actions/upload-artifact@v4
820
+ with:
821
+ name: build
822
+ path: .next/
823
+ ```
824
+
825
+ ### 5. Notification Integration
826
+
827
+ Integrate with Slack, Discord, etc.:
828
+
829
+ ```yaml
830
+ - name: Notify Slack
831
+ uses: 8398a7/action-slack@v3
832
+ with:
833
+ status: ${{ job.status }}
834
+ text: 'Deployment ${{ job.status }}'
835
+ webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
836
+ ```
837
+
838
+ ---
839
+
840
+ ## Troubleshooting
841
+
842
+ ### Issue: Workflow Fails on Environment Variables
843
+
844
+ **Symptoms:**
845
+ - Workflow fails during build
846
+ - Environment variable errors
847
+
848
+ **Solutions:**
849
+
850
+ ```bash
851
+ # Verify secrets are set
852
+ gh secret list
853
+
854
+ # Check secret names match exactly
855
+ # Case-sensitive names
856
+
857
+ # Verify secrets are accessible
858
+ # Check repository permissions
859
+ ```
860
+
861
+ ### Issue: Deployment Fails Due to Tests
862
+
863
+ **Symptoms:**
864
+ - Tests fail in CI but pass locally
865
+ - Flaky tests
866
+
867
+ **Solutions:**
868
+
869
+ ```yaml
870
+ # Add retry logic
871
+ - name: Run tests
872
+ run: pnpm test
873
+ continue-on-error: false
874
+
875
+ # Use test retries
876
+ # Configure in vitest.config.ts
877
+ ```
878
+
879
+ ### Issue: Preview Deployments Not Created
880
+
881
+ **Symptoms:**
882
+ - PRs don't create preview deployments
883
+ - No preview URL in PR comments
884
+
885
+ **Solutions:**
886
+
887
+ ```bash
888
+ # Check Vercel Git integration
889
+ # Settings → Git → Preview Deployments
890
+
891
+ # Verify Vercel credentials
892
+ # Check VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID
893
+
894
+ # Check workflow permissions
895
+ # Repository → Settings → Actions → General → Workflow permissions
896
+ ```
897
+
898
+ ---
899
+
900
+ ## Related Documentation
901
+
902
+ - [Vercel Deployment](./vercel.md) - Vercel deployment guide
903
+ - [DigitalOcean Deployment](./digitalocean.md) - DigitalOcean deployment guide
904
+ - [Environment Variables](./environment-variables.md) - Complete variable reference
905
+ - [Production Checklist](./production-checklist.md) - Pre-deployment checklist
906
+ - [Monitoring](./monitoring.md) - Monitoring and alerting setup
907
+ - [Testing Guide](../testing-guide.md) - Testing patterns and practices