-
Notifications
You must be signed in to change notification settings - Fork 13
291 lines (283 loc) · 15.1 KB
/
cicd.yaml
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
name: CI/CD
on:
pull_request:
branches:
- main
push:
branches:
- main
permissions:
contents: read
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
test:
if: ${{ github.event_name == 'pull_request' }}
strategy:
fail-fast: false
matrix:
command:
- 'build'
- 'lint:check'
- 'format:check'
- 'test:unit'
- 'test:integration'
- 'test:acceptance'
runs-on: ubuntu-20.04
name: Test on Node.js 16 ( ${{ matrix.command }} )
steps:
- name: Checkout Repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
fetch-depth: 0
- name: Set Up Node.js
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d
with:
node-version: 16
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Run ${{ matrix.command }}
run: yarn ${{ matrix.command }}
build:
if: ${{ github.event_name == 'push' && github.ref_type == 'branch' }}
runs-on: ubuntu-20.04
name: Build
steps:
- name: Checkout Repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
fetch-depth: 0
- name: Set Up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3
- name: Set Up Docker Buildx
id: set-up-buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226
with:
install: true
- name: Cache Docker Layers
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build Docker
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09
with:
builder: ${{ steps.set-up-buildx.outputs.name }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
context: .
file: .maintain/docker/Dockerfile
tags: ${{ github.repository }}:${{ github.sha }}
outputs: type=docker,dest=/tmp/docker_image.tar
- name: Move Cache Docker Layers
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Upload Build to Artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
with:
name: build_${{ github.sha }}
path: |
/tmp/docker_image.tar
retention-days: 5
release-please:
needs:
- build
runs-on: ubuntu-20.04
name: Release Please
steps:
- name: Checkout Repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
fetch-depth: 0
- name: Release
id: release
uses: google-github-actions/release-please-action@4c5670f886fe259db4d11222f7dff41c1382304d
with:
token: ${{ secrets.PAT }}
fork: true
release-type: node
package-name: ${{ github.event.repository.name }}
include-v-in-tag: false
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
publish-docker:
needs:
- release-please
runs-on: ubuntu-20.04
name: Publish Docker
steps:
- name: Login to DockerHub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Download Build from Artifact
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a
with:
name: build_${{ github.sha }}
path: /tmp
- name: Load Downloaded Image
run: |
docker load --input /tmp/docker_image.tar
docker images --no-trunc --digests ${{ github.repository }}
- name: Tag as Release Version
if: ${{ needs.release-please.outputs.release_created }}
run: |
docker tag ${{ github.repository }}:${{ github.sha }} ${{ github.repository }}:${{ needs.release-please.outputs.tag_name }}
docker tag ${{ github.repository }}:${{ github.sha }} ${{ github.repository }}:latest
docker images --no-trunc --digests ${{ github.repository }}
- name: Push
run: docker image push -a ${{ github.repository }}
deploy:
needs:
- release-please
- publish-docker
permissions:
contents: read
id-token: write
strategy:
max-parallel: 1
matrix:
is_release:
- ${{ needs.release-please.outputs.release_created || false }}
environment:
- TESTNET
- MAINNET
exclude:
- is_release: false
environment: MAINNET
environment: ${{ matrix.environment }}
runs-on: ubuntu-20.04
name: Deploy to ${{ matrix.environment }}
steps:
- name: Checkout Repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
fetch-depth: 0
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@35b0e87d162680511bf346c299f71c9c5c379033
with:
workload_identity_provider: ${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_WORKLOAD_IDENTITY_PROVIDER')] }}
service_account: ${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT')] }}
- name: Set Up Google Cloud SDK
uses: google-github-actions/setup-gcloud@e30db14379863a8c79331b04a9969f4c1e225e0b
- name: Get GKE Credentials
uses: google-github-actions/get-gke-credentials@35ab0d2b2d48792c19f09325413bd185c8d44394
with:
cluster_name: ${{ secrets[format('{0}_{1}', matrix.environment, 'GKE_CLUSTER_NAME')] }}
location: ${{ secrets[format('{0}_{1}', matrix.environment, 'GKE_LOCATION')] }}
use_internal_ip: true
- name: Get Secrets from Google Secret Manager
id: secrets
uses: google-github-actions/get-secretmanager-secrets@4d6d3dfd94110800dda8d84109cb6da0f6a5919d
with:
secrets: |-
ADMIN_SUBSTRATE_MNEMONIC:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/ADMIN_SUBSTRATE_MNEMONIC
ADMIN_NEAR_MNEMONIC:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/ADMIN_NEAR_MNEMONIC
JWT_TOKEN_SECRET_KEY:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/JWT_TOKEN_SECRET_KEY
JWT_TOKEN_EXPIRES_IN:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/JWT_TOKEN_EXPIRES_IN
JWT_REFRESH_TOKEN_SECRET_KEY:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/JWT_REFRESH_TOKEN_SECRET_KEY
JWT_REFRESH_TOKEN_EXPIRES_IN:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/JWT_REFRESH_TOKEN_EXPIRES_IN
MONGO_PROTOCOL:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_PROTOCOL
MONGO_HOST:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_HOST
MONGO_PORT:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_PORT
MONGO_USER_API:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_USER_API
MONGO_PASSWORD_API:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_PASSWORD_API
MONGO_DB:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_DB
MONGO_URL:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/MONGO_URL
REDIS_CONNECTOR:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/REDIS_CONNECTOR
REDIS_HOST:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/REDIS_HOST
REDIS_PORT:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/REDIS_PORT
REDIS_PASSWORD:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/REDIS_PASSWORD
SMTP_SERVER:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/SMTP_SERVER
SMTP_PORT:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/SMTP_PORT
SMTP_USERNAME:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/SMTP_USERNAME
SMTP_PASSWORD:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/SMTP_PASSWORD
SMTP_SENDER_ADDRESS:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/SMTP_SENDER_ADDRESS
FIREBASE_SERVICE_ACCOUNT_BASE64:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/FIREBASE_SERVICE_ACCOUNT_BASE64
FIREBASE_STORAGE_BUCKET:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/FIREBASE_STORAGE_BUCKET
API_SENTRY_DSN:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/API_SENTRY_DSN
TWITTER_API_KEY:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/TWITTER_API_KEY
COIN_MARKET_CAP_API_KEY:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/COIN_MARKET_CAP_API_KEY
API_DNS:${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}/API_DNS
- name: Tunneling SSH connections
run: |
gcloud compute ssh ${{ secrets[format('{0}_{1}', matrix.environment, 'GCE_BASTION_INSTANCE_NAME')] }} \
--project=${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }} \
--zone ${{ secrets[format('{0}_{1}', matrix.environment, 'GCE_BASTION_INSTANCE_ZONE')] }} \
--ssh-flag '-4 -L 8888:127.0.0.1:8888 -N -q -f' \
--tunnel-through-iap \
--quiet
- name: Set Up Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78
with:
version: v3.10.0
- name: Perform Deployment
run: |
helm repo add myriadsocial https://charts.myriad.social
helm repo update
HTTPS_PROXY=127.0.0.1:8888 helm upgrade ${{ github.event.repository.name }} myriadsocial/myriad-api \
--install \
--set-string image.tag=${{ needs.release-please.outputs.tag_name || github.sha }} \
--set-string serviceAccount.name=${{ github.event.repository.name }} \
--set-string serviceAccount.annotations.'iam\.gke\.io/gcp-service-account'=${{ github.event.repository.name }}@${{ secrets[format('{0}_{1}', matrix.environment, 'GCP_PROJECT_ID')] }}.iam.gserviceaccount.com \
--set-string config.domain=${{ steps.secrets.outputs.API_DNS }} \
--set-string config.adminSubstrateMnemonic="${{ steps.secrets.outputs.ADMIN_SUBSTRATE_MNEMONIC }}" \
--set-string config.adminNearMnemonic="${{ steps.secrets.outputs.ADMIN_NEAR_MNEMONIC }}" \
--set-string config.jwt.tokenSecretKey=${{ steps.secrets.outputs.JWT_TOKEN_SECRET_KEY }} \
--set config.jwt.tokenExpireIn=${{ steps.secrets.outputs.JWT_TOKEN_EXPIRES_IN }} \
--set-string config.jwt.refreshTokenSecretKey=${{ steps.secrets.outputs.JWT_REFRESH_TOKEN_SECRET_KEY }} \
--set config.jwt.refreshTokenExpireIn=${{ steps.secrets.outputs.JWT_REFRESH_TOKEN_EXPIRES_IN }} \
--set-string config.mongo.protocol=${{ steps.secrets.outputs.MONGO_PROTOCOL }} \
--set-string config.mongo.host=${{ steps.secrets.outputs.MONGO_HOST }} \
--set config.mongo.port=${{ steps.secrets.outputs.MONGO_PORT }} \
--set-string config.mongo.user=${{ steps.secrets.outputs.MONGO_USER_API }} \
--set-string config.mongo.password=${{ steps.secrets.outputs.MONGO_PASSWORD_API }} \
--set-string config.mongo.database=${{ steps.secrets.outputs.MONGO_DB }} \
--set-string config.mongo.url="${{ steps.secrets.outputs.MONGO_URL }}" \
--set-string config.redis.connector=${{ steps.secrets.outputs.REDIS_CONNECTOR }} \
--set-string config.redis.host=${{ steps.secrets.outputs.REDIS_HOST }} \
--set-string config.redis.port=${{ steps.secrets.outputs.REDIS_PORT }} \
--set-string config.redis.password=${{ steps.secrets.outputs.REDIS_PASSWORD }} \
--set-string config.smtp.server=${{ steps.secrets.outputs.SMTP_SERVER }} \
--set config.smtp.port=${{ steps.secrets.outputs.SMTP_PORT }} \
--set-string config.smtp.username=${{ steps.secrets.outputs.SMTP_USERNAME }} \
--set-string config.smtp.password=${{ steps.secrets.outputs.SMTP_PASSWORD }} \
--set-string config.smtp.senderAddress=${{ steps.secrets.outputs.SMTP_SENDER_ADDRESS }} \
--set-string config.firebase.serviceAccountBase64=${{ steps.secrets.outputs.FIREBASE_SERVICE_ACCOUNT_BASE64 }} \
--set-string config.firebase.storageBucket=${{ steps.secrets.outputs.FIREBASE_STORAGE_BUCKET }} \
--set-string config.sentry.dsn=${{ steps.secrets.outputs.API_SENTRY_DSN }} \
--set-string config.twitter.apiKey=${{ steps.secrets.outputs.TWITTER_API_KEY }} \
--set-string config.coinMarketCap.apiKey=${{ steps.secrets.outputs.COIN_MARKET_CAP_API_KEY }} \
--set ingress.enabled=true \
--set-string ingress.className=nginx \
--set-string ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt \
--set-string ingress.annotations."nginx\.ingress\.kubernetes\.io/proxy-body-size"="100m" \
--set-string ingress.annotations."nginx\.org/client-max-body-size"="100m" \
--set-string ingress.hosts[0].host=${{ steps.secrets.outputs.API_DNS }} \
--set-string ingress.hosts[0].paths[0].path=/ \
--set-string ingress.hosts[0].paths[0].pathType=ImplementationSpecific \
--set-string ingress.tls[0].secretName=${{ steps.secrets.outputs.API_DNS }}-letsencrypt-tls \
--set-string ingress.tls[0].hosts[0]=${{ steps.secrets.outputs.API_DNS }} \
--set-string resources.requests.cpu=300m \
--set-string resources.requests.memory=512Mi \
--set-string resources.limits.cpu=500m \
--set-string resources.limits.memory=1024Mi \
--set replicaCount=1 \
--set autoscaling.enabled=true \
--set autoscaling.minReplicas=1 \
--set autoscaling.maxReplicas=1 \
--set-string nodeSelector.pool=general \
--set-string nodeSelector.'iam\.gke\.io/gke-metadata-server-enabled'='true'
HTTPS_PROXY=127.0.0.1:8888 kubectl rollout status deployment/${{ github.event.repository.name }}
- name: Clean Up Tunneling SSH Connections
if: always()
run: |
kill -9 $(lsof -ti:8888)
gcloud compute os-login ssh-keys remove --key-file=/home/runner/.ssh/google_compute_engine.pub