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