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