@catladder/pipeline 3.7.0 โ†’ 3.8.1

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