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