@catladder/pipeline 3.36.1 โ†’ 3.37.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,1601 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`matches snapshot for cloud-run-session-affinity 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
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 ๐Ÿงพ sbom | dev ':
357
+ stage: build
358
+ image:
359
+ name: aquasec/trivy:0.58.2
360
+ entrypoint:
361
+ - ''
362
+ variables: {}
363
+ script:
364
+ - collapseable_section_start "injectvars" "Injecting variables"
365
+ - collapseable_section_end "injectvars"
366
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
367
+ artifacts:
368
+ paths:
369
+ - __sbom.json
370
+ rules:
371
+ - when: never
372
+ if: $CI_PIPELINE_SOURCE == "trigger"
373
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
374
+ needs: []
375
+ retry: *a1
376
+ interruptible: true
377
+ allow_failure: true
378
+ 'api ๐Ÿš€ Deploy | dev ':
379
+ stage: deploy dev
380
+ image: path/to/docker/gcloud:the-version
381
+ variables:
382
+ KUBERNETES_CPU_REQUEST: '0.22'
383
+ KUBERNETES_MEMORY_REQUEST: 200Mi
384
+ KUBERNETES_MEMORY_LIMIT: 400Mi
385
+ script:
386
+ - collapseable_section_start "injectvars" "Injecting variables"
387
+ - export ENV_SHORT="dev"
388
+ - export APP_DIR="api"
389
+ - export ENV_TYPE="dev"
390
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
391
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
392
+ - 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")"
393
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
394
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
395
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
396
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
397
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
398
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
399
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
400
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
401
+ - 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\\"]"
402
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
403
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
404
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
405
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
406
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
407
+ - collapseable_section_end "injectvars"
408
+ - collapseable_section_start "prepare" "Prepare..."
409
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
410
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
411
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
412
+ - collapseable_section_end "prepare"
413
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
414
+ - |
415
+ cat > ____envvars.yaml <<EOF
416
+ ENV_SHORT: |-
417
+ dev
418
+ APP_DIR: |-
419
+ api
420
+ ENV_TYPE: |-
421
+ dev
422
+ BUILD_INFO_BUILD_ID: |-
423
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
424
+ BUILD_INFO_BUILD_TIME: |-
425
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
426
+ BUILD_INFO_CURRENT_VERSION: |-
427
+ $(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/^/ /')
428
+ HOSTNAME: |-
429
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
430
+ ROOT_URL: |-
431
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
432
+ HOSTNAME_INTERNAL: |-
433
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
434
+ ROOT_URL_INTERNAL: |-
435
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
436
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
437
+ google-project-id
438
+ DEPLOY_CLOUD_RUN_REGION: |-
439
+ europe-west6
440
+ GCLOUD_RUN_canonicalHostSuffix: |-
441
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
442
+ _ALL_ENV_VAR_KEYS: |-
443
+ ["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"]
444
+
445
+ EOF
446
+ - collapseable_section_end "writeenvvars"
447
+ - collapseable_section_start "deploy" "Deploy to cloud run"
448
+ - 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 --session-affinity --cpu-boost
449
+ - collapseable_section_end "deploy"
450
+ - collapseable_section_start "cleanup" "Cleanup"
451
+ - set +e
452
+ - 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
453
+ - 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
454
+ - 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
455
+ - set -e
456
+ - collapseable_section_end "cleanup"
457
+ - echo 'Uploading SBOM to Dependency Track'
458
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
459
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
460
+ environment:
461
+ name: dev/api
462
+ url: $CL_GITLAB_ENVIRONMENT_URL
463
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | dev '
464
+ auto_stop_in: 4 weeks
465
+ artifacts:
466
+ reports:
467
+ dotenv: gitlab_environment.env
468
+ rules:
469
+ - when: never
470
+ if: $CI_PIPELINE_SOURCE == "trigger"
471
+ - when: on_success
472
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
473
+ needs:
474
+ - job: 'api ๐Ÿ‘ฎ lint | dev '
475
+ artifacts: false
476
+ - job: 'api ๐Ÿ”จ app | dev '
477
+ artifacts: false
478
+ - job: 'api ๐Ÿ”จ docker | dev '
479
+ artifacts: false
480
+ - job: 'api ๐Ÿงช test | dev '
481
+ artifacts: false
482
+ - job: 'api ๐Ÿงพ sbom | dev '
483
+ artifacts: true
484
+ - job: 'api ๐Ÿ›ก audit | dev '
485
+ artifacts: false
486
+ retry: *a1
487
+ interruptible: true
488
+ allow_failure: false
489
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | dev ':
490
+ stage: stop dev
491
+ image: path/to/docker/gcloud:the-version
492
+ variables:
493
+ KUBERNETES_CPU_REQUEST: '0.22'
494
+ KUBERNETES_MEMORY_REQUEST: 200Mi
495
+ KUBERNETES_MEMORY_LIMIT: 400Mi
496
+ GIT_STRATEGY: none
497
+ script:
498
+ - collapseable_section_start "injectvars" "Injecting variables"
499
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
500
+ - collapseable_section_end "injectvars"
501
+ - set +e
502
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
503
+ - gcloud run services delete pan-test-app-dev-api --project=google-project-id --region=europe-west6
504
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
505
+ - 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
506
+ - echo 'Disabling component in Dependency Track'
507
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
508
+ - set -e
509
+ environment:
510
+ name: dev/api
511
+ action: stop
512
+ rules:
513
+ - when: never
514
+ if: $CI_PIPELINE_SOURCE == "trigger"
515
+ - when: manual
516
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
517
+ needs: []
518
+ retry: *a1
519
+ interruptible: true
520
+ allow_failure: true
521
+ 'api ๐Ÿ›ก audit | review ':
522
+ stage: test
523
+ image: path/to/docker/jobs-default:the-version
524
+ variables:
525
+ KUBERNETES_CPU_REQUEST: '0.45'
526
+ KUBERNETES_MEMORY_REQUEST: 1Gi
527
+ KUBERNETES_MEMORY_LIMIT: 4Gi
528
+ script:
529
+ - collapseable_section_start "injectvars" "Injecting variables"
530
+ - export APP_PATH="api"
531
+ - collapseable_section_end "injectvars"
532
+ - cd api
533
+ - yarn npm audit --environment production
534
+ rules:
535
+ - when: never
536
+ if: $CI_PIPELINE_SOURCE == "trigger"
537
+ - if: $CI_MERGE_REQUEST_ID
538
+ needs: []
539
+ retry: *a1
540
+ interruptible: true
541
+ allow_failure: true
542
+ 'api ๐Ÿ‘ฎ lint | review ':
543
+ stage: test
544
+ image: path/to/docker/jobs-default:the-version
545
+ variables:
546
+ KUBERNETES_CPU_REQUEST: '0.45'
547
+ KUBERNETES_MEMORY_REQUEST: 1Gi
548
+ KUBERNETES_MEMORY_LIMIT: 4Gi
549
+ script:
550
+ - collapseable_section_start "injectvars" "Injecting variables"
551
+ - export APP_PATH="api"
552
+ - collapseable_section_end "injectvars"
553
+ - collapseable_section_start "nodeinstall" "Ensure node version"
554
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
555
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
556
+ - collapseable_section_end "nodeinstall"
557
+ - cd api
558
+ - collapseable_section_start "nodeinstall" "Ensure node version"
559
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
560
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
561
+ - collapseable_section_end "nodeinstall"
562
+ - collapseable_section_start "yarninstall" "Yarn install"
563
+ - yarn install --immutable --inline-builds
564
+ - collapseable_section_end "yarninstall"
565
+ - yarn lint
566
+ cache:
567
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
568
+ policy: pull-push
569
+ paths:
570
+ - api/.yarn
571
+ fallback_keys:
572
+ - api-yarn
573
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
574
+ policy: pull-push
575
+ paths:
576
+ - api/node_modules
577
+ - api/.yarn/install-state.gz
578
+ fallback_keys:
579
+ - api-node-modules
580
+ rules:
581
+ - when: never
582
+ if: $CI_PIPELINE_SOURCE == "trigger"
583
+ - if: $CI_MERGE_REQUEST_ID
584
+ needs: []
585
+ retry: *a1
586
+ interruptible: true
587
+ 'api ๐Ÿงช test | review ':
588
+ stage: test
589
+ image: path/to/docker/jobs-testing-chrome:the-version
590
+ variables:
591
+ KUBERNETES_CPU_REQUEST: '0.45'
592
+ KUBERNETES_MEMORY_REQUEST: 1Gi
593
+ KUBERNETES_MEMORY_LIMIT: 4Gi
594
+ script:
595
+ - collapseable_section_start "injectvars" "Injecting variables"
596
+ - export APP_PATH="api"
597
+ - collapseable_section_end "injectvars"
598
+ - collapseable_section_start "nodeinstall" "Ensure node version"
599
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
600
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
601
+ - collapseable_section_end "nodeinstall"
602
+ - cd api
603
+ - collapseable_section_start "nodeinstall" "Ensure node version"
604
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
605
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
606
+ - collapseable_section_end "nodeinstall"
607
+ - collapseable_section_start "yarninstall" "Yarn install"
608
+ - yarn install --immutable --inline-builds
609
+ - collapseable_section_end "yarninstall"
610
+ - yarn test
611
+ cache:
612
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
613
+ policy: pull-push
614
+ paths:
615
+ - api/.yarn
616
+ fallback_keys:
617
+ - api-yarn
618
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
619
+ policy: pull-push
620
+ paths:
621
+ - api/node_modules
622
+ - api/.yarn/install-state.gz
623
+ fallback_keys:
624
+ - api-node-modules
625
+ rules:
626
+ - when: never
627
+ if: $CI_PIPELINE_SOURCE == "trigger"
628
+ - if: $CI_MERGE_REQUEST_ID
629
+ needs: []
630
+ retry: *a1
631
+ interruptible: true
632
+ 'api ๐Ÿ”จ app | review ':
633
+ stage: build
634
+ image: path/to/docker/jobs-default:the-version
635
+ variables:
636
+ KUBERNETES_CPU_REQUEST: '0.45'
637
+ KUBERNETES_MEMORY_REQUEST: 1Gi
638
+ KUBERNETES_MEMORY_LIMIT: 4Gi
639
+ script:
640
+ - collapseable_section_start "injectvars" "Injecting variables"
641
+ - export ENV_SHORT="review"
642
+ - export APP_DIR="api"
643
+ - export ENV_TYPE="review"
644
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
645
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
646
+ - 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")"
647
+ - 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)}')"
648
+ - 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)}')"
649
+ - 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)}')"
650
+ - 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)}')"
651
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
652
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
653
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
654
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
655
+ - 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\\"]"
656
+ - collapseable_section_end "injectvars"
657
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
658
+ - |-
659
+ cat <<EOF > api/.env
660
+ ENV_SHORT=review
661
+ APP_DIR=api
662
+ ENV_TYPE=review
663
+ 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)
664
+ 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)
665
+ 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)
666
+ 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)
667
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
668
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
669
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
670
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
671
+ _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"]
672
+ EOF
673
+ - collapseable_section_end "write-dotenv-api"
674
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
675
+ - collapseable_section_start "nodeinstall" "Ensure node version"
676
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
677
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
678
+ - collapseable_section_end "nodeinstall"
679
+ - cd api
680
+ - collapseable_section_start "nodeinstall" "Ensure node version"
681
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
682
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
683
+ - collapseable_section_end "nodeinstall"
684
+ - collapseable_section_start "yarninstall" "Yarn install"
685
+ - yarn install --immutable --inline-builds
686
+ - collapseable_section_end "yarninstall"
687
+ - yarn build
688
+ cache:
689
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
690
+ policy: pull-push
691
+ paths:
692
+ - api/.yarn
693
+ fallback_keys:
694
+ - api-yarn
695
+ - key: api-node-modules-mr$CI_MERGE_REQUEST_IID
696
+ policy: pull-push
697
+ paths:
698
+ - api/node_modules
699
+ - api/.yarn/install-state.gz
700
+ fallback_keys:
701
+ - api-node-modules
702
+ artifacts:
703
+ paths:
704
+ - api/__build_info.json
705
+ - api/.next
706
+ - api/dist
707
+ exclude:
708
+ - api/.env
709
+ - api/.next/cache/**/*
710
+ expire_in: 1 day
711
+ when: always
712
+ reports: {}
713
+ rules:
714
+ - when: never
715
+ if: $CI_PIPELINE_SOURCE == "trigger"
716
+ - if: $CI_MERGE_REQUEST_ID
717
+ needs: []
718
+ retry: *a1
719
+ interruptible: true
720
+ 'api ๐Ÿ”จ docker | review ':
721
+ stage: build
722
+ image: path/to/docker/docker-build:the-version
723
+ services:
724
+ - name: docker:24.0.6-dind
725
+ command:
726
+ - --tls=false
727
+ - --registry-mirror=https://mirror.gcr.io
728
+ variables:
729
+ DOCKER_HOST: tcp://docker:2375
730
+ DOCKER_TLS_CERTDIR: ''
731
+ DOCKER_DRIVER: overlay2
732
+ DOCKER_BUILDKIT: '1'
733
+ KUBERNETES_CPU_REQUEST: '0.45'
734
+ KUBERNETES_MEMORY_REQUEST: 1Gi
735
+ KUBERNETES_MEMORY_LIMIT: 2Gi
736
+ script:
737
+ - collapseable_section_start "injectvars" "Injecting variables"
738
+ - export APP_DIR="api"
739
+ - export DOCKER_BUILD_CONTEXT="."
740
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
741
+ - 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"; })"
742
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
743
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
744
+ - |-
745
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
746
+ COPY --chown=node:node $APP_DIR .
747
+ RUN yarn plugin import workspace-tools
748
+ RUN yarn workspaces focus --production
749
+ RUN yarn rebuild"
750
+ - |-
751
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
752
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
753
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
754
+ COPY --chown=node:node .yarn /app/.yarn"
755
+ - collapseable_section_end "injectvars"
756
+ - ensureNodeDockerfile
757
+ - collapseable_section_start "docker-login" "Docker Login"
758
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
759
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
760
+ - collapseable_section_end "docker-login"
761
+ - collapseable_section_start "docker-build" "Docker build"
762
+ - 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
763
+ - collapseable_section_end "docker-build"
764
+ - collapseable_section_start "docker-push" "Docker push and tag"
765
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
766
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
767
+ - docker push $DOCKER_CACHE_IMAGE
768
+ - collapseable_section_end "docker-push"
769
+ cache:
770
+ - key: api-yarn-mr$CI_MERGE_REQUEST_IID
771
+ policy: pull
772
+ paths:
773
+ - api/.yarn
774
+ fallback_keys:
775
+ - api-yarn
776
+ rules:
777
+ - when: never
778
+ if: $CI_PIPELINE_SOURCE == "trigger"
779
+ - if: $CI_MERGE_REQUEST_ID
780
+ needs:
781
+ - 'api ๐Ÿ”จ app | review '
782
+ retry: *a1
783
+ interruptible: true
784
+ 'api ๐Ÿงพ sbom | review ':
785
+ stage: build
786
+ image:
787
+ name: aquasec/trivy:0.58.2
788
+ entrypoint:
789
+ - ''
790
+ variables: {}
791
+ script:
792
+ - collapseable_section_start "injectvars" "Injecting variables"
793
+ - collapseable_section_end "injectvars"
794
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
795
+ artifacts:
796
+ paths:
797
+ - __sbom.json
798
+ rules:
799
+ - when: never
800
+ if: $CI_PIPELINE_SOURCE == "trigger"
801
+ - if: $CI_MERGE_REQUEST_ID
802
+ needs: []
803
+ retry: *a1
804
+ interruptible: true
805
+ allow_failure: true
806
+ 'api ๐Ÿš€ Deploy | review ':
807
+ stage: deploy review
808
+ image: path/to/docker/gcloud:the-version
809
+ variables:
810
+ KUBERNETES_CPU_REQUEST: '0.22'
811
+ KUBERNETES_MEMORY_REQUEST: 200Mi
812
+ KUBERNETES_MEMORY_LIMIT: 400Mi
813
+ script:
814
+ - collapseable_section_start "injectvars" "Injecting variables"
815
+ - export ENV_SHORT="review"
816
+ - export APP_DIR="api"
817
+ - export ENV_TYPE="review"
818
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
819
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
820
+ - 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")"
821
+ - 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)}')"
822
+ - 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)}')"
823
+ - 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)}')"
824
+ - 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)}')"
825
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
826
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
827
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
828
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
829
+ - 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\\"]"
830
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
831
+ - 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"; })"
832
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
833
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
834
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
835
+ - collapseable_section_end "injectvars"
836
+ - collapseable_section_start "prepare" "Prepare..."
837
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
838
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
839
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
840
+ - collapseable_section_end "prepare"
841
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
842
+ - |
843
+ cat > ____envvars.yaml <<EOF
844
+ ENV_SHORT: |-
845
+ review
846
+ APP_DIR: |-
847
+ api
848
+ ENV_TYPE: |-
849
+ review
850
+ BUILD_INFO_BUILD_ID: |-
851
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
852
+ BUILD_INFO_BUILD_TIME: |-
853
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
854
+ BUILD_INFO_CURRENT_VERSION: |-
855
+ $(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/^/ /')
856
+ HOSTNAME: |-
857
+ $(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/^/ /')
858
+ ROOT_URL: |-
859
+ $(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/^/ /')
860
+ HOSTNAME_INTERNAL: |-
861
+ $(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/^/ /')
862
+ ROOT_URL_INTERNAL: |-
863
+ $(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/^/ /')
864
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
865
+ google-project-id
866
+ DEPLOY_CLOUD_RUN_REGION: |-
867
+ europe-west6
868
+ GCLOUD_RUN_canonicalHostSuffix: |-
869
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
870
+ _ALL_ENV_VAR_KEYS: |-
871
+ ["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"]
872
+
873
+ EOF
874
+ - collapseable_section_end "writeenvvars"
875
+ - collapseable_section_start "deploy" "Deploy to cloud run"
876
+ - 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 --session-affinity --cpu-boost
877
+ - collapseable_section_end "deploy"
878
+ - collapseable_section_start "cleanup" "Cleanup"
879
+ - set +e
880
+ - 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
881
+ - 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
882
+ - 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
883
+ - set +e
884
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
885
+ - set -e
886
+ - set -e
887
+ - collapseable_section_end "cleanup"
888
+ - echo 'Uploading SBOM to Dependency Track'
889
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
890
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
891
+ environment:
892
+ name: review/$CI_COMMIT_REF_NAME/api
893
+ url: $CL_GITLAB_ENVIRONMENT_URL
894
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | review '
895
+ auto_stop_in: 1 week
896
+ artifacts:
897
+ reports:
898
+ dotenv: gitlab_environment.env
899
+ rules:
900
+ - when: never
901
+ if: $CI_PIPELINE_SOURCE == "trigger"
902
+ - when: on_success
903
+ if: $CI_MERGE_REQUEST_ID
904
+ needs:
905
+ - job: 'api ๐Ÿ‘ฎ lint | review '
906
+ artifacts: false
907
+ - job: 'api ๐Ÿ”จ app | review '
908
+ artifacts: false
909
+ - job: 'api ๐Ÿ”จ docker | review '
910
+ artifacts: false
911
+ - job: 'api ๐Ÿงช test | review '
912
+ artifacts: false
913
+ - job: 'api ๐Ÿงพ sbom | review '
914
+ artifacts: true
915
+ - job: 'api ๐Ÿ›ก audit | review '
916
+ artifacts: false
917
+ retry: *a1
918
+ interruptible: true
919
+ allow_failure: false
920
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | review ':
921
+ stage: stop review
922
+ image: path/to/docker/gcloud:the-version
923
+ variables:
924
+ KUBERNETES_CPU_REQUEST: '0.22'
925
+ KUBERNETES_MEMORY_REQUEST: 200Mi
926
+ KUBERNETES_MEMORY_LIMIT: 400Mi
927
+ GIT_STRATEGY: none
928
+ script:
929
+ - collapseable_section_start "injectvars" "Injecting variables"
930
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
931
+ - collapseable_section_end "injectvars"
932
+ - set +e
933
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
934
+ - 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
935
+ - 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
936
+ - 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
937
+ - set +e
938
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
939
+ - set -e
940
+ - echo 'Disabling component in Dependency Track'
941
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
942
+ - set -e
943
+ environment:
944
+ name: review/$CI_COMMIT_REF_NAME/api
945
+ action: stop
946
+ rules:
947
+ - when: never
948
+ if: $CI_PIPELINE_SOURCE == "trigger"
949
+ - when: manual
950
+ if: $CI_MERGE_REQUEST_ID
951
+ needs: []
952
+ retry: *a1
953
+ interruptible: true
954
+ allow_failure: true
955
+ 'api ๐Ÿ”จ app | stage ':
956
+ stage: build
957
+ image: path/to/docker/jobs-default:the-version
958
+ variables:
959
+ KUBERNETES_CPU_REQUEST: '0.45'
960
+ KUBERNETES_MEMORY_REQUEST: 1Gi
961
+ KUBERNETES_MEMORY_LIMIT: 4Gi
962
+ script:
963
+ - collapseable_section_start "injectvars" "Injecting variables"
964
+ - export ENV_SHORT="stage"
965
+ - export APP_DIR="api"
966
+ - export ENV_TYPE="stage"
967
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
968
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
969
+ - 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")"
970
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
971
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
972
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
973
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
974
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
975
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
976
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
977
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
978
+ - 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\\"]"
979
+ - collapseable_section_end "injectvars"
980
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
981
+ - |-
982
+ cat <<EOF > api/.env
983
+ ENV_SHORT=stage
984
+ APP_DIR=api
985
+ ENV_TYPE=stage
986
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
987
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
988
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
989
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
990
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
991
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
992
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
993
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
994
+ _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"]
995
+ EOF
996
+ - collapseable_section_end "write-dotenv-api"
997
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
998
+ - collapseable_section_start "nodeinstall" "Ensure node version"
999
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1000
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1001
+ - collapseable_section_end "nodeinstall"
1002
+ - cd api
1003
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1004
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1005
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1006
+ - collapseable_section_end "nodeinstall"
1007
+ - collapseable_section_start "yarninstall" "Yarn install"
1008
+ - yarn install --immutable --inline-builds
1009
+ - collapseable_section_end "yarninstall"
1010
+ - yarn build
1011
+ cache:
1012
+ - key: api-yarn
1013
+ policy: pull-push
1014
+ paths:
1015
+ - api/.yarn
1016
+ - key: api-node-modules
1017
+ policy: pull-push
1018
+ paths:
1019
+ - api/node_modules
1020
+ - api/.yarn/install-state.gz
1021
+ artifacts:
1022
+ paths:
1023
+ - api/__build_info.json
1024
+ - api/.next
1025
+ - api/dist
1026
+ exclude:
1027
+ - api/.env
1028
+ - api/.next/cache/**/*
1029
+ expire_in: 1 day
1030
+ when: always
1031
+ reports: {}
1032
+ rules:
1033
+ - when: never
1034
+ if: $CI_PIPELINE_SOURCE == "trigger"
1035
+ - if: $CI_COMMIT_TAG
1036
+ needs: []
1037
+ retry: *a1
1038
+ interruptible: true
1039
+ 'api ๐Ÿ”จ docker | stage ':
1040
+ stage: build
1041
+ image: path/to/docker/docker-build:the-version
1042
+ services:
1043
+ - name: docker:24.0.6-dind
1044
+ command:
1045
+ - --tls=false
1046
+ - --registry-mirror=https://mirror.gcr.io
1047
+ variables:
1048
+ DOCKER_HOST: tcp://docker:2375
1049
+ DOCKER_TLS_CERTDIR: ''
1050
+ DOCKER_DRIVER: overlay2
1051
+ DOCKER_BUILDKIT: '1'
1052
+ KUBERNETES_CPU_REQUEST: '0.45'
1053
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1054
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1055
+ script:
1056
+ - collapseable_section_start "injectvars" "Injecting variables"
1057
+ - export APP_DIR="api"
1058
+ - export DOCKER_BUILD_CONTEXT="."
1059
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1060
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1061
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1062
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1063
+ - |-
1064
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
1065
+ COPY --chown=node:node $APP_DIR .
1066
+ RUN yarn plugin import workspace-tools
1067
+ RUN yarn workspaces focus --production
1068
+ RUN yarn rebuild"
1069
+ - |-
1070
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1071
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1072
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1073
+ COPY --chown=node:node .yarn /app/.yarn"
1074
+ - collapseable_section_end "injectvars"
1075
+ - ensureNodeDockerfile
1076
+ - collapseable_section_start "docker-login" "Docker Login"
1077
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1078
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1079
+ - collapseable_section_end "docker-login"
1080
+ - collapseable_section_start "docker-build" "Docker build"
1081
+ - 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
1082
+ - collapseable_section_end "docker-build"
1083
+ - collapseable_section_start "docker-push" "Docker push and tag"
1084
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1085
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1086
+ - docker push $DOCKER_CACHE_IMAGE
1087
+ - collapseable_section_end "docker-push"
1088
+ cache:
1089
+ - key: api-yarn
1090
+ policy: pull
1091
+ paths:
1092
+ - api/.yarn
1093
+ rules:
1094
+ - when: never
1095
+ if: $CI_PIPELINE_SOURCE == "trigger"
1096
+ - if: $CI_COMMIT_TAG
1097
+ needs:
1098
+ - 'api ๐Ÿ”จ app | stage '
1099
+ retry: *a1
1100
+ interruptible: true
1101
+ 'api ๐Ÿงพ sbom | stage ':
1102
+ stage: build
1103
+ image:
1104
+ name: aquasec/trivy:0.58.2
1105
+ entrypoint:
1106
+ - ''
1107
+ variables: {}
1108
+ script:
1109
+ - collapseable_section_start "injectvars" "Injecting variables"
1110
+ - collapseable_section_end "injectvars"
1111
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1112
+ artifacts:
1113
+ paths:
1114
+ - __sbom.json
1115
+ rules:
1116
+ - when: never
1117
+ if: $CI_PIPELINE_SOURCE == "trigger"
1118
+ - if: $CI_COMMIT_TAG
1119
+ needs: []
1120
+ retry: *a1
1121
+ interruptible: true
1122
+ allow_failure: true
1123
+ 'api ๐Ÿš€ Deploy | stage ':
1124
+ stage: deploy stage
1125
+ image: path/to/docker/gcloud:the-version
1126
+ variables:
1127
+ KUBERNETES_CPU_REQUEST: '0.22'
1128
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1129
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1130
+ script:
1131
+ - collapseable_section_start "injectvars" "Injecting variables"
1132
+ - export ENV_SHORT="stage"
1133
+ - export APP_DIR="api"
1134
+ - export ENV_TYPE="stage"
1135
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1136
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1137
+ - 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")"
1138
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1139
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1140
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1141
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1142
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1143
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1144
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
1145
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
1146
+ - 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\\"]"
1147
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1148
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1149
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1150
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1151
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1152
+ - collapseable_section_end "injectvars"
1153
+ - collapseable_section_start "prepare" "Prepare..."
1154
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1155
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1156
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1157
+ - collapseable_section_end "prepare"
1158
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1159
+ - |
1160
+ cat > ____envvars.yaml <<EOF
1161
+ ENV_SHORT: |-
1162
+ stage
1163
+ APP_DIR: |-
1164
+ api
1165
+ ENV_TYPE: |-
1166
+ stage
1167
+ BUILD_INFO_BUILD_ID: |-
1168
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1169
+ BUILD_INFO_BUILD_TIME: |-
1170
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1171
+ BUILD_INFO_CURRENT_VERSION: |-
1172
+ $(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/^/ /')
1173
+ HOSTNAME: |-
1174
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1175
+ ROOT_URL: |-
1176
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1177
+ HOSTNAME_INTERNAL: |-
1178
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1179
+ ROOT_URL_INTERNAL: |-
1180
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1181
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1182
+ google-project-id
1183
+ DEPLOY_CLOUD_RUN_REGION: |-
1184
+ europe-west6
1185
+ GCLOUD_RUN_canonicalHostSuffix: |-
1186
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1187
+ _ALL_ENV_VAR_KEYS: |-
1188
+ ["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"]
1189
+
1190
+ EOF
1191
+ - collapseable_section_end "writeenvvars"
1192
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1193
+ - 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 --session-affinity --cpu-boost
1194
+ - collapseable_section_end "deploy"
1195
+ - collapseable_section_start "cleanup" "Cleanup"
1196
+ - set +e
1197
+ - 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
1198
+ - 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
1199
+ - 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
1200
+ - set -e
1201
+ - collapseable_section_end "cleanup"
1202
+ - echo 'Uploading SBOM to Dependency Track'
1203
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
1204
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1205
+ environment:
1206
+ name: stage/api
1207
+ url: $CL_GITLAB_ENVIRONMENT_URL
1208
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | stage '
1209
+ artifacts:
1210
+ reports:
1211
+ dotenv: gitlab_environment.env
1212
+ rules:
1213
+ - when: never
1214
+ if: $CI_PIPELINE_SOURCE == "trigger"
1215
+ - when: on_success
1216
+ if: $CI_COMMIT_TAG
1217
+ needs:
1218
+ - job: 'api ๐Ÿ”จ app | stage '
1219
+ artifacts: false
1220
+ - job: 'api ๐Ÿ”จ docker | stage '
1221
+ artifacts: false
1222
+ - job: 'api ๐Ÿงพ sbom | stage '
1223
+ artifacts: true
1224
+ retry: *a1
1225
+ interruptible: true
1226
+ allow_failure: false
1227
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | stage ':
1228
+ stage: stop stage
1229
+ image: path/to/docker/gcloud:the-version
1230
+ variables:
1231
+ KUBERNETES_CPU_REQUEST: '0.22'
1232
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1233
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1234
+ GIT_STRATEGY: none
1235
+ script:
1236
+ - collapseable_section_start "injectvars" "Injecting variables"
1237
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1238
+ - collapseable_section_end "injectvars"
1239
+ - set +e
1240
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1241
+ - gcloud run services delete pan-test-app-stage-api --project=google-project-id --region=europe-west6
1242
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1243
+ - 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
1244
+ - echo 'Disabling component in Dependency Track'
1245
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
1246
+ - set -e
1247
+ environment:
1248
+ name: stage/api
1249
+ action: stop
1250
+ rules:
1251
+ - when: never
1252
+ if: $CI_PIPELINE_SOURCE == "trigger"
1253
+ - when: manual
1254
+ if: $CI_COMMIT_TAG
1255
+ needs: []
1256
+ retry: *a1
1257
+ interruptible: true
1258
+ allow_failure: true
1259
+ 'api ๐Ÿ”จ app | prod ':
1260
+ stage: build
1261
+ image: path/to/docker/jobs-default:the-version
1262
+ variables:
1263
+ KUBERNETES_CPU_REQUEST: '0.45'
1264
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1265
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1266
+ script:
1267
+ - collapseable_section_start "injectvars" "Injecting variables"
1268
+ - export ENV_SHORT="prod"
1269
+ - export APP_DIR="api"
1270
+ - export ENV_TYPE="prod"
1271
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1272
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1273
+ - 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")"
1274
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1275
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1276
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1277
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1278
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1279
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1280
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1281
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1282
+ - 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\\"]"
1283
+ - collapseable_section_end "injectvars"
1284
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
1285
+ - |-
1286
+ cat <<EOF > api/.env
1287
+ ENV_SHORT=prod
1288
+ APP_DIR=api
1289
+ ENV_TYPE=prod
1290
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1291
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1292
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1293
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1294
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
1295
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
1296
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
1297
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
1298
+ _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"]
1299
+ EOF
1300
+ - collapseable_section_end "write-dotenv-api"
1301
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1302
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1303
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1304
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1305
+ - collapseable_section_end "nodeinstall"
1306
+ - cd api
1307
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1308
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1309
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1310
+ - collapseable_section_end "nodeinstall"
1311
+ - collapseable_section_start "yarninstall" "Yarn install"
1312
+ - yarn install --immutable --inline-builds
1313
+ - collapseable_section_end "yarninstall"
1314
+ - yarn build
1315
+ cache:
1316
+ - key: api-yarn
1317
+ policy: pull-push
1318
+ paths:
1319
+ - api/.yarn
1320
+ - key: api-node-modules
1321
+ policy: pull-push
1322
+ paths:
1323
+ - api/node_modules
1324
+ - api/.yarn/install-state.gz
1325
+ artifacts:
1326
+ paths:
1327
+ - api/__build_info.json
1328
+ - api/.next
1329
+ - api/dist
1330
+ exclude:
1331
+ - api/.env
1332
+ - api/.next/cache/**/*
1333
+ expire_in: 1 day
1334
+ when: always
1335
+ reports: {}
1336
+ rules:
1337
+ - when: never
1338
+ if: $CI_PIPELINE_SOURCE == "trigger"
1339
+ - if: $CI_COMMIT_TAG
1340
+ needs: []
1341
+ retry: *a1
1342
+ interruptible: true
1343
+ 'api ๐Ÿ”จ docker | prod ':
1344
+ stage: build
1345
+ image: path/to/docker/docker-build:the-version
1346
+ services:
1347
+ - name: docker:24.0.6-dind
1348
+ command:
1349
+ - --tls=false
1350
+ - --registry-mirror=https://mirror.gcr.io
1351
+ variables:
1352
+ DOCKER_HOST: tcp://docker:2375
1353
+ DOCKER_TLS_CERTDIR: ''
1354
+ DOCKER_DRIVER: overlay2
1355
+ DOCKER_BUILDKIT: '1'
1356
+ KUBERNETES_CPU_REQUEST: '0.45'
1357
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1358
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1359
+ script:
1360
+ - collapseable_section_start "injectvars" "Injecting variables"
1361
+ - export APP_DIR="api"
1362
+ - export DOCKER_BUILD_CONTEXT="."
1363
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1364
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1365
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1366
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1367
+ - |-
1368
+ export DOCKER_COPY_AND_INSTALL_APP="ENV YARN_ENABLE_INLINE_BUILDS=1
1369
+ COPY --chown=node:node $APP_DIR .
1370
+ RUN yarn plugin import workspace-tools
1371
+ RUN yarn workspaces focus --production
1372
+ RUN yarn rebuild"
1373
+ - |-
1374
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1375
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1376
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1377
+ COPY --chown=node:node .yarn /app/.yarn"
1378
+ - collapseable_section_end "injectvars"
1379
+ - ensureNodeDockerfile
1380
+ - collapseable_section_start "docker-login" "Docker Login"
1381
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1382
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1383
+ - collapseable_section_end "docker-login"
1384
+ - collapseable_section_start "docker-build" "Docker build"
1385
+ - 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
1386
+ - collapseable_section_end "docker-build"
1387
+ - collapseable_section_start "docker-push" "Docker push and tag"
1388
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1389
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1390
+ - docker push $DOCKER_CACHE_IMAGE
1391
+ - collapseable_section_end "docker-push"
1392
+ cache:
1393
+ - key: api-yarn
1394
+ policy: pull
1395
+ paths:
1396
+ - api/.yarn
1397
+ rules:
1398
+ - when: never
1399
+ if: $CI_PIPELINE_SOURCE == "trigger"
1400
+ - if: $CI_COMMIT_TAG
1401
+ needs:
1402
+ - 'api ๐Ÿ”จ app | prod '
1403
+ retry: *a1
1404
+ interruptible: true
1405
+ 'api ๐Ÿงพ sbom | prod ':
1406
+ stage: build
1407
+ image:
1408
+ name: aquasec/trivy:0.58.2
1409
+ entrypoint:
1410
+ - ''
1411
+ variables: {}
1412
+ script:
1413
+ - collapseable_section_start "injectvars" "Injecting variables"
1414
+ - collapseable_section_end "injectvars"
1415
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1416
+ artifacts:
1417
+ paths:
1418
+ - __sbom.json
1419
+ rules:
1420
+ - when: never
1421
+ if: $CI_PIPELINE_SOURCE == "trigger"
1422
+ - if: $CI_COMMIT_TAG
1423
+ needs: []
1424
+ retry: *a1
1425
+ interruptible: true
1426
+ allow_failure: true
1427
+ 'api ๐Ÿš€ Deploy | prod ':
1428
+ stage: deploy prod
1429
+ image: path/to/docker/gcloud:the-version
1430
+ variables:
1431
+ KUBERNETES_CPU_REQUEST: '0.22'
1432
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1433
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1434
+ script:
1435
+ - collapseable_section_start "injectvars" "Injecting variables"
1436
+ - export ENV_SHORT="prod"
1437
+ - export APP_DIR="api"
1438
+ - export ENV_TYPE="prod"
1439
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1440
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1441
+ - 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")"
1442
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1443
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1444
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1445
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1446
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1447
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1448
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1449
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1450
+ - 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\\"]"
1451
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1452
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1453
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1454
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1455
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1456
+ - collapseable_section_end "injectvars"
1457
+ - collapseable_section_start "prepare" "Prepare..."
1458
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1459
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1460
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1461
+ - collapseable_section_end "prepare"
1462
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1463
+ - |
1464
+ cat > ____envvars.yaml <<EOF
1465
+ ENV_SHORT: |-
1466
+ prod
1467
+ APP_DIR: |-
1468
+ api
1469
+ ENV_TYPE: |-
1470
+ prod
1471
+ BUILD_INFO_BUILD_ID: |-
1472
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1473
+ BUILD_INFO_BUILD_TIME: |-
1474
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1475
+ BUILD_INFO_CURRENT_VERSION: |-
1476
+ $(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/^/ /')
1477
+ HOSTNAME: |-
1478
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1479
+ ROOT_URL: |-
1480
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1481
+ HOSTNAME_INTERNAL: |-
1482
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1483
+ ROOT_URL_INTERNAL: |-
1484
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1485
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1486
+ google-project-id
1487
+ DEPLOY_CLOUD_RUN_REGION: |-
1488
+ europe-west6
1489
+ GCLOUD_RUN_canonicalHostSuffix: |-
1490
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1491
+ _ALL_ENV_VAR_KEYS: |-
1492
+ ["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"]
1493
+
1494
+ EOF
1495
+ - collapseable_section_end "writeenvvars"
1496
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1497
+ - 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 --session-affinity --cpu-boost
1498
+ - collapseable_section_end "deploy"
1499
+ - collapseable_section_start "cleanup" "Cleanup"
1500
+ - set +e
1501
+ - 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
1502
+ - 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
1503
+ - 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
1504
+ - set -e
1505
+ - collapseable_section_end "cleanup"
1506
+ - echo 'Uploading SBOM to Dependency Track'
1507
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
1508
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1509
+ environment:
1510
+ name: prod/api
1511
+ url: $CL_GITLAB_ENVIRONMENT_URL
1512
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | prod '
1513
+ artifacts:
1514
+ reports:
1515
+ dotenv: gitlab_environment.env
1516
+ rules:
1517
+ - when: never
1518
+ if: $CI_PIPELINE_SOURCE == "trigger"
1519
+ - when: manual
1520
+ if: $CI_COMMIT_TAG
1521
+ needs:
1522
+ - job: 'api ๐Ÿ”จ app | prod '
1523
+ artifacts: false
1524
+ - job: 'api ๐Ÿ”จ docker | prod '
1525
+ artifacts: false
1526
+ - job: 'api ๐Ÿงพ sbom | prod '
1527
+ artifacts: true
1528
+ retry: *a1
1529
+ interruptible: true
1530
+ allow_failure: true
1531
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | prod ':
1532
+ stage: stop prod
1533
+ image: path/to/docker/gcloud:the-version
1534
+ variables:
1535
+ KUBERNETES_CPU_REQUEST: '0.22'
1536
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1537
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1538
+ GIT_STRATEGY: none
1539
+ script:
1540
+ - collapseable_section_start "injectvars" "Injecting variables"
1541
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1542
+ - collapseable_section_end "injectvars"
1543
+ - set +e
1544
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1545
+ - gcloud run services delete pan-test-app-prod-api --project=google-project-id --region=europe-west6
1546
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
1547
+ - 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
1548
+ - echo 'Disabling component in Dependency Track'
1549
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
1550
+ - set -e
1551
+ environment:
1552
+ name: prod/api
1553
+ action: stop
1554
+ rules:
1555
+ - when: never
1556
+ if: $CI_PIPELINE_SOURCE == "trigger"
1557
+ - when: manual
1558
+ if: $CI_COMMIT_TAG
1559
+ needs: []
1560
+ retry: *a1
1561
+ interruptible: true
1562
+ allow_failure: true
1563
+ create release:
1564
+ stage: release
1565
+ image: path/to/docker/semantic-release:the-version
1566
+ script:
1567
+ - semanticRelease
1568
+ after_script:
1569
+ - echo '๐Ÿ‘‰ If this job failed with access denied, the project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1570
+ rules:
1571
+ - &a2
1572
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1573
+ when: never
1574
+ - &a3
1575
+ if: $CI_PIPELINE_SOURCE == "trigger"
1576
+ when: never
1577
+ - &a4
1578
+ if: $CI_PIPELINE_SOURCE == "schedule"
1579
+ when: never
1580
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1581
+ when: manual
1582
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1583
+ when: manual
1584
+ โš ๏ธ force create release:
1585
+ stage: release
1586
+ image: path/to/docker/semantic-release:the-version
1587
+ script:
1588
+ - semanticRelease
1589
+ after_script:
1590
+ - echo '๐Ÿ‘‰ If this job failed with access denied, the project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1591
+ rules:
1592
+ - *a2
1593
+ - *a3
1594
+ - *a4
1595
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1596
+ when: manual
1597
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1598
+ when: manual
1599
+ needs: []
1600
+ "
1601
+ `;