1
+ name : Deploy MCP Web Interface
2
+
3
+ on :
4
+ push :
5
+ branches : [main]
6
+ tags : ['v*']
7
+ pull_request :
8
+ branches : [main]
9
+
10
+ env :
11
+ NODE_VERSION : ' 18'
12
+ REGISTRY : ghcr.io
13
+ IMAGE_NAME : ${{ github.repository }}
14
+
15
+ jobs :
16
+ test :
17
+ runs-on : ubuntu-latest
18
+ steps :
19
+ - uses : actions/checkout@v4
20
+
21
+ - name : Setup Node.js
22
+ uses : actions/setup-node@v4
23
+ with :
24
+ node-version : ${{ env.NODE_VERSION }}
25
+ cache : ' npm'
26
+ cache-dependency-path : web/package-lock.json
27
+
28
+ - name : Install dependencies
29
+ run : |
30
+ cd web
31
+ npm ci
32
+
33
+ - name : Run type check
34
+ run : |
35
+ cd web
36
+ npm run type-check
37
+
38
+ - name : Run linting
39
+ run : |
40
+ cd web
41
+ npm run lint
42
+
43
+ - name : Run tests
44
+ run : |
45
+ cd web
46
+ npm run test:all
47
+
48
+ build :
49
+ needs : test
50
+ runs-on : ubuntu-latest
51
+ outputs :
52
+ image : ${{ steps.image.outputs.image }}
53
+ digest : ${{ steps.build.outputs.digest }}
54
+ steps :
55
+ - uses : actions/checkout@v4
56
+
57
+ - name : Setup Node.js
58
+ uses : actions/setup-node@v4
59
+ with :
60
+ node-version : ${{ env.NODE_VERSION }}
61
+ cache : ' npm'
62
+ cache-dependency-path : web/package-lock.json
63
+
64
+ - name : Install dependencies
65
+ run : |
66
+ cd web
67
+ npm ci
68
+
69
+ - name : Build application
70
+ run : |
71
+ cd web
72
+ npm run build:production
73
+ env :
74
+ NODE_ENV : production
75
+
76
+ - name : Upload build artifacts
77
+ uses : actions/upload-artifact@v4
78
+ with :
79
+ name : build-files
80
+ path : web/dist/
81
+ retention-days : 7
82
+
83
+ - name : Set up Docker Buildx
84
+ uses : docker/setup-buildx-action@v3
85
+
86
+ - name : Log in to Container Registry
87
+ uses : docker/login-action@v3
88
+ with :
89
+ registry : ${{ env.REGISTRY }}
90
+ username : ${{ github.actor }}
91
+ password : ${{ secrets.GITHUB_TOKEN }}
92
+
93
+ - name : Extract metadata
94
+ id : meta
95
+ uses : docker/metadata-action@v5
96
+ with :
97
+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
98
+ tags : |
99
+ type=ref,event=branch
100
+ type=ref,event=pr
101
+ type=semver,pattern={{version}}
102
+ type=semver,pattern={{major}}.{{minor}}
103
+ type=sha
104
+
105
+ - name : Build and push Docker image
106
+ id : build
107
+ uses : docker/build-push-action@v5
108
+ with :
109
+ context : ./web
110
+ push : true
111
+ tags : ${{ steps.meta.outputs.tags }}
112
+ labels : ${{ steps.meta.outputs.labels }}
113
+ cache-from : type=gha
114
+ cache-to : type=gha,mode=max
115
+ platforms : linux/amd64,linux/arm64
116
+
117
+ - name : Output image
118
+ id : image
119
+ run : |
120
+ echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" >> $GITHUB_OUTPUT
121
+
122
+ deploy-vercel :
123
+ needs : build
124
+ runs-on : ubuntu-latest
125
+ if : github.ref == 'refs/heads/main'
126
+ steps :
127
+ - uses : actions/checkout@v4
128
+
129
+ - name : Download build artifacts
130
+ uses : actions/download-artifact@v4
131
+ with :
132
+ name : build-files
133
+ path : web/dist/
134
+
135
+ - name : Deploy to Vercel
136
+ uses : amondnet/vercel-action@v25
137
+ with :
138
+ vercel-token : ${{ secrets.VERCEL_TOKEN }}
139
+ vercel-org-id : ${{ secrets.VERCEL_ORG_ID }}
140
+ vercel-project-id : ${{ secrets.VERCEL_PROJECT_ID }}
141
+ working-directory : ./web
142
+ vercel-args : ' --prod'
143
+
144
+ deploy-netlify :
145
+ needs : build
146
+ runs-on : ubuntu-latest
147
+ if : github.ref == 'refs/heads/main'
148
+ steps :
149
+ - uses : actions/checkout@v4
150
+
151
+ - name : Download build artifacts
152
+ uses : actions/download-artifact@v4
153
+ with :
154
+ name : build-files
155
+ path : web/dist/
156
+
157
+ - name : Deploy to Netlify
158
+ uses : nwtgck/actions-netlify@v3.0
159
+ with :
160
+ publish-dir : ' ./web/dist'
161
+ production-branch : main
162
+ github-token : ${{ secrets.GITHUB_TOKEN }}
163
+ deploy-message : " Deploy from GitHub Actions"
164
+ enable-pull-request-comment : false
165
+ enable-commit-comment : true
166
+ overwrites-pull-request-comment : true
167
+ env :
168
+ NETLIFY_AUTH_TOKEN : ${{ secrets.NETLIFY_AUTH_TOKEN }}
169
+ NETLIFY_SITE_ID : ${{ secrets.NETLIFY_SITE_ID }}
170
+
171
+ deploy-aws :
172
+ needs : build
173
+ runs-on : ubuntu-latest
174
+ if : github.ref == 'refs/heads/main'
175
+ steps :
176
+ - uses : actions/checkout@v4
177
+
178
+ - name : Configure AWS credentials
179
+ uses : aws-actions/configure-aws-credentials@v4
180
+ with :
181
+ aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
182
+ aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
183
+ aws-region : us-east-1
184
+
185
+ - name : Download build artifacts
186
+ uses : actions/download-artifact@v4
187
+ with :
188
+ name : build-files
189
+ path : web/dist/
190
+
191
+ - name : Deploy to S3
192
+ run : |
193
+ aws s3 sync web/dist/ s3://${{ secrets.AWS_S3_BUCKET }} --delete
194
+
195
+ - name : Invalidate CloudFront
196
+ run : |
197
+ aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"
198
+
199
+ deploy-docker :
200
+ needs : build
201
+ runs-on : ubuntu-latest
202
+ if : github.ref == 'refs/heads/main'
203
+ steps :
204
+ - name : Deploy to production server
205
+ uses : appleboy/ssh-action@v1.0.0
206
+ with :
207
+ host : ${{ secrets.PRODUCTION_HOST }}
208
+ username : ${{ secrets.PRODUCTION_USER }}
209
+ key : ${{ secrets.PRODUCTION_SSH_KEY }}
210
+ script : |
211
+ docker pull ${{ needs.build.outputs.image }}
212
+ docker stop mcp-web-interface || true
213
+ docker rm mcp-web-interface || true
214
+ docker run -d \
215
+ --name mcp-web-interface \
216
+ --restart unless-stopped \
217
+ -p 3000:3000 \
218
+ -e NODE_ENV=production \
219
+ ${{ needs.build.outputs.image }}
220
+
221
+ security-scan :
222
+ needs : build
223
+ runs-on : ubuntu-latest
224
+ steps :
225
+ - name : Run Trivy vulnerability scanner
226
+ uses : aquasecurity/trivy-action@master
227
+ with :
228
+ image-ref : ${{ needs.build.outputs.image }}
229
+ format : ' sarif'
230
+ output : ' trivy-results.sarif'
231
+
232
+ - name : Upload Trivy scan results to GitHub Security tab
233
+ uses : github/codeql-action/upload-sarif@v3
234
+ with :
235
+ sarif_file : ' trivy-results.sarif'
0 commit comments