-
Notifications
You must be signed in to change notification settings - Fork 1
240 lines (209 loc) · 8.57 KB
/
cd.yml
File metadata and controls
240 lines (209 loc) · 8.57 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
name: CD Pipeline
on:
push:
branches: [ main ]
workflow_run:
workflows: ["CI Pipeline"]
branches: [ main ]
types: [completed]
permissions:
contents: read
deployments: write
issues: write
pull-requests: write
statuses: write
env:
NODE_VERSION: '20'
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
# Deploy to Staging (Preview)
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref != 'refs/heads/main'
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 Vercel CLI
run: npm install --global vercel@canary
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
id: deploy
run: |
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "preview_url=$url" >> $GITHUB_OUTPUT
- name: Comment PR with Preview URL
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🚀 **Preview Deployment Ready!**
Preview URL: ${{ steps.deploy.outputs.preview_url }}
This preview will be automatically updated when you push new changes to this PR.`
})
# Deploy to Production
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'))
environment:
name: production
url: ${{ steps.deploy.outputs.production_url }}
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 Vercel CLI
run: npm install --global vercel@canary
- name: Verify Vercel Secrets
run: |
echo "## Vercel Configuration Check" >> $GITHUB_STEP_SUMMARY
if [ -z "${{ secrets.VERCEL_TOKEN }}" ]; then
echo "❌ VERCEL_TOKEN secret not configured" >> $GITHUB_STEP_SUMMARY
echo "Please add it to GitHub secrets: https://github.com/SifatAli008/TOC-Simulator/settings/secrets/actions"
echo "Value should be: 4QoNVvLgxcN4UlrAeWXBn8Zc"
exit 1
fi
if [ -z "${{ secrets.VERCEL_ORG_ID }}" ]; then
echo "❌ VERCEL_ORG_ID secret not configured" >> $GITHUB_STEP_SUMMARY
echo "Please add VERCEL_ORG_ID: team_9eEABLbyiHLdJRpp2L5GTlZF"
exit 1
fi
if [ -z "${{ secrets.VERCEL_PROJECT_ID }}" ]; then
echo "❌ VERCEL_PROJECT_ID secret not configured" >> $GITHUB_STEP_SUMMARY
echo "Please add VERCEL_PROJECT_ID: prj_9Ec6A6C4B53fKo31K18r1bNdPARB"
exit 1
fi
echo "✅ All Vercel secrets configured" >> $GITHUB_STEP_SUMMARY
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Setup Environment Variables
run: |
echo "NEXT_PUBLIC_FIREBASE_API_KEY=build-mock-key" > .env.local
echo "NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=build.firebaseapp.com" >> .env.local
echo "NEXT_PUBLIC_FIREBASE_PROJECT_ID=build-project" >> .env.local
echo "NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=build.firebasestorage.app" >> .env.local
echo "NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789" >> .env.local
echo "NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789:web:buildmock" >> .env.local
echo "NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-BUILDMOCK" >> .env.local
- name: Deploy to Vercel
id: deploy
run: |
echo "Deploying directly to Vercel..."
url=$(vercel --prod --token=${{ secrets.VERCEL_TOKEN }} --yes)
echo "Deployment URL: $url"
echo "production_url=$url" >> $GITHUB_OUTPUT
- name: Create deployment status
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
try {
// Create a deployment record first
const deployment = await github.rest.repos.createDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha,
environment: 'production',
description: 'Production deployment',
auto_merge: false,
required_contexts: []
});
// Then create the deployment status
if (deployment.data.id) {
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.data.id,
state: 'success',
environment_url: '${{ steps.deploy.outputs.production_url }}',
description: 'Deployment completed successfully'
});
}
} catch (error) {
console.log('Deployment status creation failed:', error.message);
}
# Post-Deployment Tests
post-deploy-tests:
name: Post-Deployment Tests
runs-on: ubuntu-latest
needs: [deploy-production]
if: github.ref == 'refs/heads/main'
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 --legacy-peer-deps
- name: Verify deployment
run: |
echo "Deployment completed successfully"
echo "Production URL: ${{ needs.deploy-production.outputs.production_url }}"
# Notification
notify:
name: Deployment Notification
runs-on: ubuntu-latest
needs: [deploy-production, post-deploy-tests]
if: always() && github.ref == 'refs/heads/main'
permissions:
contents: write
issues: write
pull-requests: write
steps:
- name: Notify deployment status
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
try {
const deployResult = '${{ needs.deploy-production.result }}';
const testResult = '${{ needs.post-deploy-tests.result }}';
const status = deployResult === 'success' && testResult === 'success' ? '✅ Success' : '❌ Failed';
const url = '${{ needs.deploy-production.outputs.production_url }}' || 'URL not available';
const body = `🚀 **Deployment ${status}**
**Deployment Result**: ${deployResult}
**Tests Result**: ${testResult}
**Production URL**: ${url}
The TOC Simulator deployment process has completed!`;
await github.rest.repos.createCommitComment({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: context.sha,
body: body
});
console.log('Deployment notification sent successfully');
} catch (error) {
console.log('Failed to create deployment notification:', error.message);
// Try alternative notification method
try {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Deployment Status - ${new Date().toISOString()}`,
body: `Deployment completed with status: ${{ needs.deploy-production.result }}`
});
} catch (fallbackError) {
console.log('Fallback notification also failed:', fallbackError.message);
}
}