-
Notifications
You must be signed in to change notification settings - Fork 0
484 lines (403 loc) · 16 KB
/
cd-with-e2e.yml
File metadata and controls
484 lines (403 loc) · 16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
name: Continuous Deployment with E2E Validation
on:
push:
branches: [ main ]
paths-ignore:
- '*.md'
- 'docs/**'
- '.github/**'
- '!.github/workflows/**'
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
skip_tests:
description: 'Skip E2E tests (emergency deployment)'
required: false
default: false
type: boolean
rollback_on_failure:
description: 'Auto-rollback on test failure'
required: false
default: true
type: boolean
env:
NODE_VERSION: '18'
DEPLOYMENT_TIMEOUT: 1800 # 30 minutes
jobs:
# Pre-deployment validation
pre-deployment:
name: Pre-deployment Validation
runs-on: ubuntu-latest
outputs:
deploy-environment: ${{ steps.config.outputs.environment }}
skip-tests: ${{ steps.config.outputs.skip_tests }}
deployment-id: ${{ steps.config.outputs.deployment_id }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure deployment
id: config
run: |
# Determine deployment environment
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
ENVIRONMENT="${{ github.event.inputs.environment }}"
SKIP_TESTS="${{ github.event.inputs.skip_tests }}"
else
ENVIRONMENT="staging"
SKIP_TESTS="false"
fi
DEPLOYMENT_ID="deploy-$(date +%Y%m%d-%H%M%S)-${GITHUB_SHA:0:8}"
echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT
echo "skip_tests=$SKIP_TESTS" >> $GITHUB_OUTPUT
echo "deployment_id=$DEPLOYMENT_ID" >> $GITHUB_OUTPUT
echo "🚀 Preparing deployment to $ENVIRONMENT"
echo "📋 Deployment ID: $DEPLOYMENT_ID"
echo "🧪 Skip tests: $SKIP_TESTS"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run pre-deployment checks
run: |
echo "🔍 Running pre-deployment checks..."
# Type checking
npm run type-check
# Linting
npm run lint
# Build validation
npm run build
# Check environment variables
if [[ "${{ steps.config.outputs.environment }}" == "production" ]]; then
echo "⚠️ Production deployment detected - additional validation required"
# Check for production-specific requirements
if [[ ! -f ".env.production" && ! -f ".env.local" ]]; then
echo "❌ Production environment configuration missing"
exit 1
fi
fi
echo "✅ Pre-deployment checks passed"
# Critical E2E tests before deployment
critical-e2e-tests:
name: Critical E2E Tests
runs-on: ubuntu-latest
needs: pre-deployment
if: needs.pre-deployment.outputs.skip-tests != 'true'
timeout-minutes: 20
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: |
npm ci
npx playwright install --with-deps chromium
- name: Start development server
run: |
npm run dev &
sleep 15
curl -f http://localhost:3001 || exit 1
- name: Run critical marketplace tests
run: |
echo "🧪 Running critical E2E tests for deployment validation..."
# Run only the most critical tests that validate core functionality
npx playwright test tests/e2e/marketplace/critical-path.spec.ts \
tests/e2e/marketplace/smoke-tests.spec.ts \
--reporter=html,junit \
--output-dir=test-results/critical
- name: Validate test results
run: |
# Check if any critical tests failed
if [[ -f "test-results/critical/results.xml" ]]; then
FAILURES=$(grep -c 'failure' test-results/critical/results.xml || echo "0")
if [[ "$FAILURES" -gt "0" ]]; then
echo "❌ Critical tests failed - blocking deployment"
exit 1
fi
fi
echo "✅ Critical E2E tests passed - deployment approved"
- name: Upload critical test results
uses: actions/upload-artifact@v4
if: always()
with:
name: critical-test-results
path: |
test-results/critical/
playwright-report/
retention-days: 7
# Staging deployment
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: [pre-deployment, critical-e2e-tests]
if: |
always() &&
needs.pre-deployment.result == 'success' &&
(needs.critical-e2e-tests.result == 'success' || needs.pre-deployment.outputs.skip-tests == 'true') &&
needs.pre-deployment.outputs.deploy-environment == 'staging'
environment:
name: staging
url: https://staging.swaggystacks.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build for staging
env:
NODE_ENV: production
NEXT_PUBLIC_ENV: staging
run: npm run build
- name: Deploy to staging
run: |
echo "🚀 Deploying to staging environment..."
echo "📋 Deployment ID: ${{ needs.pre-deployment.outputs.deployment-id }}"
# Simulate deployment process
# In real implementation, this would deploy to your staging infrastructure
echo "✅ Successfully deployed to staging"
# Store deployment metadata
echo "STAGING_DEPLOYMENT_URL=https://staging.swaggystacks.com" >> $GITHUB_ENV
echo "DEPLOYMENT_TIMESTAMP=$(date -Iseconds)" >> $GITHUB_ENV
# Production deployment
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [pre-deployment, critical-e2e-tests]
if: |
always() &&
needs.pre-deployment.result == 'success' &&
(needs.critical-e2e-tests.result == 'success' || needs.pre-deployment.outputs.skip-tests == 'true') &&
needs.pre-deployment.outputs.deploy-environment == 'production'
environment:
name: production
url: https://swaggystacks.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build for production
env:
NODE_ENV: production
NEXT_PUBLIC_ENV: production
run: npm run build
- name: Deploy to production
run: |
echo "🚀 Deploying to production environment..."
echo "📋 Deployment ID: ${{ needs.pre-deployment.outputs.deployment-id }}"
# Simulate blue-green deployment process
echo "🔵 Creating new production instance..."
sleep 5
echo "🔄 Switching traffic to new instance..."
sleep 3
echo "✅ Successfully deployed to production"
# Store deployment metadata
echo "PRODUCTION_DEPLOYMENT_URL=https://swaggystacks.com" >> $GITHUB_ENV
echo "DEPLOYMENT_TIMESTAMP=$(date -Iseconds)" >> $GITHUB_ENV
# Post-deployment E2E validation
post-deployment-validation:
name: Post-deployment E2E Validation
runs-on: ubuntu-latest
needs: [pre-deployment, deploy-staging, deploy-production]
if: |
always() &&
(needs.deploy-staging.result == 'success' || needs.deploy-production.result == 'success')
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: |
npm ci
npx playwright install --with-deps chromium
- name: Determine deployment URL
run: |
if [[ "${{ needs.pre-deployment.outputs.deploy-environment }}" == "production" ]]; then
echo "DEPLOYMENT_URL=https://swaggystacks.com" >> $GITHUB_ENV
echo "TEST_ENVIRONMENT=production" >> $GITHUB_ENV
else
echo "DEPLOYMENT_URL=https://staging.swaggystacks.com" >> $GITHUB_ENV
echo "TEST_ENVIRONMENT=staging" >> $GITHUB_ENV
fi
- name: Wait for deployment to be ready
run: |
echo "⏳ Waiting for deployment to be ready..."
# Wait for the deployment to respond
for i in {1..30}; do
if curl -f -s "$DEPLOYMENT_URL" > /dev/null; then
echo "✅ Deployment is responding"
break
fi
if [[ $i -eq 30 ]]; then
echo "❌ Deployment not responding after 5 minutes"
exit 1
fi
echo "Attempt $i/30 - waiting 10 seconds..."
sleep 10
done
- name: Run post-deployment smoke tests
env:
PLAYWRIGHT_BASE_URL: ${{ env.DEPLOYMENT_URL }}
run: |
echo "🧪 Running post-deployment validation tests..."
# Run comprehensive smoke tests against deployed environment
npx playwright test \
tests/e2e/marketplace/smoke-tests.spec.ts \
tests/e2e/pipeline/deployment-validation.spec.ts \
--reporter=html,junit \
--output-dir=test-results/post-deployment
- name: Run deployment-specific tests
env:
PLAYWRIGHT_BASE_URL: ${{ env.DEPLOYMENT_URL }}
TEST_ENVIRONMENT: ${{ env.TEST_ENVIRONMENT }}
run: |
# Test both organization routes
npx playwright test \
--grep="swaggystacks|scientia" \
--reporter=html \
--output-dir=test-results/organization-tests
- name: Validate SLA compliance
run: |
echo "📊 Validating SLA compliance..."
# Check response times
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' "$DEPLOYMENT_URL")
RESPONSE_MS=$(echo "$RESPONSE_TIME * 1000" | bc -l | cut -d. -f1)
echo "Response time: ${RESPONSE_MS}ms"
if [[ $RESPONSE_MS -gt 3000 ]]; then
echo "⚠️ Response time exceeds 3 second SLA"
else
echo "✅ Response time meets SLA"
fi
# Test both domains
curl -f "$DEPLOYMENT_URL/swaggystacks" || exit 1
curl -f "$DEPLOYMENT_URL/scientia" || exit 1
curl -f "$DEPLOYMENT_URL/marketplace" || exit 1
echo "✅ SLA validation passed"
- name: Upload post-deployment test results
uses: actions/upload-artifact@v4
if: always()
with:
name: post-deployment-results-${{ env.TEST_ENVIRONMENT }}
path: |
test-results/
playwright-report/
retention-days: 14
# Rollback on failure
rollback-on-failure:
name: Rollback on Failure
runs-on: ubuntu-latest
needs: [pre-deployment, deploy-staging, deploy-production, post-deployment-validation]
if: |
always() &&
(needs.deploy-staging.result == 'failure' ||
needs.deploy-production.result == 'failure' ||
needs.post-deployment-validation.result == 'failure') &&
github.event.inputs.rollback_on_failure != 'false'
steps:
- name: Initiate rollback
run: |
echo "🚨 Deployment failure detected - initiating rollback..."
echo "📋 Deployment ID: ${{ needs.pre-deployment.outputs.deployment-id }}"
ENVIRONMENT="${{ needs.pre-deployment.outputs.deploy-environment }}"
echo "🔄 Rolling back $ENVIRONMENT environment..."
# Simulate rollback process
if [[ "$ENVIRONMENT" == "production" ]]; then
echo "🔴 Rolling back production deployment..."
# In real implementation, this would trigger rollback to previous version
sleep 10
else
echo "🟡 Rolling back staging deployment..."
sleep 5
fi
echo "✅ Rollback completed successfully"
- name: Validate rollback
run: |
ENVIRONMENT="${{ needs.pre-deployment.outputs.deploy-environment }}"
if [[ "$ENVIRONMENT" == "production" ]]; then
ROLLBACK_URL="https://swaggystacks.com"
else
ROLLBACK_URL="https://staging.swaggystacks.com"
fi
echo "🔍 Validating rollback at $ROLLBACK_URL..."
# Wait for rollback to complete
sleep 30
# Verify the rollback worked
if curl -f -s "$ROLLBACK_URL" > /dev/null; then
echo "✅ Rollback validation successful"
else
echo "❌ Rollback validation failed"
exit 1
fi
- name: Notify rollback completion
run: |
echo "📢 Rollback completed for ${{ needs.pre-deployment.outputs.deploy-environment }}"
echo "🔗 GitHub Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# Deployment summary
deployment-summary:
name: Deployment Summary
runs-on: ubuntu-latest
needs: [pre-deployment, critical-e2e-tests, deploy-staging, deploy-production, post-deployment-validation, rollback-on-failure]
if: always()
steps:
- name: Generate deployment summary
run: |
echo "# 🚀 Deployment Summary" > deployment-summary.md
echo "" >> deployment-summary.md
echo "**Deployment ID:** ${{ needs.pre-deployment.outputs.deployment-id }}" >> deployment-summary.md
echo "**Environment:** ${{ needs.pre-deployment.outputs.deploy-environment }}" >> deployment-summary.md
echo "**Timestamp:** $(date -Iseconds)" >> deployment-summary.md
echo "" >> deployment-summary.md
echo "## Pipeline Results" >> deployment-summary.md
echo "- Pre-deployment: ${{ needs.pre-deployment.result }}" >> deployment-summary.md
echo "- Critical E2E Tests: ${{ needs.critical-e2e-tests.result }}" >> deployment-summary.md
echo "- Staging Deployment: ${{ needs.deploy-staging.result }}" >> deployment-summary.md
echo "- Production Deployment: ${{ needs.deploy-production.result }}" >> deployment-summary.md
echo "- Post-deployment Validation: ${{ needs.post-deployment-validation.result }}" >> deployment-summary.md
echo "- Rollback: ${{ needs.rollback-on-failure.result }}" >> deployment-summary.md
echo "" >> deployment-summary.md
# Determine overall status
if [[ "${{ needs.rollback-on-failure.result }}" == "success" ]]; then
echo "## ⚠️ Status: ROLLED BACK" >> deployment-summary.md
echo "Deployment failed and was automatically rolled back." >> deployment-summary.md
elif [[ "${{ needs.post-deployment-validation.result }}" == "success" ]]; then
echo "## ✅ Status: SUCCESSFUL" >> deployment-summary.md
echo "Deployment completed successfully and passed all validation tests." >> deployment-summary.md
else
echo "## ❌ Status: FAILED" >> deployment-summary.md
echo "Deployment failed. Manual intervention may be required." >> deployment-summary.md
fi
cat deployment-summary.md
- name: Upload deployment summary
uses: actions/upload-artifact@v4
with:
name: deployment-summary
path: deployment-summary.md
retention-days: 90