@catladder/pipeline 3.42.1 → 3.43.0

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.
@@ -0,0 +1,1495 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`matches snapshot for cloud-run-worker-pool local pipeline YAML 1`] = `
4
+ "image: path/to/docker/jobs-default:the-version
5
+ stages:
6
+ - setup
7
+ - setup dev
8
+ - setup review
9
+ - setup stage
10
+ - setup prod
11
+ - test
12
+ - test dev
13
+ - test review
14
+ - test stage
15
+ - test prod
16
+ - build
17
+ - build dev
18
+ - build review
19
+ - build stage
20
+ - build prod
21
+ - deploy
22
+ - deploy dev
23
+ - deploy review
24
+ - deploy stage
25
+ - deploy prod
26
+ - verify
27
+ - verify dev
28
+ - verify review
29
+ - verify stage
30
+ - verify prod
31
+ - agents
32
+ - agents dev
33
+ - agents review
34
+ - agents stage
35
+ - agents prod
36
+ - rollback
37
+ - rollback dev
38
+ - rollback review
39
+ - rollback stage
40
+ - rollback prod
41
+ - stop
42
+ - stop dev
43
+ - stop review
44
+ - stop stage
45
+ - stop prod
46
+ - release
47
+ variables:
48
+ FF_USE_FASTZIP: 'true'
49
+ ARTIFACT_COMPRESSION_LEVEL: fast
50
+ CACHE_COMPRESSION_LEVEL: fast
51
+ TRANSFER_METER_FREQUENCY: 5s
52
+ GIT_DEPTH: '1'
53
+ workflow:
54
+ name: $PIPELINE_ICON $PIPELINE_NAME
55
+ rules:
56
+ - if: $CI_PIPELINE_SOURCE == "trigger"
57
+ variables:
58
+ PIPELINE_ICON: 🤖
59
+ PIPELINE_NAME: Thinking...
60
+ - if: $CI_MERGE_REQUEST_ID
61
+ variables:
62
+ PIPELINE_ICON: 🐱🔨
63
+ PIPELINE_NAME: mr$CI_MERGE_REQUEST_IID - $CI_MERGE_REQUEST_TITLE
64
+ - if: $CI_COMMIT_TAG
65
+ variables:
66
+ PIPELINE_ICON: 🐱📦
67
+ PIPELINE_NAME: Release $CI_COMMIT_TAG
68
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
69
+ variables:
70
+ PIPELINE_ICON: 🐱🔨
71
+ PIPELINE_NAME: Main - $CI_COMMIT_TITLE
72
+ - when: always
73
+ variables:
74
+ PIPELINE_ICON: 🐱❓
75
+ PIPELINE_NAME: Default
76
+ before_script:
77
+ - |-
78
+ function escapeForDotEnv () {
79
+ input="\${1:-$(cat)}"
80
+ input="\${input//$'\\n'/\\\\n}"
81
+ if [[ "$input" == *\\\\n* ]]; then
82
+ if [[ "$input" == *\\"* && "$input" == *\\'* && "$input" == *\\\`* ]]; then
83
+ printf "\\"%s\\"\\n" "$input"
84
+ elif [[ "$input" == *\\"* && "$input" == *\\'* ]]; then
85
+ printf "\`%s\`\\n" "$input"
86
+ elif [[ "$input" == *\\"* ]]; then
87
+ printf "'%s'\\n" "$input"
88
+ else
89
+ printf "\\"%s\\"\\n" "$input"
90
+ fi
91
+ else
92
+ printf "%s\\n" "$input"
93
+ fi
94
+ }
95
+ - |-
96
+ function collapseable_section_start () {
97
+ local section_title="\${1}"
98
+ local section_description="\${2:-$section_title}"
99
+ echo -e "section_start:\`date +%s\`:\${section_title}[collapsed=true]\\r\\e[0K\${section_description}"
100
+ }
101
+ - |-
102
+ function collapseable_section_end () {
103
+ local section_title="\${1}"
104
+ echo -e "section_end:\`date +%s\`:\${section_title}\\r\\e[0K"
105
+ }
106
+ 'api 🛡 audit | dev ':
107
+ stage: test
108
+ image: path/to/docker/jobs-default:the-version
109
+ variables:
110
+ KUBERNETES_CPU_REQUEST: '0.45'
111
+ KUBERNETES_MEMORY_REQUEST: 1Gi
112
+ KUBERNETES_MEMORY_LIMIT: 4Gi
113
+ script:
114
+ - collapseable_section_start "injectvars" "Injecting variables"
115
+ - export APP_PATH="api"
116
+ - collapseable_section_end "injectvars"
117
+ - cd api
118
+ - yarn npm audit --environment production --severity critical
119
+ rules:
120
+ - when: never
121
+ if: $CI_PIPELINE_SOURCE == "trigger"
122
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
123
+ needs: []
124
+ retry: &a1
125
+ max: 2
126
+ interruptible: true
127
+ allow_failure: true
128
+ 'api 👮 lint | dev ':
129
+ stage: test
130
+ image: path/to/docker/jobs-default:the-version
131
+ variables:
132
+ KUBERNETES_CPU_REQUEST: '0.45'
133
+ KUBERNETES_MEMORY_REQUEST: 1Gi
134
+ KUBERNETES_MEMORY_LIMIT: 4Gi
135
+ script:
136
+ - collapseable_section_start "injectvars" "Injecting variables"
137
+ - export APP_PATH="api"
138
+ - collapseable_section_end "injectvars"
139
+ - collapseable_section_start "nodeinstall" "Ensure node version"
140
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
141
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
142
+ - collapseable_section_end "nodeinstall"
143
+ - cd api
144
+ - collapseable_section_start "nodeinstall" "Ensure node version"
145
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
146
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
147
+ - collapseable_section_end "nodeinstall"
148
+ - collapseable_section_start "yarninstall" "Yarn install"
149
+ - yarn install --immutable --inline-builds
150
+ - collapseable_section_end "yarninstall"
151
+ - yarn lint
152
+ cache:
153
+ - key: api-yarn
154
+ policy: pull-push
155
+ paths:
156
+ - api/.yarn
157
+ - key: api-node-modules
158
+ policy: pull-push
159
+ paths:
160
+ - api/node_modules
161
+ - api/.yarn/install-state.gz
162
+ rules:
163
+ - when: never
164
+ if: $CI_PIPELINE_SOURCE == "trigger"
165
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
166
+ needs: []
167
+ retry: *a1
168
+ interruptible: true
169
+ 'api 🧪 test | dev ':
170
+ stage: test
171
+ image: path/to/docker/jobs-testing-chrome:the-version
172
+ variables:
173
+ KUBERNETES_CPU_REQUEST: '0.45'
174
+ KUBERNETES_MEMORY_REQUEST: 1Gi
175
+ KUBERNETES_MEMORY_LIMIT: 4Gi
176
+ script:
177
+ - collapseable_section_start "injectvars" "Injecting variables"
178
+ - export APP_PATH="api"
179
+ - collapseable_section_end "injectvars"
180
+ - collapseable_section_start "nodeinstall" "Ensure node version"
181
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
182
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
183
+ - collapseable_section_end "nodeinstall"
184
+ - cd api
185
+ - collapseable_section_start "nodeinstall" "Ensure node version"
186
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
187
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
188
+ - collapseable_section_end "nodeinstall"
189
+ - collapseable_section_start "yarninstall" "Yarn install"
190
+ - yarn install --immutable --inline-builds
191
+ - collapseable_section_end "yarninstall"
192
+ - yarn test
193
+ cache:
194
+ - key: api-yarn
195
+ policy: pull-push
196
+ paths:
197
+ - api/.yarn
198
+ - key: api-node-modules
199
+ policy: pull-push
200
+ paths:
201
+ - api/node_modules
202
+ - api/.yarn/install-state.gz
203
+ rules:
204
+ - when: never
205
+ if: $CI_PIPELINE_SOURCE == "trigger"
206
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
207
+ needs: []
208
+ retry: *a1
209
+ interruptible: true
210
+ 'api 🔨 app | dev ':
211
+ stage: build
212
+ image: path/to/docker/jobs-default:the-version
213
+ variables:
214
+ KUBERNETES_CPU_REQUEST: '0.45'
215
+ KUBERNETES_MEMORY_REQUEST: 1Gi
216
+ KUBERNETES_MEMORY_LIMIT: 4Gi
217
+ script:
218
+ - collapseable_section_start "injectvars" "Injecting variables"
219
+ - export ENV_SHORT="dev"
220
+ - export APP_DIR="api"
221
+ - export ENV_TYPE="dev"
222
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
223
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
224
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
225
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
226
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
227
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
228
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
229
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
230
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
231
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
232
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
233
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
234
+ - collapseable_section_end "injectvars"
235
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
236
+ - |-
237
+ cat <<EOF > api/.env
238
+ ENV_SHORT=dev
239
+ APP_DIR=api
240
+ ENV_TYPE=dev
241
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
242
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
243
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
244
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
245
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
246
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
247
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
248
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
249
+ _ALL_ENV_VAR_KEYS=["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
250
+ EOF
251
+ - collapseable_section_end "write-dotenv-api"
252
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
253
+ - collapseable_section_start "nodeinstall" "Ensure node version"
254
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
255
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
256
+ - collapseable_section_end "nodeinstall"
257
+ - cd api
258
+ - collapseable_section_start "nodeinstall" "Ensure node version"
259
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
260
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
261
+ - collapseable_section_end "nodeinstall"
262
+ - collapseable_section_start "yarninstall" "Yarn install"
263
+ - yarn install --immutable --inline-builds
264
+ - collapseable_section_end "yarninstall"
265
+ - yarn build
266
+ cache:
267
+ - key: api-yarn
268
+ policy: pull-push
269
+ paths:
270
+ - api/.yarn
271
+ - key: api-node-modules
272
+ policy: pull-push
273
+ paths:
274
+ - api/node_modules
275
+ - api/.yarn/install-state.gz
276
+ artifacts:
277
+ paths:
278
+ - api/__build_info.json
279
+ - api/.next
280
+ - api/dist
281
+ exclude:
282
+ - api/.env
283
+ - api/.next/cache/**/*
284
+ expire_in: 1 day
285
+ when: always
286
+ reports: {}
287
+ rules:
288
+ - when: never
289
+ if: $CI_PIPELINE_SOURCE == "trigger"
290
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
291
+ needs: []
292
+ retry: *a1
293
+ interruptible: true
294
+ 'api 🔨 docker | dev ':
295
+ stage: build
296
+ image: path/to/docker/docker-build:the-version
297
+ services:
298
+ - name: docker:24.0.6-dind
299
+ command:
300
+ - --tls=false
301
+ - --registry-mirror=https://mirror.gcr.io
302
+ variables:
303
+ DOCKER_HOST: tcp://docker:2375
304
+ DOCKER_TLS_CERTDIR: ''
305
+ DOCKER_DRIVER: overlay2
306
+ DOCKER_BUILDKIT: '1'
307
+ KUBERNETES_CPU_REQUEST: '0.45'
308
+ KUBERNETES_MEMORY_REQUEST: 1Gi
309
+ KUBERNETES_MEMORY_LIMIT: 2Gi
310
+ script:
311
+ - collapseable_section_start "injectvars" "Injecting variables"
312
+ - export APP_DIR="api"
313
+ - export DOCKER_BUILD_CONTEXT="."
314
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
315
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
316
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
317
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
318
+ - |-
319
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
320
+ COPY --chown=node:node $APP_DIR .
321
+ RUN yarn plugin import workspace-tools
322
+ RUN yarn workspaces focus --production
323
+ RUN yarn rebuild"
324
+ - |-
325
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
326
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
327
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
328
+ COPY --chown=node:node .yarn /app/.yarn"
329
+ - collapseable_section_end "injectvars"
330
+ - ensureNodeDockerfile
331
+ - collapseable_section_start "docker-login" "Docker Login"
332
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
333
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
334
+ - collapseable_section_end "docker-login"
335
+ - collapseable_section_start "docker-build" "Docker build"
336
+ - docker build --network host --cache-from $DOCKER_CACHE_IMAGE --tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG -f $APP_DIR/Dockerfile $DOCKER_BUILD_CONTEXT --build-arg BUILDKIT_INLINE_CACHE=1
337
+ - collapseable_section_end "docker-build"
338
+ - collapseable_section_start "docker-push" "Docker push and tag"
339
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
340
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
341
+ - docker push $DOCKER_CACHE_IMAGE
342
+ - collapseable_section_end "docker-push"
343
+ cache:
344
+ - key: api-yarn
345
+ policy: pull
346
+ paths:
347
+ - api/.yarn
348
+ rules:
349
+ - when: never
350
+ if: $CI_PIPELINE_SOURCE == "trigger"
351
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
352
+ needs:
353
+ - 'api 🔨 app | dev '
354
+ retry: *a1
355
+ interruptible: true
356
+ 'api 🚀 Deploy | dev ':
357
+ stage: deploy dev
358
+ image: path/to/docker/gcloud:the-version
359
+ variables:
360
+ KUBERNETES_CPU_REQUEST: '0.22'
361
+ KUBERNETES_MEMORY_REQUEST: 200Mi
362
+ KUBERNETES_MEMORY_LIMIT: 400Mi
363
+ script:
364
+ - collapseable_section_start "injectvars" "Injecting variables"
365
+ - export ENV_SHORT="dev"
366
+ - export APP_DIR="api"
367
+ - export ENV_TYPE="dev"
368
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
369
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
370
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
371
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
372
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
373
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
374
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
375
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
376
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
377
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
378
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
379
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
380
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
381
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
382
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
383
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
384
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
385
+ - collapseable_section_end "injectvars"
386
+ - collapseable_section_start "prepare" "Prepare..."
387
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
388
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
389
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
390
+ - collapseable_section_end "prepare"
391
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
392
+ - |
393
+ cat > ____envvars.yaml <<EOF
394
+ ENV_SHORT: |-
395
+ dev
396
+ APP_DIR: |-
397
+ api
398
+ ENV_TYPE: |-
399
+ dev
400
+ BUILD_INFO_BUILD_ID: |-
401
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
402
+ BUILD_INFO_BUILD_TIME: |-
403
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
404
+ BUILD_INFO_CURRENT_VERSION: |-
405
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed '1!s/^/ /')
406
+ HOSTNAME: |-
407
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
408
+ ROOT_URL: |-
409
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
410
+ HOSTNAME_INTERNAL: |-
411
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
412
+ ROOT_URL_INTERNAL: |-
413
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
414
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
415
+ google-project-id
416
+ DEPLOY_CLOUD_RUN_REGION: |-
417
+ europe-west6
418
+ GCLOUD_RUN_canonicalHostSuffix: |-
419
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
420
+ _ALL_ENV_VAR_KEYS: |-
421
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
422
+
423
+ EOF
424
+ - collapseable_section_end "writeenvvars"
425
+ - collapseable_section_start "deploy" "Deploy to cloud run"
426
+ - gcloud run deploy pan-test-app-dev-api --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-service-name=pan-test-app-dev-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
427
+ - gcloud beta run worker-pools deploy pan-test-app-dev-api-worker --command="yarn,start:worker" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-worker-pool-name=pan-test-app-dev-api-worker --env-vars-file=____envvars.yaml --instances=1 --cpu=1 --memory=512Mi
428
+ - collapseable_section_end "deploy"
429
+ - collapseable_section_start "cleanup" "Cleanup"
430
+ - set +e
431
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-dev-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=google-project-id --region=europe-west6 --quiet $revisionname ; done
432
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api@$version --quiet --delete-tags; done
433
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
434
+ - set -e
435
+ - collapseable_section_end "cleanup"
436
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
437
+ environment:
438
+ name: dev/api
439
+ url: $CL_GITLAB_ENVIRONMENT_URL
440
+ on_stop: 'api 🛑 Stop ⚠️ | dev '
441
+ auto_stop_in: 4 weeks
442
+ artifacts:
443
+ reports:
444
+ dotenv: gitlab_environment.env
445
+ rules:
446
+ - when: never
447
+ if: $CI_PIPELINE_SOURCE == "trigger"
448
+ - when: on_success
449
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
450
+ needs:
451
+ - job: 'api 👮 lint | dev '
452
+ artifacts: false
453
+ - job: 'api 🔨 app | dev '
454
+ artifacts: false
455
+ - job: 'api 🔨 docker | dev '
456
+ artifacts: false
457
+ - job: 'api 🧪 test | dev '
458
+ artifacts: false
459
+ - job: 'api 🛡 audit | dev '
460
+ artifacts: false
461
+ retry: *a1
462
+ interruptible: true
463
+ allow_failure: false
464
+ 'api 🛑 Stop ⚠️ | dev ':
465
+ stage: stop dev
466
+ image: path/to/docker/gcloud:the-version
467
+ variables:
468
+ KUBERNETES_CPU_REQUEST: '0.22'
469
+ KUBERNETES_MEMORY_REQUEST: 200Mi
470
+ KUBERNETES_MEMORY_LIMIT: 400Mi
471
+ GIT_STRATEGY: none
472
+ script:
473
+ - collapseable_section_start "injectvars" "Injecting variables"
474
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
475
+ - collapseable_section_end "injectvars"
476
+ - set +e
477
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
478
+ - gcloud run services delete pan-test-app-dev-api --project=google-project-id --region=europe-west6
479
+ - gcloud beta run worker-pools delete pan-test-app-dev-api-worker --project=google-project-id --region=europe-west6
480
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
481
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
482
+ - set -e
483
+ environment:
484
+ name: dev/api
485
+ action: stop
486
+ rules:
487
+ - when: never
488
+ if: $CI_PIPELINE_SOURCE == "trigger"
489
+ - when: manual
490
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
491
+ needs: []
492
+ retry: *a1
493
+ interruptible: true
494
+ allow_failure: true
495
+ 'api 🛡 audit | review ':
496
+ stage: test
497
+ image: path/to/docker/jobs-default:the-version
498
+ variables:
499
+ KUBERNETES_CPU_REQUEST: '0.45'
500
+ KUBERNETES_MEMORY_REQUEST: 1Gi
501
+ KUBERNETES_MEMORY_LIMIT: 4Gi
502
+ script:
503
+ - collapseable_section_start "injectvars" "Injecting variables"
504
+ - export APP_PATH="api"
505
+ - collapseable_section_end "injectvars"
506
+ - cd api
507
+ - yarn npm audit --environment production --severity critical
508
+ rules:
509
+ - when: never
510
+ if: $CI_PIPELINE_SOURCE == "trigger"
511
+ - if: $CI_MERGE_REQUEST_ID
512
+ needs: []
513
+ retry: *a1
514
+ interruptible: true
515
+ allow_failure: true
516
+ 'api 👮 lint | review ':
517
+ stage: test
518
+ image: path/to/docker/jobs-default:the-version
519
+ variables:
520
+ KUBERNETES_CPU_REQUEST: '0.45'
521
+ KUBERNETES_MEMORY_REQUEST: 1Gi
522
+ KUBERNETES_MEMORY_LIMIT: 4Gi
523
+ script:
524
+ - collapseable_section_start "injectvars" "Injecting variables"
525
+ - export APP_PATH="api"
526
+ - collapseable_section_end "injectvars"
527
+ - collapseable_section_start "nodeinstall" "Ensure node version"
528
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
529
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
530
+ - collapseable_section_end "nodeinstall"
531
+ - cd api
532
+ - collapseable_section_start "nodeinstall" "Ensure node version"
533
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
534
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
535
+ - collapseable_section_end "nodeinstall"
536
+ - collapseable_section_start "yarninstall" "Yarn install"
537
+ - yarn install --immutable --inline-builds
538
+ - collapseable_section_end "yarninstall"
539
+ - yarn lint
540
+ cache:
541
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
542
+ policy: pull-push
543
+ paths:
544
+ - api/.yarn
545
+ fallback_keys:
546
+ - api-yarn
547
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
548
+ policy: pull-push
549
+ paths:
550
+ - api/node_modules
551
+ - api/.yarn/install-state.gz
552
+ fallback_keys:
553
+ - api-node-modules
554
+ rules:
555
+ - when: never
556
+ if: $CI_PIPELINE_SOURCE == "trigger"
557
+ - if: $CI_MERGE_REQUEST_ID
558
+ needs: []
559
+ retry: *a1
560
+ interruptible: true
561
+ 'api 🧪 test | review ':
562
+ stage: test
563
+ image: path/to/docker/jobs-testing-chrome:the-version
564
+ variables:
565
+ KUBERNETES_CPU_REQUEST: '0.45'
566
+ KUBERNETES_MEMORY_REQUEST: 1Gi
567
+ KUBERNETES_MEMORY_LIMIT: 4Gi
568
+ script:
569
+ - collapseable_section_start "injectvars" "Injecting variables"
570
+ - export APP_PATH="api"
571
+ - collapseable_section_end "injectvars"
572
+ - collapseable_section_start "nodeinstall" "Ensure node version"
573
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
574
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
575
+ - collapseable_section_end "nodeinstall"
576
+ - cd api
577
+ - collapseable_section_start "nodeinstall" "Ensure node version"
578
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
579
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
580
+ - collapseable_section_end "nodeinstall"
581
+ - collapseable_section_start "yarninstall" "Yarn install"
582
+ - yarn install --immutable --inline-builds
583
+ - collapseable_section_end "yarninstall"
584
+ - yarn test
585
+ cache:
586
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
587
+ policy: pull-push
588
+ paths:
589
+ - api/.yarn
590
+ fallback_keys:
591
+ - api-yarn
592
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
593
+ policy: pull-push
594
+ paths:
595
+ - api/node_modules
596
+ - api/.yarn/install-state.gz
597
+ fallback_keys:
598
+ - api-node-modules
599
+ rules:
600
+ - when: never
601
+ if: $CI_PIPELINE_SOURCE == "trigger"
602
+ - if: $CI_MERGE_REQUEST_ID
603
+ needs: []
604
+ retry: *a1
605
+ interruptible: true
606
+ 'api 🔨 app | review ':
607
+ stage: build
608
+ image: path/to/docker/jobs-default:the-version
609
+ variables:
610
+ KUBERNETES_CPU_REQUEST: '0.45'
611
+ KUBERNETES_MEMORY_REQUEST: 1Gi
612
+ KUBERNETES_MEMORY_LIMIT: 4Gi
613
+ script:
614
+ - collapseable_section_start "injectvars" "Injecting variables"
615
+ - export ENV_SHORT="review"
616
+ - export APP_DIR="api"
617
+ - export ENV_TYPE="review"
618
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
619
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
620
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
621
+ - export HOSTNAME="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
622
+ - export ROOT_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
623
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
624
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
625
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
626
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
627
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
628
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
629
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
630
+ - collapseable_section_end "injectvars"
631
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
632
+ - |-
633
+ cat <<EOF > api/.env
634
+ ENV_SHORT=review
635
+ APP_DIR=api
636
+ ENV_TYPE=review
637
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
638
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
639
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
640
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
641
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
642
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
643
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
644
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
645
+ _ALL_ENV_VAR_KEYS=["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
646
+ EOF
647
+ - collapseable_section_end "write-dotenv-api"
648
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
649
+ - collapseable_section_start "nodeinstall" "Ensure node version"
650
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
651
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
652
+ - collapseable_section_end "nodeinstall"
653
+ - cd api
654
+ - collapseable_section_start "nodeinstall" "Ensure node version"
655
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
656
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
657
+ - collapseable_section_end "nodeinstall"
658
+ - collapseable_section_start "yarninstall" "Yarn install"
659
+ - yarn install --immutable --inline-builds
660
+ - collapseable_section_end "yarninstall"
661
+ - yarn build
662
+ cache:
663
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
664
+ policy: pull-push
665
+ paths:
666
+ - api/.yarn
667
+ fallback_keys:
668
+ - api-yarn
669
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
670
+ policy: pull-push
671
+ paths:
672
+ - api/node_modules
673
+ - api/.yarn/install-state.gz
674
+ fallback_keys:
675
+ - api-node-modules
676
+ artifacts:
677
+ paths:
678
+ - api/__build_info.json
679
+ - api/.next
680
+ - api/dist
681
+ exclude:
682
+ - api/.env
683
+ - api/.next/cache/**/*
684
+ expire_in: 1 day
685
+ when: always
686
+ reports: {}
687
+ rules:
688
+ - when: never
689
+ if: $CI_PIPELINE_SOURCE == "trigger"
690
+ - if: $CI_MERGE_REQUEST_ID
691
+ needs: []
692
+ retry: *a1
693
+ interruptible: true
694
+ 'api 🔨 docker | review ':
695
+ stage: build
696
+ image: path/to/docker/docker-build:the-version
697
+ services:
698
+ - name: docker:24.0.6-dind
699
+ command:
700
+ - --tls=false
701
+ - --registry-mirror=https://mirror.gcr.io
702
+ variables:
703
+ DOCKER_HOST: tcp://docker:2375
704
+ DOCKER_TLS_CERTDIR: ''
705
+ DOCKER_DRIVER: overlay2
706
+ DOCKER_BUILDKIT: '1'
707
+ KUBERNETES_CPU_REQUEST: '0.45'
708
+ KUBERNETES_MEMORY_REQUEST: 1Gi
709
+ KUBERNETES_MEMORY_LIMIT: 2Gi
710
+ script:
711
+ - collapseable_section_start "injectvars" "Injecting variables"
712
+ - export APP_DIR="api"
713
+ - export DOCKER_BUILD_CONTEXT="."
714
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
715
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
716
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
717
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
718
+ - |-
719
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
720
+ COPY --chown=node:node $APP_DIR .
721
+ RUN yarn plugin import workspace-tools
722
+ RUN yarn workspaces focus --production
723
+ RUN yarn rebuild"
724
+ - |-
725
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
726
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
727
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
728
+ COPY --chown=node:node .yarn /app/.yarn"
729
+ - collapseable_section_end "injectvars"
730
+ - ensureNodeDockerfile
731
+ - collapseable_section_start "docker-login" "Docker Login"
732
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
733
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
734
+ - collapseable_section_end "docker-login"
735
+ - collapseable_section_start "docker-build" "Docker build"
736
+ - docker build --network host --cache-from $DOCKER_CACHE_IMAGE --tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG -f $APP_DIR/Dockerfile $DOCKER_BUILD_CONTEXT --build-arg BUILDKIT_INLINE_CACHE=1
737
+ - collapseable_section_end "docker-build"
738
+ - collapseable_section_start "docker-push" "Docker push and tag"
739
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
740
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
741
+ - docker push $DOCKER_CACHE_IMAGE
742
+ - collapseable_section_end "docker-push"
743
+ cache:
744
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
745
+ policy: pull
746
+ paths:
747
+ - api/.yarn
748
+ fallback_keys:
749
+ - api-yarn
750
+ rules:
751
+ - when: never
752
+ if: $CI_PIPELINE_SOURCE == "trigger"
753
+ - if: $CI_MERGE_REQUEST_ID
754
+ needs:
755
+ - 'api 🔨 app | review '
756
+ retry: *a1
757
+ interruptible: true
758
+ 'api 🚀 Deploy | review ':
759
+ stage: deploy review
760
+ image: path/to/docker/gcloud:the-version
761
+ variables:
762
+ KUBERNETES_CPU_REQUEST: '0.22'
763
+ KUBERNETES_MEMORY_REQUEST: 200Mi
764
+ KUBERNETES_MEMORY_LIMIT: 400Mi
765
+ script:
766
+ - collapseable_section_start "injectvars" "Injecting variables"
767
+ - export ENV_SHORT="review"
768
+ - export APP_DIR="api"
769
+ - export ENV_TYPE="review"
770
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
771
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
772
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
773
+ - export HOSTNAME="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
774
+ - export ROOT_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
775
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
776
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
777
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
778
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
779
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
780
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
781
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
782
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
783
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
784
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
785
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
786
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
787
+ - collapseable_section_end "injectvars"
788
+ - collapseable_section_start "prepare" "Prepare..."
789
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
790
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
791
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
792
+ - collapseable_section_end "prepare"
793
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
794
+ - |
795
+ cat > ____envvars.yaml <<EOF
796
+ ENV_SHORT: |-
797
+ review
798
+ APP_DIR: |-
799
+ api
800
+ ENV_TYPE: |-
801
+ review
802
+ BUILD_INFO_BUILD_ID: |-
803
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
804
+ BUILD_INFO_BUILD_TIME: |-
805
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
806
+ BUILD_INFO_CURRENT_VERSION: |-
807
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed '1!s/^/ /')
808
+ HOSTNAME: |-
809
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
810
+ ROOT_URL: |-
811
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
812
+ HOSTNAME_INTERNAL: |-
813
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
814
+ ROOT_URL_INTERNAL: |-
815
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
816
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
817
+ google-project-id
818
+ DEPLOY_CLOUD_RUN_REGION: |-
819
+ europe-west6
820
+ GCLOUD_RUN_canonicalHostSuffix: |-
821
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
822
+ _ALL_ENV_VAR_KEYS: |-
823
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
824
+
825
+ EOF
826
+ - collapseable_section_end "writeenvvars"
827
+ - collapseable_section_start "deploy" "Deploy to cloud run"
828
+ - gcloud run deploy $(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }):$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-service-name=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
829
+ - collapseable_section_end "deploy"
830
+ - collapseable_section_start "cleanup" "Cleanup"
831
+ - set +e
832
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=google-project-id --region=europe-west6 --quiet $revisionname ; done
833
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }) --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })@$version --quiet --delete-tags; done
834
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
835
+ - set +e
836
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
837
+ - set -e
838
+ - set -e
839
+ - collapseable_section_end "cleanup"
840
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
841
+ environment:
842
+ name: review/$CI_COMMIT_REF_NAME/api
843
+ url: $CL_GITLAB_ENVIRONMENT_URL
844
+ on_stop: 'api 🛑 Stop ⚠️ | review '
845
+ auto_stop_in: 1 week
846
+ artifacts:
847
+ reports:
848
+ dotenv: gitlab_environment.env
849
+ rules:
850
+ - when: never
851
+ if: $CI_PIPELINE_SOURCE == "trigger"
852
+ - when: on_success
853
+ if: $CI_MERGE_REQUEST_ID
854
+ needs:
855
+ - job: 'api 👮 lint | review '
856
+ artifacts: false
857
+ - job: 'api 🔨 app | review '
858
+ artifacts: false
859
+ - job: 'api 🔨 docker | review '
860
+ artifacts: false
861
+ - job: 'api 🧪 test | review '
862
+ artifacts: false
863
+ - job: 'api 🛡 audit | review '
864
+ artifacts: false
865
+ retry: *a1
866
+ interruptible: true
867
+ allow_failure: false
868
+ 'api 🛑 Stop ⚠️ | review ':
869
+ stage: stop review
870
+ image: path/to/docker/gcloud:the-version
871
+ variables:
872
+ KUBERNETES_CPU_REQUEST: '0.22'
873
+ KUBERNETES_MEMORY_REQUEST: 200Mi
874
+ KUBERNETES_MEMORY_LIMIT: 400Mi
875
+ GIT_STRATEGY: none
876
+ script:
877
+ - collapseable_section_start "injectvars" "Injecting variables"
878
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
879
+ - collapseable_section_end "injectvars"
880
+ - set +e
881
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
882
+ - gcloud run services delete $(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --project=google-project-id --region=europe-west6
883
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }) --quiet --delete-tags
884
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
885
+ - set +e
886
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
887
+ - set -e
888
+ - set -e
889
+ environment:
890
+ name: review/$CI_COMMIT_REF_NAME/api
891
+ action: stop
892
+ rules:
893
+ - when: never
894
+ if: $CI_PIPELINE_SOURCE == "trigger"
895
+ - when: manual
896
+ if: $CI_MERGE_REQUEST_ID
897
+ needs: []
898
+ retry: *a1
899
+ interruptible: true
900
+ allow_failure: true
901
+ 'api 🔨 app | stage ':
902
+ stage: build
903
+ image: path/to/docker/jobs-default:the-version
904
+ variables:
905
+ KUBERNETES_CPU_REQUEST: '0.45'
906
+ KUBERNETES_MEMORY_REQUEST: 1Gi
907
+ KUBERNETES_MEMORY_LIMIT: 4Gi
908
+ script:
909
+ - collapseable_section_start "injectvars" "Injecting variables"
910
+ - export ENV_SHORT="stage"
911
+ - export APP_DIR="api"
912
+ - export ENV_TYPE="stage"
913
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
914
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
915
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
916
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
917
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
918
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
919
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
920
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
921
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
922
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
923
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
924
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
925
+ - collapseable_section_end "injectvars"
926
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
927
+ - |-
928
+ cat <<EOF > api/.env
929
+ ENV_SHORT=stage
930
+ APP_DIR=api
931
+ ENV_TYPE=stage
932
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
933
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
934
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
935
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
936
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
937
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
938
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
939
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
940
+ _ALL_ENV_VAR_KEYS=["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
941
+ EOF
942
+ - collapseable_section_end "write-dotenv-api"
943
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
944
+ - collapseable_section_start "nodeinstall" "Ensure node version"
945
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
946
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
947
+ - collapseable_section_end "nodeinstall"
948
+ - cd api
949
+ - collapseable_section_start "nodeinstall" "Ensure node version"
950
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
951
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
952
+ - collapseable_section_end "nodeinstall"
953
+ - collapseable_section_start "yarninstall" "Yarn install"
954
+ - yarn install --immutable --inline-builds
955
+ - collapseable_section_end "yarninstall"
956
+ - yarn build
957
+ cache:
958
+ - key: api-yarn
959
+ policy: pull-push
960
+ paths:
961
+ - api/.yarn
962
+ - key: api-node-modules
963
+ policy: pull-push
964
+ paths:
965
+ - api/node_modules
966
+ - api/.yarn/install-state.gz
967
+ artifacts:
968
+ paths:
969
+ - api/__build_info.json
970
+ - api/.next
971
+ - api/dist
972
+ exclude:
973
+ - api/.env
974
+ - api/.next/cache/**/*
975
+ expire_in: 1 day
976
+ when: always
977
+ reports: {}
978
+ rules:
979
+ - when: never
980
+ if: $CI_PIPELINE_SOURCE == "trigger"
981
+ - if: $CI_COMMIT_TAG
982
+ needs: []
983
+ retry: *a1
984
+ interruptible: true
985
+ 'api 🔨 docker | stage ':
986
+ stage: build
987
+ image: path/to/docker/docker-build:the-version
988
+ services:
989
+ - name: docker:24.0.6-dind
990
+ command:
991
+ - --tls=false
992
+ - --registry-mirror=https://mirror.gcr.io
993
+ variables:
994
+ DOCKER_HOST: tcp://docker:2375
995
+ DOCKER_TLS_CERTDIR: ''
996
+ DOCKER_DRIVER: overlay2
997
+ DOCKER_BUILDKIT: '1'
998
+ KUBERNETES_CPU_REQUEST: '0.45'
999
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1000
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1001
+ script:
1002
+ - collapseable_section_start "injectvars" "Injecting variables"
1003
+ - export APP_DIR="api"
1004
+ - export DOCKER_BUILD_CONTEXT="."
1005
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1006
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1007
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1008
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1009
+ - |-
1010
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
1011
+ COPY --chown=node:node $APP_DIR .
1012
+ RUN yarn plugin import workspace-tools
1013
+ RUN yarn workspaces focus --production
1014
+ RUN yarn rebuild"
1015
+ - |-
1016
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1017
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1018
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1019
+ COPY --chown=node:node .yarn /app/.yarn"
1020
+ - collapseable_section_end "injectvars"
1021
+ - ensureNodeDockerfile
1022
+ - collapseable_section_start "docker-login" "Docker Login"
1023
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1024
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1025
+ - collapseable_section_end "docker-login"
1026
+ - collapseable_section_start "docker-build" "Docker build"
1027
+ - docker build --network host --cache-from $DOCKER_CACHE_IMAGE --tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG -f $APP_DIR/Dockerfile $DOCKER_BUILD_CONTEXT --build-arg BUILDKIT_INLINE_CACHE=1
1028
+ - collapseable_section_end "docker-build"
1029
+ - collapseable_section_start "docker-push" "Docker push and tag"
1030
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1031
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1032
+ - docker push $DOCKER_CACHE_IMAGE
1033
+ - collapseable_section_end "docker-push"
1034
+ cache:
1035
+ - key: api-yarn
1036
+ policy: pull
1037
+ paths:
1038
+ - api/.yarn
1039
+ rules:
1040
+ - when: never
1041
+ if: $CI_PIPELINE_SOURCE == "trigger"
1042
+ - if: $CI_COMMIT_TAG
1043
+ needs:
1044
+ - 'api 🔨 app | stage '
1045
+ retry: *a1
1046
+ interruptible: true
1047
+ 'api 🚀 Deploy | stage ':
1048
+ stage: deploy stage
1049
+ image: path/to/docker/gcloud:the-version
1050
+ variables:
1051
+ KUBERNETES_CPU_REQUEST: '0.22'
1052
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1053
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1054
+ script:
1055
+ - collapseable_section_start "injectvars" "Injecting variables"
1056
+ - export ENV_SHORT="stage"
1057
+ - export APP_DIR="api"
1058
+ - export ENV_TYPE="stage"
1059
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1060
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1061
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
1062
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1063
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1064
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1065
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1066
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1067
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1068
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
1069
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
1070
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1071
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1072
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1073
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1074
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1075
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1076
+ - collapseable_section_end "injectvars"
1077
+ - collapseable_section_start "prepare" "Prepare..."
1078
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1079
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1080
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1081
+ - collapseable_section_end "prepare"
1082
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1083
+ - |
1084
+ cat > ____envvars.yaml <<EOF
1085
+ ENV_SHORT: |-
1086
+ stage
1087
+ APP_DIR: |-
1088
+ api
1089
+ ENV_TYPE: |-
1090
+ stage
1091
+ BUILD_INFO_BUILD_ID: |-
1092
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1093
+ BUILD_INFO_BUILD_TIME: |-
1094
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1095
+ BUILD_INFO_CURRENT_VERSION: |-
1096
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed '1!s/^/ /')
1097
+ HOSTNAME: |-
1098
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1099
+ ROOT_URL: |-
1100
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1101
+ HOSTNAME_INTERNAL: |-
1102
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1103
+ ROOT_URL_INTERNAL: |-
1104
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1105
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1106
+ google-project-id
1107
+ DEPLOY_CLOUD_RUN_REGION: |-
1108
+ europe-west6
1109
+ GCLOUD_RUN_canonicalHostSuffix: |-
1110
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1111
+ _ALL_ENV_VAR_KEYS: |-
1112
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1113
+
1114
+ EOF
1115
+ - collapseable_section_end "writeenvvars"
1116
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1117
+ - gcloud run deploy pan-test-app-stage-api --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-service-name=pan-test-app-stage-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1118
+ - gcloud beta run worker-pools deploy pan-test-app-stage-api-worker --command="yarn,start:worker" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-worker-pool-name=pan-test-app-stage-api-worker --env-vars-file=____envvars.yaml --instances=1 --cpu=1 --memory=512Mi
1119
+ - collapseable_section_end "deploy"
1120
+ - collapseable_section_start "cleanup" "Cleanup"
1121
+ - set +e
1122
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-stage-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=google-project-id --region=europe-west6 --quiet $revisionname ; done
1123
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api@$version --quiet --delete-tags; done
1124
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1125
+ - set -e
1126
+ - collapseable_section_end "cleanup"
1127
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1128
+ environment:
1129
+ name: stage/api
1130
+ url: $CL_GITLAB_ENVIRONMENT_URL
1131
+ on_stop: 'api 🛑 Stop ⚠️ | stage '
1132
+ artifacts:
1133
+ reports:
1134
+ dotenv: gitlab_environment.env
1135
+ rules:
1136
+ - when: never
1137
+ if: $CI_PIPELINE_SOURCE == "trigger"
1138
+ - when: on_success
1139
+ if: $CI_COMMIT_TAG
1140
+ needs:
1141
+ - job: 'api 🔨 app | stage '
1142
+ artifacts: false
1143
+ - job: 'api 🔨 docker | stage '
1144
+ artifacts: false
1145
+ retry: *a1
1146
+ interruptible: true
1147
+ allow_failure: false
1148
+ 'api 🛑 Stop ⚠️ | stage ':
1149
+ stage: stop stage
1150
+ image: path/to/docker/gcloud:the-version
1151
+ variables:
1152
+ KUBERNETES_CPU_REQUEST: '0.22'
1153
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1154
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1155
+ GIT_STRATEGY: none
1156
+ script:
1157
+ - collapseable_section_start "injectvars" "Injecting variables"
1158
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1159
+ - collapseable_section_end "injectvars"
1160
+ - set +e
1161
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1162
+ - gcloud run services delete pan-test-app-stage-api --project=google-project-id --region=europe-west6
1163
+ - gcloud beta run worker-pools delete pan-test-app-stage-api-worker --project=google-project-id --region=europe-west6
1164
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1165
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1166
+ - set -e
1167
+ environment:
1168
+ name: stage/api
1169
+ action: stop
1170
+ rules:
1171
+ - when: never
1172
+ if: $CI_PIPELINE_SOURCE == "trigger"
1173
+ - when: manual
1174
+ if: $CI_COMMIT_TAG
1175
+ needs: []
1176
+ retry: *a1
1177
+ interruptible: true
1178
+ allow_failure: true
1179
+ 'api 🔨 app | prod ':
1180
+ stage: build
1181
+ image: path/to/docker/jobs-default:the-version
1182
+ variables:
1183
+ KUBERNETES_CPU_REQUEST: '0.45'
1184
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1185
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1186
+ script:
1187
+ - collapseable_section_start "injectvars" "Injecting variables"
1188
+ - export ENV_SHORT="prod"
1189
+ - export APP_DIR="api"
1190
+ - export ENV_TYPE="prod"
1191
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1192
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1193
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
1194
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1195
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1196
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1197
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1198
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1199
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1200
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1201
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1202
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1203
+ - collapseable_section_end "injectvars"
1204
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
1205
+ - |-
1206
+ cat <<EOF > api/.env
1207
+ ENV_SHORT=prod
1208
+ APP_DIR=api
1209
+ ENV_TYPE=prod
1210
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1211
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1212
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1213
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1214
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
1215
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
1216
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
1217
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
1218
+ _ALL_ENV_VAR_KEYS=["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1219
+ EOF
1220
+ - collapseable_section_end "write-dotenv-api"
1221
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1222
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1223
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1224
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1225
+ - collapseable_section_end "nodeinstall"
1226
+ - cd api
1227
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1228
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1229
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1230
+ - collapseable_section_end "nodeinstall"
1231
+ - collapseable_section_start "yarninstall" "Yarn install"
1232
+ - yarn install --immutable --inline-builds
1233
+ - collapseable_section_end "yarninstall"
1234
+ - yarn build
1235
+ cache:
1236
+ - key: api-yarn
1237
+ policy: pull-push
1238
+ paths:
1239
+ - api/.yarn
1240
+ - key: api-node-modules
1241
+ policy: pull-push
1242
+ paths:
1243
+ - api/node_modules
1244
+ - api/.yarn/install-state.gz
1245
+ artifacts:
1246
+ paths:
1247
+ - api/__build_info.json
1248
+ - api/.next
1249
+ - api/dist
1250
+ exclude:
1251
+ - api/.env
1252
+ - api/.next/cache/**/*
1253
+ expire_in: 1 day
1254
+ when: always
1255
+ reports: {}
1256
+ rules:
1257
+ - when: never
1258
+ if: $CI_PIPELINE_SOURCE == "trigger"
1259
+ - if: $CI_COMMIT_TAG
1260
+ needs: []
1261
+ retry: *a1
1262
+ interruptible: true
1263
+ 'api 🔨 docker | prod ':
1264
+ stage: build
1265
+ image: path/to/docker/docker-build:the-version
1266
+ services:
1267
+ - name: docker:24.0.6-dind
1268
+ command:
1269
+ - --tls=false
1270
+ - --registry-mirror=https://mirror.gcr.io
1271
+ variables:
1272
+ DOCKER_HOST: tcp://docker:2375
1273
+ DOCKER_TLS_CERTDIR: ''
1274
+ DOCKER_DRIVER: overlay2
1275
+ DOCKER_BUILDKIT: '1'
1276
+ KUBERNETES_CPU_REQUEST: '0.45'
1277
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1278
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1279
+ script:
1280
+ - collapseable_section_start "injectvars" "Injecting variables"
1281
+ - export APP_DIR="api"
1282
+ - export DOCKER_BUILD_CONTEXT="."
1283
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1284
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1285
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1286
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1287
+ - |-
1288
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
1289
+ COPY --chown=node:node $APP_DIR .
1290
+ RUN yarn plugin import workspace-tools
1291
+ RUN yarn workspaces focus --production
1292
+ RUN yarn rebuild"
1293
+ - |-
1294
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1295
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1296
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1297
+ COPY --chown=node:node .yarn /app/.yarn"
1298
+ - collapseable_section_end "injectvars"
1299
+ - ensureNodeDockerfile
1300
+ - collapseable_section_start "docker-login" "Docker Login"
1301
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1302
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1303
+ - collapseable_section_end "docker-login"
1304
+ - collapseable_section_start "docker-build" "Docker build"
1305
+ - docker build --network host --cache-from $DOCKER_CACHE_IMAGE --tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG -f $APP_DIR/Dockerfile $DOCKER_BUILD_CONTEXT --build-arg BUILDKIT_INLINE_CACHE=1
1306
+ - collapseable_section_end "docker-build"
1307
+ - collapseable_section_start "docker-push" "Docker push and tag"
1308
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1309
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1310
+ - docker push $DOCKER_CACHE_IMAGE
1311
+ - collapseable_section_end "docker-push"
1312
+ cache:
1313
+ - key: api-yarn
1314
+ policy: pull
1315
+ paths:
1316
+ - api/.yarn
1317
+ rules:
1318
+ - when: never
1319
+ if: $CI_PIPELINE_SOURCE == "trigger"
1320
+ - if: $CI_COMMIT_TAG
1321
+ needs:
1322
+ - 'api 🔨 app | prod '
1323
+ retry: *a1
1324
+ interruptible: true
1325
+ 'api 🚀 Deploy | prod ':
1326
+ stage: deploy prod
1327
+ image: path/to/docker/gcloud:the-version
1328
+ variables:
1329
+ KUBERNETES_CPU_REQUEST: '0.22'
1330
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1331
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1332
+ script:
1333
+ - collapseable_section_start "injectvars" "Injecting variables"
1334
+ - export ENV_SHORT="prod"
1335
+ - export APP_DIR="api"
1336
+ - export ENV_TYPE="prod"
1337
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1338
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1339
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
1340
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1341
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1342
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1343
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1344
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1345
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1346
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1347
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1348
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1349
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1350
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1351
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1352
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1353
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1354
+ - collapseable_section_end "injectvars"
1355
+ - collapseable_section_start "prepare" "Prepare..."
1356
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1357
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1358
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1359
+ - collapseable_section_end "prepare"
1360
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1361
+ - |
1362
+ cat > ____envvars.yaml <<EOF
1363
+ ENV_SHORT: |-
1364
+ prod
1365
+ APP_DIR: |-
1366
+ api
1367
+ ENV_TYPE: |-
1368
+ prod
1369
+ BUILD_INFO_BUILD_ID: |-
1370
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1371
+ BUILD_INFO_BUILD_TIME: |-
1372
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1373
+ BUILD_INFO_CURRENT_VERSION: |-
1374
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed '1!s/^/ /')
1375
+ HOSTNAME: |-
1376
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1377
+ ROOT_URL: |-
1378
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1379
+ HOSTNAME_INTERNAL: |-
1380
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1381
+ ROOT_URL_INTERNAL: |-
1382
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1383
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1384
+ google-project-id
1385
+ DEPLOY_CLOUD_RUN_REGION: |-
1386
+ europe-west6
1387
+ GCLOUD_RUN_canonicalHostSuffix: |-
1388
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1389
+ _ALL_ENV_VAR_KEYS: |-
1390
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOSTNAME","ROOT_URL","HOSTNAME_INTERNAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1391
+
1392
+ EOF
1393
+ - collapseable_section_end "writeenvvars"
1394
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1395
+ - gcloud run deploy pan-test-app-prod-api --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-service-name=pan-test-app-prod-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1396
+ - gcloud beta run worker-pools deploy pan-test-app-prod-api-worker --command="yarn,start:worker" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-worker-pool-name=pan-test-app-prod-api-worker --env-vars-file=____envvars.yaml --instances=1 --cpu=1 --memory=512Mi
1397
+ - collapseable_section_end "deploy"
1398
+ - collapseable_section_start "cleanup" "Cleanup"
1399
+ - set +e
1400
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-prod-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | tail -n +6 | while read -r revisionname; do gcloud run revisions delete --project=google-project-id --region=europe-west6 --quiet $revisionname ; done
1401
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +7 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api@$version --quiet --delete-tags; done
1402
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1403
+ - set -e
1404
+ - collapseable_section_end "cleanup"
1405
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1406
+ environment:
1407
+ name: prod/api
1408
+ url: $CL_GITLAB_ENVIRONMENT_URL
1409
+ on_stop: 'api 🛑 Stop ⚠️ | prod '
1410
+ artifacts:
1411
+ reports:
1412
+ dotenv: gitlab_environment.env
1413
+ rules:
1414
+ - when: never
1415
+ if: $CI_PIPELINE_SOURCE == "trigger"
1416
+ - when: manual
1417
+ if: $CI_COMMIT_TAG
1418
+ needs:
1419
+ - job: 'api 🔨 app | prod '
1420
+ artifacts: false
1421
+ - job: 'api 🔨 docker | prod '
1422
+ artifacts: false
1423
+ retry: *a1
1424
+ interruptible: true
1425
+ allow_failure: true
1426
+ 'api 🛑 Stop ⚠️ | prod ':
1427
+ stage: stop prod
1428
+ image: path/to/docker/gcloud:the-version
1429
+ variables:
1430
+ KUBERNETES_CPU_REQUEST: '0.22'
1431
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1432
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1433
+ GIT_STRATEGY: none
1434
+ script:
1435
+ - collapseable_section_start "injectvars" "Injecting variables"
1436
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1437
+ - collapseable_section_end "injectvars"
1438
+ - set +e
1439
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1440
+ - gcloud run services delete pan-test-app-prod-api --project=google-project-id --region=europe-west6
1441
+ - gcloud beta run worker-pools delete pan-test-app-prod-api-worker --project=google-project-id --region=europe-west6
1442
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
1443
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1444
+ - set -e
1445
+ environment:
1446
+ name: prod/api
1447
+ action: stop
1448
+ rules:
1449
+ - when: never
1450
+ if: $CI_PIPELINE_SOURCE == "trigger"
1451
+ - when: manual
1452
+ if: $CI_COMMIT_TAG
1453
+ needs: []
1454
+ retry: *a1
1455
+ interruptible: true
1456
+ allow_failure: true
1457
+ create release:
1458
+ stage: release
1459
+ image: path/to/docker/semantic-release:the-version
1460
+ script:
1461
+ - semanticRelease
1462
+ after_script:
1463
+ - echo '👉 If this job failed with access denied, the project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1464
+ rules:
1465
+ - &a2
1466
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1467
+ when: never
1468
+ - &a3
1469
+ if: $CI_PIPELINE_SOURCE == "trigger"
1470
+ when: never
1471
+ - &a4
1472
+ if: $CI_PIPELINE_SOURCE == "schedule"
1473
+ when: never
1474
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1475
+ when: manual
1476
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1477
+ when: manual
1478
+ ⚠️ force create release:
1479
+ stage: release
1480
+ image: path/to/docker/semantic-release:the-version
1481
+ script:
1482
+ - semanticRelease
1483
+ after_script:
1484
+ - echo '👉 If this job failed with access denied, the project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1485
+ rules:
1486
+ - *a2
1487
+ - *a3
1488
+ - *a4
1489
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1490
+ when: manual
1491
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1492
+ when: manual
1493
+ needs: []
1494
+ "
1495
+ `;