@catladder/pipeline 3.9.3 โ†’ 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4515 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`matches snapshot for cloud-run-with-sql-multiple-dbs 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
+ db1 ๐Ÿ›ก 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="packages/db1"
88
+ - collapseable_section_end "injectvars"
89
+ - cd packages/db1
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
+ db1 ๐Ÿ‘ฎ 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="packages/db1"
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 packages/db1
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: packagesdb1-yarn
128
+ policy: pull-push
129
+ paths:
130
+ - packages/db1/.yarn
131
+ - key: packagesdb1-node-modules
132
+ policy: pull-push
133
+ paths:
134
+ - packages/db1/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
+ db1 ๐Ÿงช 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="packages/db1"
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 packages/db1
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: packagesdb1-yarn
167
+ policy: pull-push
168
+ paths:
169
+ - packages/db1/.yarn
170
+ - key: packagesdb1-node-modules
171
+ policy: pull-push
172
+ paths:
173
+ - packages/db1/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
+ 'db1 ๐Ÿ”จ 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="packages/db1"
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-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
196
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
197
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
198
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
199
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
200
+ - export DB_NAME="pan-test-app-dev-db1"
201
+ - export DB_USER="my-user"
202
+ - export DB_PASSWORD="$CL_dev_db1_DB_PASSWORD"
203
+ - export DATABASE_URL="postgresql://my-user:$CL_dev_db1_DB_PASSWORD@localhost/pan-test-app-dev-db1?host=/cloudsql/projectId:region:instancename"
204
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-dev-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db1_DB_PASSWORD"
205
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db1-migrate:run"
206
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
207
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
208
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey"
209
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix"
210
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
211
+ - collapseable_section_end "injectvars"
212
+ - collapseable_section_start "write-dotenv-db1" "write dot env for db1"
213
+ - |-
214
+ cat <<EOF > packages/db1/.env
215
+ ENV_SHORT=dev
216
+ APP_DIR=packages/db1
217
+ ENV_TYPE=dev
218
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
219
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
220
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
221
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
222
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
223
+ DB_NAME=pan-test-app-dev-db1
224
+ DB_USER=my-user
225
+ DB_PASSWORD=$(printf %s "$CL_dev_db1_DB_PASSWORD" | escapeForDotEnv)
226
+ DATABASE_URL=postgresql://my-user:$CL_dev_db1_DB_PASSWORD@localhost/pan-test-app-dev-db1?host=/cloudsql/projectId:region:instancename
227
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-dev-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db1_DB_PASSWORD
228
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db1-migrate:run
229
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
230
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
231
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
232
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
233
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
234
+ EOF
235
+ - collapseable_section_end "write-dotenv-db1"
236
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db1/__build_info.json
237
+ - collapseable_section_start "nodeinstall" "Ensure node version"
238
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
239
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
240
+ - collapseable_section_end "nodeinstall"
241
+ - cd packages/db1
242
+ - collapseable_section_start "nodeinstall" "Ensure node version"
243
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
244
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
245
+ - collapseable_section_end "nodeinstall"
246
+ - collapseable_section_start "yarninstall" "Yarn install"
247
+ - yarn install --immutable
248
+ - collapseable_section_end "yarninstall"
249
+ - yarn build
250
+ cache:
251
+ - key: packagesdb1-yarn
252
+ policy: pull-push
253
+ paths:
254
+ - packages/db1/.yarn
255
+ - key: packagesdb1-node-modules
256
+ policy: pull-push
257
+ paths:
258
+ - packages/db1/node_modules
259
+ artifacts:
260
+ paths:
261
+ - packages/db1/__build_info.json
262
+ - packages/db1/.next
263
+ - packages/db1/dist
264
+ exclude:
265
+ - packages/db1/.env
266
+ expire_in: 1 day
267
+ when: always
268
+ reports: {}
269
+ rules:
270
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
271
+ needs: []
272
+ retry: *a1
273
+ interruptible: true
274
+ 'db1 ๐Ÿ”จ docker | dev ':
275
+ stage: build
276
+ image: path/to/docker/docker-build:the-version
277
+ services:
278
+ - name: docker:24.0.6-dind
279
+ command:
280
+ - --tls=false
281
+ - --registry-mirror=https://mirror.gcr.io
282
+ variables:
283
+ DOCKER_HOST: tcp://docker:2375
284
+ DOCKER_TLS_CERTDIR: ''
285
+ DOCKER_DRIVER: overlay2
286
+ DOCKER_BUILDKIT: '1'
287
+ KUBERNETES_CPU_REQUEST: '0.45'
288
+ KUBERNETES_MEMORY_REQUEST: 1Gi
289
+ KUBERNETES_MEMORY_LIMIT: 2Gi
290
+ script:
291
+ - collapseable_section_start "injectvars" "Injecting variables"
292
+ - export APP_DIR="packages/db1"
293
+ - export DOCKER_BUILD_CONTEXT="."
294
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
295
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1"
296
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
297
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
298
+ - |-
299
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
300
+ RUN yarn plugin import workspace-tools
301
+ RUN yarn workspaces focus --production && yarn rebuild"
302
+ - |-
303
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db1/package.json /app/packages/db1/package.json
304
+ COPY --chown=node:node packages/db1/yarn.lock /app/packages/db1/yarn.lock
305
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
306
+ COPY --chown=node:node .yarn /app/.yarn"
307
+ - collapseable_section_end "injectvars"
308
+ - ensureNodeDockerfile
309
+ - collapseable_section_start "docker-login" "Docker Login"
310
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey")
311
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
312
+ - collapseable_section_end "docker-login"
313
+ - collapseable_section_start "docker-build" "Docker build"
314
+ - 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
315
+ - collapseable_section_end "docker-build"
316
+ - collapseable_section_start "docker-push" "Docker push and tag"
317
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
318
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
319
+ - docker push $DOCKER_CACHE_IMAGE
320
+ - collapseable_section_end "docker-push"
321
+ cache:
322
+ - key: packagesdb1-yarn
323
+ policy: pull
324
+ paths:
325
+ - packages/db1/.yarn
326
+ rules:
327
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
328
+ needs:
329
+ - 'db1 ๐Ÿ”จ app | dev '
330
+ retry: *a1
331
+ interruptible: true
332
+ 'db1 ๐Ÿงพ sbom | dev ':
333
+ stage: build
334
+ image:
335
+ name: aquasec/trivy:0.58.2
336
+ entrypoint:
337
+ - ''
338
+ variables: {}
339
+ script:
340
+ - collapseable_section_start "injectvars" "Injecting variables"
341
+ - collapseable_section_end "injectvars"
342
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db1
343
+ artifacts:
344
+ paths:
345
+ - __sbom.json
346
+ rules:
347
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
348
+ needs: []
349
+ retry: *a1
350
+ interruptible: true
351
+ allow_failure: true
352
+ 'db1 ๐Ÿš€ Deploy | dev ':
353
+ stage: deploy dev
354
+ image: path/to/docker/gcloud:the-version
355
+ variables:
356
+ KUBERNETES_CPU_REQUEST: '0.22'
357
+ KUBERNETES_MEMORY_REQUEST: 200Mi
358
+ KUBERNETES_MEMORY_LIMIT: 400Mi
359
+ script:
360
+ - collapseable_section_start "injectvars" "Injecting variables"
361
+ - export ENV_SHORT="dev"
362
+ - export APP_DIR="packages/db1"
363
+ - export ENV_TYPE="dev"
364
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
365
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
366
+ - 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")"
367
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
368
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
369
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
370
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
371
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
372
+ - export DB_NAME="pan-test-app-dev-db1"
373
+ - export DB_USER="my-user"
374
+ - export DB_PASSWORD="$CL_dev_db1_DB_PASSWORD"
375
+ - export DATABASE_URL="postgresql://my-user:$CL_dev_db1_DB_PASSWORD@localhost/pan-test-app-dev-db1?host=/cloudsql/projectId:region:instancename"
376
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-dev-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db1_DB_PASSWORD"
377
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db1-migrate:run"
378
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
379
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
380
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey"
381
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix"
382
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
383
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
384
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1"
385
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
386
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
387
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
388
+ - collapseable_section_end "injectvars"
389
+ - collapseable_section_start "prepare" "Prepare..."
390
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey")
391
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
392
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
393
+ - collapseable_section_end "prepare"
394
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
395
+ - |
396
+ cat > ____envvars.yaml <<EOF
397
+ ENV_SHORT: |-
398
+ dev
399
+ APP_DIR: |-
400
+ packages/db1
401
+ ENV_TYPE: |-
402
+ dev
403
+ BUILD_INFO_BUILD_ID: |-
404
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
405
+ BUILD_INFO_BUILD_TIME: |-
406
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
407
+ BUILD_INFO_CURRENT_VERSION: |-
408
+ $(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/^/ /')
409
+ HOSTNAME: |-
410
+ $(printf %s "$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
411
+ ROOT_URL: |-
412
+ $(printf %s "https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
413
+ HOSTNAME_INTERNAL: |-
414
+ $(printf %s "$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
415
+ ROOT_URL_INTERNAL: |-
416
+ $(printf %s "https://$(printf %s "pan-test-app-dev-db1-$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
417
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
418
+ projectId:region:instancename
419
+ DB_NAME: |-
420
+ pan-test-app-dev-db1
421
+ DB_USER: |-
422
+ my-user
423
+ DB_PASSWORD: |-
424
+ $(printf %s "$CL_dev_db1_DB_PASSWORD" | sed '1!s/^/ /')
425
+ DATABASE_URL: |-
426
+ postgresql://my-user:$CL_dev_db1_DB_PASSWORD@localhost/pan-test-app-dev-db1?host=/cloudsql/projectId:region:instancename
427
+ DATABASE_JDBC_URL: |-
428
+ jdbc:postgresql:///pan-test-app-dev-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db1_DB_PASSWORD
429
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
430
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db1-migrate:run
431
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
432
+ google-project-id
433
+ DEPLOY_CLOUD_RUN_REGION: |-
434
+ europe-west6
435
+ GCLOUD_RUN_canonicalHostSuffix: |-
436
+ $(printf %s "$CL_dev_db1_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
437
+ _ALL_ENV_VAR_KEYS: |-
438
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
439
+
440
+ EOF
441
+ - collapseable_section_end "writeenvvars"
442
+ - collapseable_section_start "deploy" "Deploy to cloud run"
443
+ - set +e
444
+ - echo "ensuring Database..."
445
+ - gcloud sql databases create pan-test-app-dev-db1 --instance=instancename --project projectId
446
+ - set -e
447
+ - |-
448
+ exist_job_names="$(
449
+ gcloud run jobs list --filter='metadata.name ~ dev.*db1' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
450
+ )"
451
+ current_job_name="pan-test-app-dev-db1-migrate"
452
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
453
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
454
+ else
455
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
456
+ fi
457
+ - gcloud run jobs execute pan-test-app-dev-db1-migrate --project=google-project-id --region=europe-west6
458
+ - collapseable_section_end "deploy"
459
+ - collapseable_section_start "cleanup" "Cleanup"
460
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-dev-db1 --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
461
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1 --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/db1@$version --quiet --delete-tags; done
462
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
463
+ - collapseable_section_end "cleanup"
464
+ - echo 'Uploading SBOM to Dependency Track'
465
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db1" "$ROOT_URL" "__sbom.json" vex.json || true
466
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
467
+ environment:
468
+ name: dev/db1
469
+ url: $CL_GITLAB_ENVIRONMENT_URL
470
+ on_stop: 'db1 ๐Ÿ›‘ Stop โš ๏ธ | dev '
471
+ auto_stop_in: 4 weeks
472
+ artifacts:
473
+ reports:
474
+ dotenv: gitlab_environment.env
475
+ rules:
476
+ - when: on_success
477
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
478
+ needs:
479
+ - job: db1 ๐Ÿ‘ฎ lint
480
+ artifacts: false
481
+ - job: 'db1 ๐Ÿ”จ app | dev '
482
+ artifacts: false
483
+ - job: 'db1 ๐Ÿ”จ docker | dev '
484
+ artifacts: false
485
+ - job: db1 ๐Ÿงช test
486
+ artifacts: false
487
+ - job: 'db1 ๐Ÿงพ sbom | dev '
488
+ artifacts: true
489
+ - job: db1 ๐Ÿ›ก audit
490
+ artifacts: false
491
+ retry: *a1
492
+ interruptible: true
493
+ allow_failure: false
494
+ 'db1 ๐Ÿ›‘ Stop โš ๏ธ | dev ':
495
+ stage: stop dev
496
+ image: path/to/docker/gcloud:the-version
497
+ variables:
498
+ KUBERNETES_CPU_REQUEST: '0.22'
499
+ KUBERNETES_MEMORY_REQUEST: 200Mi
500
+ KUBERNETES_MEMORY_LIMIT: 400Mi
501
+ GIT_STRATEGY: none
502
+ script:
503
+ - collapseable_section_start "injectvars" "Injecting variables"
504
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
505
+ - collapseable_section_end "injectvars"
506
+ - set +e
507
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db1_GCLOUD_DEPLOY_credentialsKey")
508
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-dev-db1-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
509
+ - gcloud run jobs delete pan-test-app-dev-db1-migrate --project=google-project-id --region=europe-west6
510
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db1 --quiet --delete-tags
511
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
512
+ - echo 'Disabling component in Dependency Track'
513
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db1" "$CI_ENVIRONMENT_URL" || true
514
+ - set -e
515
+ environment:
516
+ name: dev/db1
517
+ action: stop
518
+ rules:
519
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
520
+ when: on_success
521
+ - when: manual
522
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
523
+ needs: []
524
+ retry: *a1
525
+ interruptible: true
526
+ allow_failure: true
527
+ 'db1 ๐Ÿ”จ app | review ':
528
+ stage: build
529
+ image: path/to/docker/jobs-default:the-version
530
+ variables:
531
+ KUBERNETES_CPU_REQUEST: '0.45'
532
+ KUBERNETES_MEMORY_REQUEST: 1Gi
533
+ KUBERNETES_MEMORY_LIMIT: 4Gi
534
+ script:
535
+ - collapseable_section_start "injectvars" "Injecting variables"
536
+ - export ENV_SHORT="review"
537
+ - export APP_DIR="packages/db1"
538
+ - export ENV_TYPE="review"
539
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
540
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
541
+ - 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")"
542
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
543
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
544
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
545
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
546
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
547
+ - export DB_NAME="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"; })-db1"
548
+ - export DB_USER="my-user"
549
+ - export DB_PASSWORD="$CL_review_db1_DB_PASSWORD"
550
+ - export DATABASE_URL="postgresql://my-user:$CL_review_db1_DB_PASSWORD@localhost/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"; })-db1?host=/cloudsql/projectId:region:instancename"
551
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///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"; })-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db1_DB_PASSWORD"
552
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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\\"; })-db1\\" | awk '{print tolower($0)}')-migrate:run"
553
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
554
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
555
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_db1_GCLOUD_DEPLOY_credentialsKey"
556
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix"
557
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
558
+ - collapseable_section_end "injectvars"
559
+ - collapseable_section_start "write-dotenv-db1" "write dot env for db1"
560
+ - |-
561
+ cat <<EOF > packages/db1/.env
562
+ ENV_SHORT=review
563
+ APP_DIR=packages/db1
564
+ ENV_TYPE=review
565
+ 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
566
+ 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
567
+ 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
568
+ 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
569
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
570
+ DB_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"; })-db1" | escapeForDotEnv)
571
+ DB_USER=my-user
572
+ DB_PASSWORD=$(printf %s "$CL_review_db1_DB_PASSWORD" | escapeForDotEnv)
573
+ DATABASE_URL=$(printf %s "postgresql://my-user:$CL_review_db1_DB_PASSWORD@localhost/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"; })-db1?host=/cloudsql/projectId:region:instancename" | escapeForDotEnv)
574
+ DATABASE_JDBC_URL=$(printf %s "jdbc:postgresql:///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"; })-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db1_DB_PASSWORD" | escapeForDotEnv)
575
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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"; })-db1" | awk '{print tolower($0)}')-migrate:run
576
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
577
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
578
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_db1_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
579
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
580
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
581
+ EOF
582
+ - collapseable_section_end "write-dotenv-db1"
583
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db1/__build_info.json
584
+ - collapseable_section_start "nodeinstall" "Ensure node version"
585
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
586
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
587
+ - collapseable_section_end "nodeinstall"
588
+ - cd packages/db1
589
+ - collapseable_section_start "nodeinstall" "Ensure node version"
590
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
591
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
592
+ - collapseable_section_end "nodeinstall"
593
+ - collapseable_section_start "yarninstall" "Yarn install"
594
+ - yarn install --immutable
595
+ - collapseable_section_end "yarninstall"
596
+ - yarn build
597
+ cache:
598
+ - key: packagesdb1-yarn
599
+ policy: pull-push
600
+ paths:
601
+ - packages/db1/.yarn
602
+ - key: packagesdb1-node-modules
603
+ policy: pull-push
604
+ paths:
605
+ - packages/db1/node_modules
606
+ artifacts:
607
+ paths:
608
+ - packages/db1/__build_info.json
609
+ - packages/db1/.next
610
+ - packages/db1/dist
611
+ exclude:
612
+ - packages/db1/.env
613
+ expire_in: 1 day
614
+ when: always
615
+ reports: {}
616
+ rules:
617
+ - if: $CI_MERGE_REQUEST_ID
618
+ needs: []
619
+ retry: *a1
620
+ interruptible: true
621
+ 'db1 ๐Ÿ”จ docker | review ':
622
+ stage: build
623
+ image: path/to/docker/docker-build:the-version
624
+ services:
625
+ - name: docker:24.0.6-dind
626
+ command:
627
+ - --tls=false
628
+ - --registry-mirror=https://mirror.gcr.io
629
+ variables:
630
+ DOCKER_HOST: tcp://docker:2375
631
+ DOCKER_TLS_CERTDIR: ''
632
+ DOCKER_DRIVER: overlay2
633
+ DOCKER_BUILDKIT: '1'
634
+ KUBERNETES_CPU_REQUEST: '0.45'
635
+ KUBERNETES_MEMORY_REQUEST: 1Gi
636
+ KUBERNETES_MEMORY_LIMIT: 2Gi
637
+ script:
638
+ - collapseable_section_start "injectvars" "Injecting variables"
639
+ - export APP_DIR="packages/db1"
640
+ - export DOCKER_BUILD_CONTEXT="."
641
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
642
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
643
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
644
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
645
+ - |-
646
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
647
+ RUN yarn plugin import workspace-tools
648
+ RUN yarn workspaces focus --production && yarn rebuild"
649
+ - |-
650
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db1/package.json /app/packages/db1/package.json
651
+ COPY --chown=node:node packages/db1/yarn.lock /app/packages/db1/yarn.lock
652
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
653
+ COPY --chown=node:node .yarn /app/.yarn"
654
+ - collapseable_section_end "injectvars"
655
+ - ensureNodeDockerfile
656
+ - collapseable_section_start "docker-login" "Docker Login"
657
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db1_GCLOUD_DEPLOY_credentialsKey")
658
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
659
+ - collapseable_section_end "docker-login"
660
+ - collapseable_section_start "docker-build" "Docker build"
661
+ - 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
662
+ - collapseable_section_end "docker-build"
663
+ - collapseable_section_start "docker-push" "Docker push and tag"
664
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
665
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
666
+ - docker push $DOCKER_CACHE_IMAGE
667
+ - collapseable_section_end "docker-push"
668
+ cache:
669
+ - key: packagesdb1-yarn
670
+ policy: pull
671
+ paths:
672
+ - packages/db1/.yarn
673
+ rules:
674
+ - if: $CI_MERGE_REQUEST_ID
675
+ needs:
676
+ - 'db1 ๐Ÿ”จ app | review '
677
+ retry: *a1
678
+ interruptible: true
679
+ 'db1 ๐Ÿงพ sbom | review ':
680
+ stage: build
681
+ image:
682
+ name: aquasec/trivy:0.58.2
683
+ entrypoint:
684
+ - ''
685
+ variables: {}
686
+ script:
687
+ - collapseable_section_start "injectvars" "Injecting variables"
688
+ - collapseable_section_end "injectvars"
689
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db1
690
+ artifacts:
691
+ paths:
692
+ - __sbom.json
693
+ rules:
694
+ - if: $CI_MERGE_REQUEST_ID
695
+ needs: []
696
+ retry: *a1
697
+ interruptible: true
698
+ allow_failure: true
699
+ 'db1 ๐Ÿš€ Deploy | review ':
700
+ stage: deploy review
701
+ image: path/to/docker/gcloud:the-version
702
+ variables:
703
+ KUBERNETES_CPU_REQUEST: '0.22'
704
+ KUBERNETES_MEMORY_REQUEST: 200Mi
705
+ KUBERNETES_MEMORY_LIMIT: 400Mi
706
+ script:
707
+ - collapseable_section_start "injectvars" "Injecting variables"
708
+ - export ENV_SHORT="review"
709
+ - export APP_DIR="packages/db1"
710
+ - export ENV_TYPE="review"
711
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
712
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
713
+ - 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")"
714
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
715
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
716
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
717
+ - 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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
718
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
719
+ - export DB_NAME="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"; })-db1"
720
+ - export DB_USER="my-user"
721
+ - export DB_PASSWORD="$CL_review_db1_DB_PASSWORD"
722
+ - export DATABASE_URL="postgresql://my-user:$CL_review_db1_DB_PASSWORD@localhost/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"; })-db1?host=/cloudsql/projectId:region:instancename"
723
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///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"; })-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db1_DB_PASSWORD"
724
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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\\"; })-db1\\" | awk '{print tolower($0)}')-migrate:run"
725
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
726
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
727
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_db1_GCLOUD_DEPLOY_credentialsKey"
728
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix"
729
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
730
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
731
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
732
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
733
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
734
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
735
+ - collapseable_section_end "injectvars"
736
+ - collapseable_section_start "prepare" "Prepare..."
737
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db1_GCLOUD_DEPLOY_credentialsKey")
738
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
739
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
740
+ - collapseable_section_end "prepare"
741
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
742
+ - |
743
+ cat > ____envvars.yaml <<EOF
744
+ ENV_SHORT: |-
745
+ review
746
+ APP_DIR: |-
747
+ packages/db1
748
+ ENV_TYPE: |-
749
+ review
750
+ BUILD_INFO_BUILD_ID: |-
751
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
752
+ BUILD_INFO_BUILD_TIME: |-
753
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
754
+ BUILD_INFO_CURRENT_VERSION: |-
755
+ $(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/^/ /')
756
+ HOSTNAME: |-
757
+ $(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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
758
+ ROOT_URL: |-
759
+ $(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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
760
+ HOSTNAME_INTERNAL: |-
761
+ $(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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
762
+ ROOT_URL_INTERNAL: |-
763
+ $(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"; })-db1-$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
764
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
765
+ projectId:region:instancename
766
+ DB_NAME: |-
767
+ $(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"; })-db1" | sed '1!s/^/ /')
768
+ DB_USER: |-
769
+ my-user
770
+ DB_PASSWORD: |-
771
+ $(printf %s "$CL_review_db1_DB_PASSWORD" | sed '1!s/^/ /')
772
+ DATABASE_URL: |-
773
+ $(printf %s "postgresql://my-user:$CL_review_db1_DB_PASSWORD@localhost/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"; })-db1?host=/cloudsql/projectId:region:instancename" | sed '1!s/^/ /')
774
+ DATABASE_JDBC_URL: |-
775
+ $(printf %s "jdbc:postgresql:///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"; })-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db1_DB_PASSWORD" | sed '1!s/^/ /')
776
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
777
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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"; })-db1" | awk '{print tolower($0)}')-migrate:run
778
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
779
+ google-project-id
780
+ DEPLOY_CLOUD_RUN_REGION: |-
781
+ europe-west6
782
+ GCLOUD_RUN_canonicalHostSuffix: |-
783
+ $(printf %s "$CL_review_db1_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
784
+ _ALL_ENV_VAR_KEYS: |-
785
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
786
+
787
+ EOF
788
+ - collapseable_section_end "writeenvvars"
789
+ - collapseable_section_start "deploy" "Deploy to cloud run"
790
+ - set +e
791
+ - echo "ensuring Database..."
792
+ - gcloud sql databases create 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"; })-db1 --instance=instancename --project projectId
793
+ - set -e
794
+ - |-
795
+ exist_job_names="$(
796
+ gcloud run jobs list --filter='metadata.name ~ review.*db1' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
797
+ )"
798
+ current_job_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"; })-db1" | awk '{print tolower($0)}')-migrate"
799
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
800
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
801
+ else
802
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
803
+ fi
804
+ - gcloud run jobs execute $(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"; })-db1" | awk '{print tolower($0)}')-migrate --project=google-project-id --region=europe-west6
805
+ - collapseable_section_end "deploy"
806
+ - collapseable_section_start "cleanup" "Cleanup"
807
+ - 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"; })-db1" | 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
808
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -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/db1/$([ -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
809
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
810
+ - set +e
811
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1 --quiet --delete-tags
812
+ - set -e
813
+ - collapseable_section_end "cleanup"
814
+ - echo 'Uploading SBOM to Dependency Track'
815
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db1" "$ROOT_URL" "__sbom.json" vex.json || true
816
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
817
+ environment:
818
+ name: review/$CI_COMMIT_REF_NAME/db1
819
+ url: $CL_GITLAB_ENVIRONMENT_URL
820
+ on_stop: 'db1 ๐Ÿ›‘ Stop โš ๏ธ | review '
821
+ auto_stop_in: 1 week
822
+ artifacts:
823
+ reports:
824
+ dotenv: gitlab_environment.env
825
+ rules:
826
+ - when: on_success
827
+ if: $CI_MERGE_REQUEST_ID
828
+ needs:
829
+ - job: db1 ๐Ÿ‘ฎ lint
830
+ artifacts: false
831
+ - job: 'db1 ๐Ÿ”จ app | review '
832
+ artifacts: false
833
+ - job: 'db1 ๐Ÿ”จ docker | review '
834
+ artifacts: false
835
+ - job: db1 ๐Ÿงช test
836
+ artifacts: false
837
+ - job: 'db1 ๐Ÿงพ sbom | review '
838
+ artifacts: true
839
+ - job: db1 ๐Ÿ›ก audit
840
+ artifacts: false
841
+ retry: *a1
842
+ interruptible: true
843
+ allow_failure: false
844
+ 'db1 ๐Ÿ›‘ Stop โš ๏ธ | review ':
845
+ stage: stop review
846
+ image: path/to/docker/gcloud:the-version
847
+ variables:
848
+ KUBERNETES_CPU_REQUEST: '0.22'
849
+ KUBERNETES_MEMORY_REQUEST: 200Mi
850
+ KUBERNETES_MEMORY_LIMIT: 400Mi
851
+ GIT_STRATEGY: none
852
+ script:
853
+ - collapseable_section_start "injectvars" "Injecting variables"
854
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
855
+ - collapseable_section_end "injectvars"
856
+ - set +e
857
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db1_GCLOUD_DEPLOY_credentialsKey")
858
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job $(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"; })-db1" | awk '{print tolower($0)}')-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
859
+ - gcloud run jobs 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"; })-db1" | awk '{print tolower($0)}')-migrate --project=google-project-id --region=europe-west6
860
+ - echo "deleting database 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"; })-db1..."
861
+ - echo "๐Ÿ‘† this can take multiple attemps (3-5min), because google cloud run may still have a connection to the database after the cloud run service is shut down"
862
+ - "\\n until gcloud sql databases delete 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\\"; })-db1 --instance=instancename --project projectId\\n do\\n echo \\"Trying again.\\"\\n sleep 10\\n done\\n "
863
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1/$([ -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
864
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
865
+ - set +e
866
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db1 --quiet --delete-tags
867
+ - set -e
868
+ - echo 'Disabling component in Dependency Track'
869
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db1" "$CI_ENVIRONMENT_URL" || true
870
+ - set -e
871
+ environment:
872
+ name: review/$CI_COMMIT_REF_NAME/db1
873
+ action: stop
874
+ rules:
875
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
876
+ when: on_success
877
+ - when: manual
878
+ if: $CI_MERGE_REQUEST_ID
879
+ needs: []
880
+ retry: *a1
881
+ interruptible: true
882
+ allow_failure: true
883
+ 'db1 ๐Ÿ”จ app | stage ':
884
+ stage: build
885
+ image: path/to/docker/jobs-default:the-version
886
+ variables:
887
+ KUBERNETES_CPU_REQUEST: '0.45'
888
+ KUBERNETES_MEMORY_REQUEST: 1Gi
889
+ KUBERNETES_MEMORY_LIMIT: 4Gi
890
+ script:
891
+ - collapseable_section_start "injectvars" "Injecting variables"
892
+ - export ENV_SHORT="stage"
893
+ - export APP_DIR="packages/db1"
894
+ - export ENV_TYPE="stage"
895
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
896
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
897
+ - 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")"
898
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
899
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
900
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
901
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
902
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
903
+ - export DB_NAME="pan-test-app-stage-db1"
904
+ - export DB_USER="my-user"
905
+ - export DB_PASSWORD="$CL_stage_db1_DB_PASSWORD"
906
+ - export DATABASE_URL="postgresql://my-user:$CL_stage_db1_DB_PASSWORD@localhost/pan-test-app-stage-db1?host=/cloudsql/projectId:region:instancename"
907
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-stage-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db1_DB_PASSWORD"
908
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db1-migrate:run"
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_db1_GCLOUD_DEPLOY_credentialsKey"
912
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_db1_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\\",\\"HOSTNAME\\",\\"ROOT_URL\\",\\"HOSTNAME_INTERNAL\\",\\"ROOT_URL_INTERNAL\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
914
+ - collapseable_section_end "injectvars"
915
+ - collapseable_section_start "write-dotenv-db1" "write dot env for db1"
916
+ - |-
917
+ cat <<EOF > packages/db1/.env
918
+ ENV_SHORT=stage
919
+ APP_DIR=packages/db1
920
+ ENV_TYPE=stage
921
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
922
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
923
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
924
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
925
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
926
+ DB_NAME=pan-test-app-stage-db1
927
+ DB_USER=my-user
928
+ DB_PASSWORD=$(printf %s "$CL_stage_db1_DB_PASSWORD" | escapeForDotEnv)
929
+ DATABASE_URL=postgresql://my-user:$CL_stage_db1_DB_PASSWORD@localhost/pan-test-app-stage-db1?host=/cloudsql/projectId:region:instancename
930
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-stage-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db1_DB_PASSWORD
931
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db1-migrate:run
932
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
933
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
934
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_db1_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
935
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
936
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
937
+ EOF
938
+ - collapseable_section_end "write-dotenv-db1"
939
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db1/__build_info.json
940
+ - collapseable_section_start "nodeinstall" "Ensure node version"
941
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
942
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
943
+ - collapseable_section_end "nodeinstall"
944
+ - cd packages/db1
945
+ - collapseable_section_start "nodeinstall" "Ensure node version"
946
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
947
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
948
+ - collapseable_section_end "nodeinstall"
949
+ - collapseable_section_start "yarninstall" "Yarn install"
950
+ - yarn install --immutable
951
+ - collapseable_section_end "yarninstall"
952
+ - yarn build
953
+ cache:
954
+ - key: packagesdb1-yarn
955
+ policy: pull-push
956
+ paths:
957
+ - packages/db1/.yarn
958
+ - key: packagesdb1-node-modules
959
+ policy: pull-push
960
+ paths:
961
+ - packages/db1/node_modules
962
+ artifacts:
963
+ paths:
964
+ - packages/db1/__build_info.json
965
+ - packages/db1/.next
966
+ - packages/db1/dist
967
+ exclude:
968
+ - packages/db1/.env
969
+ expire_in: 1 day
970
+ when: always
971
+ reports: {}
972
+ rules:
973
+ - if: $CI_COMMIT_TAG
974
+ needs: []
975
+ retry: *a1
976
+ interruptible: true
977
+ 'db1 ๐Ÿ”จ docker | stage ':
978
+ stage: build
979
+ image: path/to/docker/docker-build:the-version
980
+ services:
981
+ - name: docker:24.0.6-dind
982
+ command:
983
+ - --tls=false
984
+ - --registry-mirror=https://mirror.gcr.io
985
+ variables:
986
+ DOCKER_HOST: tcp://docker:2375
987
+ DOCKER_TLS_CERTDIR: ''
988
+ DOCKER_DRIVER: overlay2
989
+ DOCKER_BUILDKIT: '1'
990
+ KUBERNETES_CPU_REQUEST: '0.45'
991
+ KUBERNETES_MEMORY_REQUEST: 1Gi
992
+ KUBERNETES_MEMORY_LIMIT: 2Gi
993
+ script:
994
+ - collapseable_section_start "injectvars" "Injecting variables"
995
+ - export APP_DIR="packages/db1"
996
+ - export DOCKER_BUILD_CONTEXT="."
997
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
998
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1"
999
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
1000
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1001
+ - |-
1002
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1003
+ RUN yarn plugin import workspace-tools
1004
+ RUN yarn workspaces focus --production && yarn rebuild"
1005
+ - |-
1006
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db1/package.json /app/packages/db1/package.json
1007
+ COPY --chown=node:node packages/db1/yarn.lock /app/packages/db1/yarn.lock
1008
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1009
+ COPY --chown=node:node .yarn /app/.yarn"
1010
+ - collapseable_section_end "injectvars"
1011
+ - ensureNodeDockerfile
1012
+ - collapseable_section_start "docker-login" "Docker Login"
1013
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db1_GCLOUD_DEPLOY_credentialsKey")
1014
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1015
+ - collapseable_section_end "docker-login"
1016
+ - collapseable_section_start "docker-build" "Docker build"
1017
+ - 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
1018
+ - collapseable_section_end "docker-build"
1019
+ - collapseable_section_start "docker-push" "Docker push and tag"
1020
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1021
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1022
+ - docker push $DOCKER_CACHE_IMAGE
1023
+ - collapseable_section_end "docker-push"
1024
+ cache:
1025
+ - key: packagesdb1-yarn
1026
+ policy: pull
1027
+ paths:
1028
+ - packages/db1/.yarn
1029
+ rules:
1030
+ - if: $CI_COMMIT_TAG
1031
+ needs:
1032
+ - 'db1 ๐Ÿ”จ app | stage '
1033
+ retry: *a1
1034
+ interruptible: true
1035
+ 'db1 ๐Ÿงพ sbom | stage ':
1036
+ stage: build
1037
+ image:
1038
+ name: aquasec/trivy:0.58.2
1039
+ entrypoint:
1040
+ - ''
1041
+ variables: {}
1042
+ script:
1043
+ - collapseable_section_start "injectvars" "Injecting variables"
1044
+ - collapseable_section_end "injectvars"
1045
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db1
1046
+ artifacts:
1047
+ paths:
1048
+ - __sbom.json
1049
+ rules:
1050
+ - if: $CI_COMMIT_TAG
1051
+ needs: []
1052
+ retry: *a1
1053
+ interruptible: true
1054
+ allow_failure: true
1055
+ 'db1 ๐Ÿš€ Deploy | stage ':
1056
+ stage: deploy stage
1057
+ image: path/to/docker/gcloud:the-version
1058
+ variables:
1059
+ KUBERNETES_CPU_REQUEST: '0.22'
1060
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1061
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1062
+ script:
1063
+ - collapseable_section_start "injectvars" "Injecting variables"
1064
+ - export ENV_SHORT="stage"
1065
+ - export APP_DIR="packages/db1"
1066
+ - export ENV_TYPE="stage"
1067
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1068
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1069
+ - 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")"
1070
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1071
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1072
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1073
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1074
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1075
+ - export DB_NAME="pan-test-app-stage-db1"
1076
+ - export DB_USER="my-user"
1077
+ - export DB_PASSWORD="$CL_stage_db1_DB_PASSWORD"
1078
+ - export DATABASE_URL="postgresql://my-user:$CL_stage_db1_DB_PASSWORD@localhost/pan-test-app-stage-db1?host=/cloudsql/projectId:region:instancename"
1079
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-stage-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db1_DB_PASSWORD"
1080
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db1-migrate:run"
1081
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1082
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1083
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_db1_GCLOUD_DEPLOY_credentialsKey"
1084
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix"
1085
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1086
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1087
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1"
1088
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
1089
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1090
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1091
+ - collapseable_section_end "injectvars"
1092
+ - collapseable_section_start "prepare" "Prepare..."
1093
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db1_GCLOUD_DEPLOY_credentialsKey")
1094
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1095
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1096
+ - collapseable_section_end "prepare"
1097
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1098
+ - |
1099
+ cat > ____envvars.yaml <<EOF
1100
+ ENV_SHORT: |-
1101
+ stage
1102
+ APP_DIR: |-
1103
+ packages/db1
1104
+ ENV_TYPE: |-
1105
+ stage
1106
+ BUILD_INFO_BUILD_ID: |-
1107
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1108
+ BUILD_INFO_BUILD_TIME: |-
1109
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1110
+ BUILD_INFO_CURRENT_VERSION: |-
1111
+ $(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/^/ /')
1112
+ HOSTNAME: |-
1113
+ $(printf %s "$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1114
+ ROOT_URL: |-
1115
+ $(printf %s "https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1116
+ HOSTNAME_INTERNAL: |-
1117
+ $(printf %s "$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1118
+ ROOT_URL_INTERNAL: |-
1119
+ $(printf %s "https://$(printf %s "pan-test-app-stage-db1-$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1120
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1121
+ projectId:region:instancename
1122
+ DB_NAME: |-
1123
+ pan-test-app-stage-db1
1124
+ DB_USER: |-
1125
+ my-user
1126
+ DB_PASSWORD: |-
1127
+ $(printf %s "$CL_stage_db1_DB_PASSWORD" | sed '1!s/^/ /')
1128
+ DATABASE_URL: |-
1129
+ postgresql://my-user:$CL_stage_db1_DB_PASSWORD@localhost/pan-test-app-stage-db1?host=/cloudsql/projectId:region:instancename
1130
+ DATABASE_JDBC_URL: |-
1131
+ jdbc:postgresql:///pan-test-app-stage-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db1_DB_PASSWORD
1132
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
1133
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db1-migrate:run
1134
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1135
+ google-project-id
1136
+ DEPLOY_CLOUD_RUN_REGION: |-
1137
+ europe-west6
1138
+ GCLOUD_RUN_canonicalHostSuffix: |-
1139
+ $(printf %s "$CL_stage_db1_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1140
+ _ALL_ENV_VAR_KEYS: |-
1141
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1142
+
1143
+ EOF
1144
+ - collapseable_section_end "writeenvvars"
1145
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1146
+ - set +e
1147
+ - echo "ensuring Database..."
1148
+ - gcloud sql databases create pan-test-app-stage-db1 --instance=instancename --project projectId
1149
+ - set -e
1150
+ - |-
1151
+ exist_job_names="$(
1152
+ gcloud run jobs list --filter='metadata.name ~ stage.*db1' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
1153
+ )"
1154
+ current_job_name="pan-test-app-stage-db1-migrate"
1155
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1156
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1157
+ else
1158
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1159
+ fi
1160
+ - gcloud run jobs execute pan-test-app-stage-db1-migrate --project=google-project-id --region=europe-west6
1161
+ - collapseable_section_end "deploy"
1162
+ - collapseable_section_start "cleanup" "Cleanup"
1163
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-stage-db1 --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
1164
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1 --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/db1@$version --quiet --delete-tags; done
1165
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
1166
+ - collapseable_section_end "cleanup"
1167
+ - echo 'Uploading SBOM to Dependency Track'
1168
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db1" "$ROOT_URL" "__sbom.json" vex.json || true
1169
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1170
+ environment:
1171
+ name: stage/db1
1172
+ url: $CL_GITLAB_ENVIRONMENT_URL
1173
+ on_stop: 'db1 ๐Ÿ›‘ Stop โš ๏ธ | stage '
1174
+ artifacts:
1175
+ reports:
1176
+ dotenv: gitlab_environment.env
1177
+ rules:
1178
+ - when: on_success
1179
+ if: $CI_COMMIT_TAG
1180
+ needs:
1181
+ - job: 'db1 ๐Ÿ”จ app | stage '
1182
+ artifacts: false
1183
+ - job: 'db1 ๐Ÿ”จ docker | stage '
1184
+ artifacts: false
1185
+ - job: 'db1 ๐Ÿงพ sbom | stage '
1186
+ artifacts: true
1187
+ retry: *a1
1188
+ interruptible: true
1189
+ allow_failure: false
1190
+ 'db1 ๐Ÿ›‘ Stop โš ๏ธ | stage ':
1191
+ stage: stop stage
1192
+ image: path/to/docker/gcloud:the-version
1193
+ variables:
1194
+ KUBERNETES_CPU_REQUEST: '0.22'
1195
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1196
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1197
+ GIT_STRATEGY: none
1198
+ script:
1199
+ - collapseable_section_start "injectvars" "Injecting variables"
1200
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1201
+ - collapseable_section_end "injectvars"
1202
+ - set +e
1203
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db1_GCLOUD_DEPLOY_credentialsKey")
1204
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-stage-db1-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1205
+ - gcloud run jobs delete pan-test-app-stage-db1-migrate --project=google-project-id --region=europe-west6
1206
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db1 --quiet --delete-tags
1207
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
1208
+ - echo 'Disabling component in Dependency Track'
1209
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db1" "$CI_ENVIRONMENT_URL" || true
1210
+ - set -e
1211
+ environment:
1212
+ name: stage/db1
1213
+ action: stop
1214
+ rules:
1215
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1216
+ when: on_success
1217
+ - when: manual
1218
+ if: $CI_COMMIT_TAG
1219
+ needs: []
1220
+ retry: *a1
1221
+ interruptible: true
1222
+ allow_failure: true
1223
+ 'db1 ๐Ÿ”จ app | prod ':
1224
+ stage: build
1225
+ image: path/to/docker/jobs-default:the-version
1226
+ variables:
1227
+ KUBERNETES_CPU_REQUEST: '0.45'
1228
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1229
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1230
+ script:
1231
+ - collapseable_section_start "injectvars" "Injecting variables"
1232
+ - export ENV_SHORT="prod"
1233
+ - export APP_DIR="packages/db1"
1234
+ - export ENV_TYPE="prod"
1235
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1236
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1237
+ - 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")"
1238
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1239
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1240
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1241
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1242
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1243
+ - export DB_NAME="pan-test-app-prod-db1"
1244
+ - export DB_USER="my-user"
1245
+ - export DB_PASSWORD="$CL_prod_db1_DB_PASSWORD"
1246
+ - export DATABASE_URL="postgresql://my-user:$CL_prod_db1_DB_PASSWORD@localhost/pan-test-app-prod-db1?host=/cloudsql/projectId:region:instancename"
1247
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-prod-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db1_DB_PASSWORD"
1248
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db1-migrate:run"
1249
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1250
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1251
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey"
1252
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix"
1253
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1254
+ - collapseable_section_end "injectvars"
1255
+ - collapseable_section_start "write-dotenv-db1" "write dot env for db1"
1256
+ - |-
1257
+ cat <<EOF > packages/db1/.env
1258
+ ENV_SHORT=prod
1259
+ APP_DIR=packages/db1
1260
+ ENV_TYPE=prod
1261
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1262
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1263
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1264
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1265
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
1266
+ DB_NAME=pan-test-app-prod-db1
1267
+ DB_USER=my-user
1268
+ DB_PASSWORD=$(printf %s "$CL_prod_db1_DB_PASSWORD" | escapeForDotEnv)
1269
+ DATABASE_URL=postgresql://my-user:$CL_prod_db1_DB_PASSWORD@localhost/pan-test-app-prod-db1?host=/cloudsql/projectId:region:instancename
1270
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-prod-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db1_DB_PASSWORD
1271
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db1-migrate:run
1272
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
1273
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
1274
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
1275
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
1276
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1277
+ EOF
1278
+ - collapseable_section_end "write-dotenv-db1"
1279
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db1/__build_info.json
1280
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1281
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1282
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1283
+ - collapseable_section_end "nodeinstall"
1284
+ - cd packages/db1
1285
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1286
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1287
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1288
+ - collapseable_section_end "nodeinstall"
1289
+ - collapseable_section_start "yarninstall" "Yarn install"
1290
+ - yarn install --immutable
1291
+ - collapseable_section_end "yarninstall"
1292
+ - yarn build
1293
+ cache:
1294
+ - key: packagesdb1-yarn
1295
+ policy: pull-push
1296
+ paths:
1297
+ - packages/db1/.yarn
1298
+ - key: packagesdb1-node-modules
1299
+ policy: pull-push
1300
+ paths:
1301
+ - packages/db1/node_modules
1302
+ artifacts:
1303
+ paths:
1304
+ - packages/db1/__build_info.json
1305
+ - packages/db1/.next
1306
+ - packages/db1/dist
1307
+ exclude:
1308
+ - packages/db1/.env
1309
+ expire_in: 1 day
1310
+ when: always
1311
+ reports: {}
1312
+ rules:
1313
+ - if: $CI_COMMIT_TAG
1314
+ needs: []
1315
+ retry: *a1
1316
+ interruptible: true
1317
+ 'db1 ๐Ÿ”จ docker | prod ':
1318
+ stage: build
1319
+ image: path/to/docker/docker-build:the-version
1320
+ services:
1321
+ - name: docker:24.0.6-dind
1322
+ command:
1323
+ - --tls=false
1324
+ - --registry-mirror=https://mirror.gcr.io
1325
+ variables:
1326
+ DOCKER_HOST: tcp://docker:2375
1327
+ DOCKER_TLS_CERTDIR: ''
1328
+ DOCKER_DRIVER: overlay2
1329
+ DOCKER_BUILDKIT: '1'
1330
+ KUBERNETES_CPU_REQUEST: '0.45'
1331
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1332
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1333
+ script:
1334
+ - collapseable_section_start "injectvars" "Injecting variables"
1335
+ - export APP_DIR="packages/db1"
1336
+ - export DOCKER_BUILD_CONTEXT="."
1337
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1338
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1"
1339
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
1340
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1341
+ - |-
1342
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1343
+ RUN yarn plugin import workspace-tools
1344
+ RUN yarn workspaces focus --production && yarn rebuild"
1345
+ - |-
1346
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db1/package.json /app/packages/db1/package.json
1347
+ COPY --chown=node:node packages/db1/yarn.lock /app/packages/db1/yarn.lock
1348
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1349
+ COPY --chown=node:node .yarn /app/.yarn"
1350
+ - collapseable_section_end "injectvars"
1351
+ - ensureNodeDockerfile
1352
+ - collapseable_section_start "docker-login" "Docker Login"
1353
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey")
1354
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1355
+ - collapseable_section_end "docker-login"
1356
+ - collapseable_section_start "docker-build" "Docker build"
1357
+ - 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
1358
+ - collapseable_section_end "docker-build"
1359
+ - collapseable_section_start "docker-push" "Docker push and tag"
1360
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1361
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1362
+ - docker push $DOCKER_CACHE_IMAGE
1363
+ - collapseable_section_end "docker-push"
1364
+ cache:
1365
+ - key: packagesdb1-yarn
1366
+ policy: pull
1367
+ paths:
1368
+ - packages/db1/.yarn
1369
+ rules:
1370
+ - if: $CI_COMMIT_TAG
1371
+ needs:
1372
+ - 'db1 ๐Ÿ”จ app | prod '
1373
+ retry: *a1
1374
+ interruptible: true
1375
+ 'db1 ๐Ÿงพ sbom | prod ':
1376
+ stage: build
1377
+ image:
1378
+ name: aquasec/trivy:0.58.2
1379
+ entrypoint:
1380
+ - ''
1381
+ variables: {}
1382
+ script:
1383
+ - collapseable_section_start "injectvars" "Injecting variables"
1384
+ - collapseable_section_end "injectvars"
1385
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db1
1386
+ artifacts:
1387
+ paths:
1388
+ - __sbom.json
1389
+ rules:
1390
+ - if: $CI_COMMIT_TAG
1391
+ needs: []
1392
+ retry: *a1
1393
+ interruptible: true
1394
+ allow_failure: true
1395
+ 'db1 ๐Ÿš€ Deploy | prod ':
1396
+ stage: deploy prod
1397
+ image: path/to/docker/gcloud:the-version
1398
+ variables:
1399
+ KUBERNETES_CPU_REQUEST: '0.22'
1400
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1401
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1402
+ script:
1403
+ - collapseable_section_start "injectvars" "Injecting variables"
1404
+ - export ENV_SHORT="prod"
1405
+ - export APP_DIR="packages/db1"
1406
+ - export ENV_TYPE="prod"
1407
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1408
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1409
+ - 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")"
1410
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1411
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1412
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1413
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1414
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1415
+ - export DB_NAME="pan-test-app-prod-db1"
1416
+ - export DB_USER="my-user"
1417
+ - export DB_PASSWORD="$CL_prod_db1_DB_PASSWORD"
1418
+ - export DATABASE_URL="postgresql://my-user:$CL_prod_db1_DB_PASSWORD@localhost/pan-test-app-prod-db1?host=/cloudsql/projectId:region:instancename"
1419
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-prod-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db1_DB_PASSWORD"
1420
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db1-migrate:run"
1421
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1422
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1423
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey"
1424
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix"
1425
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1426
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1427
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1"
1428
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1"
1429
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1430
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1431
+ - collapseable_section_end "injectvars"
1432
+ - collapseable_section_start "prepare" "Prepare..."
1433
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey")
1434
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1435
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1436
+ - collapseable_section_end "prepare"
1437
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1438
+ - |
1439
+ cat > ____envvars.yaml <<EOF
1440
+ ENV_SHORT: |-
1441
+ prod
1442
+ APP_DIR: |-
1443
+ packages/db1
1444
+ ENV_TYPE: |-
1445
+ prod
1446
+ BUILD_INFO_BUILD_ID: |-
1447
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1448
+ BUILD_INFO_BUILD_TIME: |-
1449
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1450
+ BUILD_INFO_CURRENT_VERSION: |-
1451
+ $(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/^/ /')
1452
+ HOSTNAME: |-
1453
+ $(printf %s "$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1454
+ ROOT_URL: |-
1455
+ $(printf %s "https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1456
+ HOSTNAME_INTERNAL: |-
1457
+ $(printf %s "$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1458
+ ROOT_URL_INTERNAL: |-
1459
+ $(printf %s "https://$(printf %s "pan-test-app-prod-db1-$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1460
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1461
+ projectId:region:instancename
1462
+ DB_NAME: |-
1463
+ pan-test-app-prod-db1
1464
+ DB_USER: |-
1465
+ my-user
1466
+ DB_PASSWORD: |-
1467
+ $(printf %s "$CL_prod_db1_DB_PASSWORD" | sed '1!s/^/ /')
1468
+ DATABASE_URL: |-
1469
+ postgresql://my-user:$CL_prod_db1_DB_PASSWORD@localhost/pan-test-app-prod-db1?host=/cloudsql/projectId:region:instancename
1470
+ DATABASE_JDBC_URL: |-
1471
+ jdbc:postgresql:///pan-test-app-prod-db1?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db1_DB_PASSWORD
1472
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
1473
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db1-migrate:run
1474
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1475
+ google-project-id
1476
+ DEPLOY_CLOUD_RUN_REGION: |-
1477
+ europe-west6
1478
+ GCLOUD_RUN_canonicalHostSuffix: |-
1479
+ $(printf %s "$CL_prod_db1_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1480
+ _ALL_ENV_VAR_KEYS: |-
1481
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1482
+
1483
+ EOF
1484
+ - collapseable_section_end "writeenvvars"
1485
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1486
+ - set +e
1487
+ - echo "ensuring Database..."
1488
+ - gcloud sql databases create pan-test-app-prod-db1 --instance=instancename --project projectId
1489
+ - set -e
1490
+ - |-
1491
+ exist_job_names="$(
1492
+ gcloud run jobs list --filter='metadata.name ~ prod.*db1' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
1493
+ )"
1494
+ current_job_name="pan-test-app-prod-db1-migrate"
1495
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1496
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1497
+ else
1498
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db1,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1499
+ fi
1500
+ - gcloud run jobs execute pan-test-app-prod-db1-migrate --project=google-project-id --region=europe-west6
1501
+ - collapseable_section_end "deploy"
1502
+ - collapseable_section_start "cleanup" "Cleanup"
1503
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-prod-db1 --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
1504
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1 --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/db1@$version --quiet --delete-tags; done
1505
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
1506
+ - collapseable_section_end "cleanup"
1507
+ - echo 'Uploading SBOM to Dependency Track'
1508
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db1" "$ROOT_URL" "__sbom.json" vex.json || true
1509
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1510
+ environment:
1511
+ name: prod/db1
1512
+ url: $CL_GITLAB_ENVIRONMENT_URL
1513
+ on_stop: 'db1 ๐Ÿ›‘ Stop โš ๏ธ | prod '
1514
+ artifacts:
1515
+ reports:
1516
+ dotenv: gitlab_environment.env
1517
+ rules:
1518
+ - when: manual
1519
+ if: $CI_COMMIT_TAG
1520
+ needs:
1521
+ - job: 'db1 ๐Ÿ”จ app | prod '
1522
+ artifacts: false
1523
+ - job: 'db1 ๐Ÿ”จ docker | prod '
1524
+ artifacts: false
1525
+ - job: 'db1 ๐Ÿงพ sbom | prod '
1526
+ artifacts: true
1527
+ retry: *a1
1528
+ interruptible: true
1529
+ allow_failure: true
1530
+ 'db1 ๐Ÿ›‘ Stop โš ๏ธ | prod ':
1531
+ stage: stop prod
1532
+ image: path/to/docker/gcloud:the-version
1533
+ variables:
1534
+ KUBERNETES_CPU_REQUEST: '0.22'
1535
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1536
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1537
+ GIT_STRATEGY: none
1538
+ script:
1539
+ - collapseable_section_start "injectvars" "Injecting variables"
1540
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1541
+ - collapseable_section_end "injectvars"
1542
+ - set +e
1543
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db1_GCLOUD_DEPLOY_credentialsKey")
1544
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-prod-db1-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1545
+ - gcloud run jobs delete pan-test-app-prod-db1-migrate --project=google-project-id --region=europe-west6
1546
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db1 --quiet --delete-tags
1547
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db1 --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/db1@$version --quiet --delete-tags; done
1548
+ - echo 'Disabling component in Dependency Track'
1549
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db1" "$CI_ENVIRONMENT_URL" || true
1550
+ - set -e
1551
+ environment:
1552
+ name: prod/db1
1553
+ action: stop
1554
+ rules:
1555
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1556
+ when: on_success
1557
+ - when: manual
1558
+ if: $CI_COMMIT_TAG
1559
+ needs: []
1560
+ retry: *a1
1561
+ interruptible: true
1562
+ allow_failure: true
1563
+ db2 ๐Ÿ›ก audit:
1564
+ stage: test
1565
+ image: path/to/docker/jobs-default:the-version
1566
+ variables:
1567
+ KUBERNETES_CPU_REQUEST: '0.45'
1568
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1569
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1570
+ script:
1571
+ - collapseable_section_start "injectvars" "Injecting variables"
1572
+ - export APP_PATH="packages/db2"
1573
+ - collapseable_section_end "injectvars"
1574
+ - cd packages/db2
1575
+ - yarn npm audit --environment production
1576
+ rules:
1577
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1578
+ - if: $CI_MERGE_REQUEST_ID
1579
+ needs: []
1580
+ retry: *a1
1581
+ interruptible: true
1582
+ allow_failure: true
1583
+ db2 ๐Ÿ‘ฎ lint:
1584
+ stage: test
1585
+ image: path/to/docker/jobs-default:the-version
1586
+ variables:
1587
+ KUBERNETES_CPU_REQUEST: '0.45'
1588
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1589
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1590
+ script:
1591
+ - collapseable_section_start "injectvars" "Injecting variables"
1592
+ - export APP_PATH="packages/db2"
1593
+ - collapseable_section_end "injectvars"
1594
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1595
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1596
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1597
+ - collapseable_section_end "nodeinstall"
1598
+ - cd packages/db2
1599
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1600
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1601
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1602
+ - collapseable_section_end "nodeinstall"
1603
+ - collapseable_section_start "yarninstall" "Yarn install"
1604
+ - yarn install --immutable
1605
+ - collapseable_section_end "yarninstall"
1606
+ - yarn lint
1607
+ cache:
1608
+ - key: packagesdb2-yarn
1609
+ policy: pull-push
1610
+ paths:
1611
+ - packages/db2/.yarn
1612
+ - key: packagesdb2-node-modules
1613
+ policy: pull-push
1614
+ paths:
1615
+ - packages/db2/node_modules
1616
+ rules:
1617
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1618
+ - if: $CI_MERGE_REQUEST_ID
1619
+ needs: []
1620
+ retry: *a1
1621
+ interruptible: true
1622
+ db2 ๐Ÿงช test:
1623
+ stage: test
1624
+ image: path/to/docker/jobs-testing-chrome:the-version
1625
+ variables:
1626
+ KUBERNETES_CPU_REQUEST: '0.45'
1627
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1628
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1629
+ script:
1630
+ - collapseable_section_start "injectvars" "Injecting variables"
1631
+ - export APP_PATH="packages/db2"
1632
+ - collapseable_section_end "injectvars"
1633
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1634
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1635
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1636
+ - collapseable_section_end "nodeinstall"
1637
+ - cd packages/db2
1638
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1639
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1640
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1641
+ - collapseable_section_end "nodeinstall"
1642
+ - collapseable_section_start "yarninstall" "Yarn install"
1643
+ - yarn install --immutable
1644
+ - collapseable_section_end "yarninstall"
1645
+ - yarn test
1646
+ cache:
1647
+ - key: packagesdb2-yarn
1648
+ policy: pull-push
1649
+ paths:
1650
+ - packages/db2/.yarn
1651
+ - key: packagesdb2-node-modules
1652
+ policy: pull-push
1653
+ paths:
1654
+ - packages/db2/node_modules
1655
+ rules:
1656
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1657
+ - if: $CI_MERGE_REQUEST_ID
1658
+ needs: []
1659
+ retry: *a1
1660
+ interruptible: true
1661
+ 'db2 ๐Ÿ”จ app | dev ':
1662
+ stage: build
1663
+ image: path/to/docker/jobs-default:the-version
1664
+ variables:
1665
+ KUBERNETES_CPU_REQUEST: '0.45'
1666
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1667
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1668
+ script:
1669
+ - collapseable_section_start "injectvars" "Injecting variables"
1670
+ - export ENV_SHORT="dev"
1671
+ - export APP_DIR="packages/db2"
1672
+ - export ENV_TYPE="dev"
1673
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1674
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1675
+ - 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")"
1676
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1677
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1678
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1679
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1680
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1681
+ - export DB_NAME="pan-test-app-dev-db2"
1682
+ - export DB_USER="my-user"
1683
+ - export DB_PASSWORD="$CL_dev_db2_DB_PASSWORD"
1684
+ - export DATABASE_URL="postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename"
1685
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-dev-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db2_DB_PASSWORD"
1686
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db2-migrate:run"
1687
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1688
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1689
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey"
1690
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix"
1691
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1692
+ - collapseable_section_end "injectvars"
1693
+ - collapseable_section_start "write-dotenv-db2" "write dot env for db2"
1694
+ - |-
1695
+ cat <<EOF > packages/db2/.env
1696
+ ENV_SHORT=dev
1697
+ APP_DIR=packages/db2
1698
+ ENV_TYPE=dev
1699
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1700
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1701
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1702
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1703
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
1704
+ DB_NAME=pan-test-app-dev-db2
1705
+ DB_USER=my-user
1706
+ DB_PASSWORD=$(printf %s "$CL_dev_db2_DB_PASSWORD" | escapeForDotEnv)
1707
+ DATABASE_URL=postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename
1708
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-dev-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db2_DB_PASSWORD
1709
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db2-migrate:run
1710
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
1711
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
1712
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
1713
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
1714
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1715
+ EOF
1716
+ - collapseable_section_end "write-dotenv-db2"
1717
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db2/__build_info.json
1718
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1719
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1720
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1721
+ - collapseable_section_end "nodeinstall"
1722
+ - cd packages/db2
1723
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1724
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1725
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1726
+ - collapseable_section_end "nodeinstall"
1727
+ - collapseable_section_start "yarninstall" "Yarn install"
1728
+ - yarn install --immutable
1729
+ - collapseable_section_end "yarninstall"
1730
+ - yarn build
1731
+ cache:
1732
+ - key: packagesdb2-yarn
1733
+ policy: pull-push
1734
+ paths:
1735
+ - packages/db2/.yarn
1736
+ - key: packagesdb2-node-modules
1737
+ policy: pull-push
1738
+ paths:
1739
+ - packages/db2/node_modules
1740
+ artifacts:
1741
+ paths:
1742
+ - packages/db2/__build_info.json
1743
+ - packages/db2/.next
1744
+ - packages/db2/dist
1745
+ exclude:
1746
+ - packages/db2/.env
1747
+ expire_in: 1 day
1748
+ when: always
1749
+ reports: {}
1750
+ rules:
1751
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1752
+ needs: []
1753
+ retry: *a1
1754
+ interruptible: true
1755
+ 'db2 ๐Ÿ”จ docker | dev ':
1756
+ stage: build
1757
+ image: path/to/docker/docker-build:the-version
1758
+ services:
1759
+ - name: docker:24.0.6-dind
1760
+ command:
1761
+ - --tls=false
1762
+ - --registry-mirror=https://mirror.gcr.io
1763
+ variables:
1764
+ DOCKER_HOST: tcp://docker:2375
1765
+ DOCKER_TLS_CERTDIR: ''
1766
+ DOCKER_DRIVER: overlay2
1767
+ DOCKER_BUILDKIT: '1'
1768
+ KUBERNETES_CPU_REQUEST: '0.45'
1769
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1770
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1771
+ script:
1772
+ - collapseable_section_start "injectvars" "Injecting variables"
1773
+ - export APP_DIR="packages/db2"
1774
+ - export DOCKER_BUILD_CONTEXT="."
1775
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1776
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2"
1777
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
1778
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1779
+ - |-
1780
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1781
+ RUN yarn plugin import workspace-tools
1782
+ RUN yarn workspaces focus --production && yarn rebuild"
1783
+ - |-
1784
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db2/package.json /app/packages/db2/package.json
1785
+ COPY --chown=node:node packages/db2/yarn.lock /app/packages/db2/yarn.lock
1786
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1787
+ COPY --chown=node:node .yarn /app/.yarn"
1788
+ - collapseable_section_end "injectvars"
1789
+ - ensureNodeDockerfile
1790
+ - collapseable_section_start "docker-login" "Docker Login"
1791
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey")
1792
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1793
+ - collapseable_section_end "docker-login"
1794
+ - collapseable_section_start "docker-build" "Docker build"
1795
+ - 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
1796
+ - collapseable_section_end "docker-build"
1797
+ - collapseable_section_start "docker-push" "Docker push and tag"
1798
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1799
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1800
+ - docker push $DOCKER_CACHE_IMAGE
1801
+ - collapseable_section_end "docker-push"
1802
+ cache:
1803
+ - key: packagesdb2-yarn
1804
+ policy: pull
1805
+ paths:
1806
+ - packages/db2/.yarn
1807
+ rules:
1808
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1809
+ needs:
1810
+ - 'db2 ๐Ÿ”จ app | dev '
1811
+ retry: *a1
1812
+ interruptible: true
1813
+ 'db2 ๐Ÿงพ sbom | dev ':
1814
+ stage: build
1815
+ image:
1816
+ name: aquasec/trivy:0.58.2
1817
+ entrypoint:
1818
+ - ''
1819
+ variables: {}
1820
+ script:
1821
+ - collapseable_section_start "injectvars" "Injecting variables"
1822
+ - collapseable_section_end "injectvars"
1823
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db2
1824
+ artifacts:
1825
+ paths:
1826
+ - __sbom.json
1827
+ rules:
1828
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1829
+ needs: []
1830
+ retry: *a1
1831
+ interruptible: true
1832
+ allow_failure: true
1833
+ 'db2 ๐Ÿš€ Deploy | dev ':
1834
+ stage: deploy dev
1835
+ image: path/to/docker/gcloud:the-version
1836
+ variables:
1837
+ KUBERNETES_CPU_REQUEST: '0.22'
1838
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1839
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1840
+ script:
1841
+ - collapseable_section_start "injectvars" "Injecting variables"
1842
+ - export ENV_SHORT="dev"
1843
+ - export APP_DIR="packages/db2"
1844
+ - export ENV_TYPE="dev"
1845
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1846
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1847
+ - 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")"
1848
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1849
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1850
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1851
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1852
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1853
+ - export DB_NAME="pan-test-app-dev-db2"
1854
+ - export DB_USER="my-user"
1855
+ - export DB_PASSWORD="$CL_dev_db2_DB_PASSWORD"
1856
+ - export DATABASE_URL="postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename"
1857
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-dev-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db2_DB_PASSWORD"
1858
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db2-migrate:run"
1859
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1860
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1861
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey"
1862
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix"
1863
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1864
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1865
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2"
1866
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
1867
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1868
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1869
+ - collapseable_section_end "injectvars"
1870
+ - collapseable_section_start "prepare" "Prepare..."
1871
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey")
1872
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1873
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1874
+ - collapseable_section_end "prepare"
1875
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1876
+ - |
1877
+ cat > ____envvars.yaml <<EOF
1878
+ ENV_SHORT: |-
1879
+ dev
1880
+ APP_DIR: |-
1881
+ packages/db2
1882
+ ENV_TYPE: |-
1883
+ dev
1884
+ BUILD_INFO_BUILD_ID: |-
1885
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1886
+ BUILD_INFO_BUILD_TIME: |-
1887
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1888
+ BUILD_INFO_CURRENT_VERSION: |-
1889
+ $(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/^/ /')
1890
+ HOSTNAME: |-
1891
+ $(printf %s "$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1892
+ ROOT_URL: |-
1893
+ $(printf %s "https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1894
+ HOSTNAME_INTERNAL: |-
1895
+ $(printf %s "$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1896
+ ROOT_URL_INTERNAL: |-
1897
+ $(printf %s "https://$(printf %s "pan-test-app-dev-db2-$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1898
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1899
+ projectId:region:instancename
1900
+ DB_NAME: |-
1901
+ pan-test-app-dev-db2
1902
+ DB_USER: |-
1903
+ my-user
1904
+ DB_PASSWORD: |-
1905
+ $(printf %s "$CL_dev_db2_DB_PASSWORD" | sed '1!s/^/ /')
1906
+ DATABASE_URL: |-
1907
+ postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename
1908
+ DATABASE_JDBC_URL: |-
1909
+ jdbc:postgresql:///pan-test-app-dev-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_dev_db2_DB_PASSWORD
1910
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
1911
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-db2-migrate:run
1912
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1913
+ google-project-id
1914
+ DEPLOY_CLOUD_RUN_REGION: |-
1915
+ europe-west6
1916
+ GCLOUD_RUN_canonicalHostSuffix: |-
1917
+ $(printf %s "$CL_dev_db2_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1918
+ _ALL_ENV_VAR_KEYS: |-
1919
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1920
+
1921
+ EOF
1922
+ - collapseable_section_end "writeenvvars"
1923
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1924
+ - set +e
1925
+ - echo "ensuring Database..."
1926
+ - gcloud sql databases create pan-test-app-dev-db2 --instance=instancename --project projectId
1927
+ - set -e
1928
+ - |-
1929
+ exist_job_names="$(
1930
+ gcloud run jobs list --filter='metadata.name ~ dev.*db2' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
1931
+ )"
1932
+ current_job_name="pan-test-app-dev-db2-migrate"
1933
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1934
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1935
+ else
1936
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1937
+ fi
1938
+ - gcloud run jobs execute pan-test-app-dev-db2-migrate --project=google-project-id --region=europe-west6
1939
+ - collapseable_section_end "deploy"
1940
+ - collapseable_section_start "cleanup" "Cleanup"
1941
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-dev-db2 --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
1942
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2 --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/db2@$version --quiet --delete-tags; done
1943
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
1944
+ - collapseable_section_end "cleanup"
1945
+ - echo 'Uploading SBOM to Dependency Track'
1946
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db2" "$ROOT_URL" "__sbom.json" vex.json || true
1947
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1948
+ environment:
1949
+ name: dev/db2
1950
+ url: $CL_GITLAB_ENVIRONMENT_URL
1951
+ on_stop: 'db2 ๐Ÿ›‘ Stop โš ๏ธ | dev '
1952
+ auto_stop_in: 4 weeks
1953
+ artifacts:
1954
+ reports:
1955
+ dotenv: gitlab_environment.env
1956
+ rules:
1957
+ - when: on_success
1958
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
1959
+ needs:
1960
+ - job: db2 ๐Ÿ‘ฎ lint
1961
+ artifacts: false
1962
+ - job: 'db2 ๐Ÿ”จ app | dev '
1963
+ artifacts: false
1964
+ - job: 'db2 ๐Ÿ”จ docker | dev '
1965
+ artifacts: false
1966
+ - job: db2 ๐Ÿงช test
1967
+ artifacts: false
1968
+ - job: 'db2 ๐Ÿงพ sbom | dev '
1969
+ artifacts: true
1970
+ - job: db2 ๐Ÿ›ก audit
1971
+ artifacts: false
1972
+ retry: *a1
1973
+ interruptible: true
1974
+ allow_failure: false
1975
+ 'db2 ๐Ÿ›‘ Stop โš ๏ธ | dev ':
1976
+ stage: stop dev
1977
+ image: path/to/docker/gcloud:the-version
1978
+ variables:
1979
+ KUBERNETES_CPU_REQUEST: '0.22'
1980
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1981
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1982
+ GIT_STRATEGY: none
1983
+ script:
1984
+ - collapseable_section_start "injectvars" "Injecting variables"
1985
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1986
+ - collapseable_section_end "injectvars"
1987
+ - set +e
1988
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_db2_GCLOUD_DEPLOY_credentialsKey")
1989
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-dev-db2-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1990
+ - gcloud run jobs delete pan-test-app-dev-db2-migrate --project=google-project-id --region=europe-west6
1991
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/db2 --quiet --delete-tags
1992
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
1993
+ - echo 'Disabling component in Dependency Track'
1994
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db2" "$CI_ENVIRONMENT_URL" || true
1995
+ - set -e
1996
+ environment:
1997
+ name: dev/db2
1998
+ action: stop
1999
+ rules:
2000
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2001
+ when: on_success
2002
+ - when: manual
2003
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
2004
+ needs: []
2005
+ retry: *a1
2006
+ interruptible: true
2007
+ allow_failure: true
2008
+ 'db2 ๐Ÿ”จ app | review ':
2009
+ stage: build
2010
+ image: path/to/docker/jobs-default:the-version
2011
+ variables:
2012
+ KUBERNETES_CPU_REQUEST: '0.45'
2013
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2014
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2015
+ script:
2016
+ - collapseable_section_start "injectvars" "Injecting variables"
2017
+ - export ENV_SHORT="review"
2018
+ - export APP_DIR="packages/db2"
2019
+ - export ENV_TYPE="review"
2020
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2021
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2022
+ - 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")"
2023
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2024
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2025
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2026
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2027
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2028
+ - export DB_NAME="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"; })-db2"
2029
+ - export DB_USER="my-user"
2030
+ - export DB_PASSWORD="$CL_review_db2_DB_PASSWORD"
2031
+ - export DATABASE_URL="postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename"
2032
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///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"; })-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db2_DB_PASSWORD"
2033
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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\\"; })-db2\\" | awk '{print tolower($0)}')-migrate:run"
2034
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2035
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2036
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_db2_GCLOUD_DEPLOY_credentialsKey"
2037
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix"
2038
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2039
+ - collapseable_section_end "injectvars"
2040
+ - collapseable_section_start "write-dotenv-db2" "write dot env for db2"
2041
+ - |-
2042
+ cat <<EOF > packages/db2/.env
2043
+ ENV_SHORT=review
2044
+ APP_DIR=packages/db2
2045
+ ENV_TYPE=review
2046
+ 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2047
+ 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2048
+ 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2049
+ 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2050
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
2051
+ DB_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"; })-db2" | escapeForDotEnv)
2052
+ DB_USER=my-user
2053
+ DB_PASSWORD=$(printf %s "$CL_review_db2_DB_PASSWORD" | escapeForDotEnv)
2054
+ DATABASE_URL=$(printf %s "postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename" | escapeForDotEnv)
2055
+ DATABASE_JDBC_URL=$(printf %s "jdbc:postgresql:///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"; })-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db2_DB_PASSWORD" | escapeForDotEnv)
2056
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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"; })-db2" | awk '{print tolower($0)}')-migrate:run
2057
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
2058
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
2059
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_db2_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
2060
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
2061
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2062
+ EOF
2063
+ - collapseable_section_end "write-dotenv-db2"
2064
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db2/__build_info.json
2065
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2066
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2067
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2068
+ - collapseable_section_end "nodeinstall"
2069
+ - cd packages/db2
2070
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2071
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2072
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2073
+ - collapseable_section_end "nodeinstall"
2074
+ - collapseable_section_start "yarninstall" "Yarn install"
2075
+ - yarn install --immutable
2076
+ - collapseable_section_end "yarninstall"
2077
+ - yarn build
2078
+ cache:
2079
+ - key: packagesdb2-yarn
2080
+ policy: pull-push
2081
+ paths:
2082
+ - packages/db2/.yarn
2083
+ - key: packagesdb2-node-modules
2084
+ policy: pull-push
2085
+ paths:
2086
+ - packages/db2/node_modules
2087
+ artifacts:
2088
+ paths:
2089
+ - packages/db2/__build_info.json
2090
+ - packages/db2/.next
2091
+ - packages/db2/dist
2092
+ exclude:
2093
+ - packages/db2/.env
2094
+ expire_in: 1 day
2095
+ when: always
2096
+ reports: {}
2097
+ rules:
2098
+ - if: $CI_MERGE_REQUEST_ID
2099
+ needs: []
2100
+ retry: *a1
2101
+ interruptible: true
2102
+ 'db2 ๐Ÿ”จ docker | review ':
2103
+ stage: build
2104
+ image: path/to/docker/docker-build:the-version
2105
+ services:
2106
+ - name: docker:24.0.6-dind
2107
+ command:
2108
+ - --tls=false
2109
+ - --registry-mirror=https://mirror.gcr.io
2110
+ variables:
2111
+ DOCKER_HOST: tcp://docker:2375
2112
+ DOCKER_TLS_CERTDIR: ''
2113
+ DOCKER_DRIVER: overlay2
2114
+ DOCKER_BUILDKIT: '1'
2115
+ KUBERNETES_CPU_REQUEST: '0.45'
2116
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2117
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2118
+ script:
2119
+ - collapseable_section_start "injectvars" "Injecting variables"
2120
+ - export APP_DIR="packages/db2"
2121
+ - export DOCKER_BUILD_CONTEXT="."
2122
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2123
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
2124
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2125
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2126
+ - |-
2127
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2128
+ RUN yarn plugin import workspace-tools
2129
+ RUN yarn workspaces focus --production && yarn rebuild"
2130
+ - |-
2131
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db2/package.json /app/packages/db2/package.json
2132
+ COPY --chown=node:node packages/db2/yarn.lock /app/packages/db2/yarn.lock
2133
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2134
+ COPY --chown=node:node .yarn /app/.yarn"
2135
+ - collapseable_section_end "injectvars"
2136
+ - ensureNodeDockerfile
2137
+ - collapseable_section_start "docker-login" "Docker Login"
2138
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db2_GCLOUD_DEPLOY_credentialsKey")
2139
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
2140
+ - collapseable_section_end "docker-login"
2141
+ - collapseable_section_start "docker-build" "Docker build"
2142
+ - 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
2143
+ - collapseable_section_end "docker-build"
2144
+ - collapseable_section_start "docker-push" "Docker push and tag"
2145
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2146
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2147
+ - docker push $DOCKER_CACHE_IMAGE
2148
+ - collapseable_section_end "docker-push"
2149
+ cache:
2150
+ - key: packagesdb2-yarn
2151
+ policy: pull
2152
+ paths:
2153
+ - packages/db2/.yarn
2154
+ rules:
2155
+ - if: $CI_MERGE_REQUEST_ID
2156
+ needs:
2157
+ - 'db2 ๐Ÿ”จ app | review '
2158
+ retry: *a1
2159
+ interruptible: true
2160
+ 'db2 ๐Ÿงพ sbom | review ':
2161
+ stage: build
2162
+ image:
2163
+ name: aquasec/trivy:0.58.2
2164
+ entrypoint:
2165
+ - ''
2166
+ variables: {}
2167
+ script:
2168
+ - collapseable_section_start "injectvars" "Injecting variables"
2169
+ - collapseable_section_end "injectvars"
2170
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db2
2171
+ artifacts:
2172
+ paths:
2173
+ - __sbom.json
2174
+ rules:
2175
+ - if: $CI_MERGE_REQUEST_ID
2176
+ needs: []
2177
+ retry: *a1
2178
+ interruptible: true
2179
+ allow_failure: true
2180
+ 'db2 ๐Ÿš€ Deploy | review ':
2181
+ stage: deploy review
2182
+ image: path/to/docker/gcloud:the-version
2183
+ variables:
2184
+ KUBERNETES_CPU_REQUEST: '0.22'
2185
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2186
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2187
+ script:
2188
+ - collapseable_section_start "injectvars" "Injecting variables"
2189
+ - export ENV_SHORT="review"
2190
+ - export APP_DIR="packages/db2"
2191
+ - export ENV_TYPE="review"
2192
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2193
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2194
+ - 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")"
2195
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2196
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2197
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2198
+ - 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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2199
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2200
+ - export DB_NAME="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"; })-db2"
2201
+ - export DB_USER="my-user"
2202
+ - export DB_PASSWORD="$CL_review_db2_DB_PASSWORD"
2203
+ - export DATABASE_URL="postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename"
2204
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///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"; })-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db2_DB_PASSWORD"
2205
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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\\"; })-db2\\" | awk '{print tolower($0)}')-migrate:run"
2206
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2207
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2208
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_db2_GCLOUD_DEPLOY_credentialsKey"
2209
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix"
2210
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2211
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2212
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
2213
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2214
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2215
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2216
+ - collapseable_section_end "injectvars"
2217
+ - collapseable_section_start "prepare" "Prepare..."
2218
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db2_GCLOUD_DEPLOY_credentialsKey")
2219
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2220
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2221
+ - collapseable_section_end "prepare"
2222
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
2223
+ - |
2224
+ cat > ____envvars.yaml <<EOF
2225
+ ENV_SHORT: |-
2226
+ review
2227
+ APP_DIR: |-
2228
+ packages/db2
2229
+ ENV_TYPE: |-
2230
+ review
2231
+ BUILD_INFO_BUILD_ID: |-
2232
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
2233
+ BUILD_INFO_BUILD_TIME: |-
2234
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
2235
+ BUILD_INFO_CURRENT_VERSION: |-
2236
+ $(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/^/ /')
2237
+ HOSTNAME: |-
2238
+ $(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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2239
+ ROOT_URL: |-
2240
+ $(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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2241
+ HOSTNAME_INTERNAL: |-
2242
+ $(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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2243
+ ROOT_URL_INTERNAL: |-
2244
+ $(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"; })-db2-$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2245
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2246
+ projectId:region:instancename
2247
+ DB_NAME: |-
2248
+ $(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"; })-db2" | sed '1!s/^/ /')
2249
+ DB_USER: |-
2250
+ my-user
2251
+ DB_PASSWORD: |-
2252
+ $(printf %s "$CL_review_db2_DB_PASSWORD" | sed '1!s/^/ /')
2253
+ DATABASE_URL: |-
2254
+ $(printf %s "postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename" | sed '1!s/^/ /')
2255
+ DATABASE_JDBC_URL: |-
2256
+ $(printf %s "jdbc:postgresql:///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"; })-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_review_db2_DB_PASSWORD" | sed '1!s/^/ /')
2257
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
2258
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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"; })-db2" | awk '{print tolower($0)}')-migrate:run
2259
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2260
+ google-project-id
2261
+ DEPLOY_CLOUD_RUN_REGION: |-
2262
+ europe-west6
2263
+ GCLOUD_RUN_canonicalHostSuffix: |-
2264
+ $(printf %s "$CL_review_db2_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
2265
+ _ALL_ENV_VAR_KEYS: |-
2266
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2267
+
2268
+ EOF
2269
+ - collapseable_section_end "writeenvvars"
2270
+ - collapseable_section_start "deploy" "Deploy to cloud run"
2271
+ - set +e
2272
+ - echo "ensuring Database..."
2273
+ - gcloud sql databases create 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"; })-db2 --instance=instancename --project projectId
2274
+ - set -e
2275
+ - |-
2276
+ exist_job_names="$(
2277
+ gcloud run jobs list --filter='metadata.name ~ review.*db2' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
2278
+ )"
2279
+ current_job_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"; })-db2" | awk '{print tolower($0)}')-migrate"
2280
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
2281
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2282
+ else
2283
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2284
+ fi
2285
+ - gcloud run jobs execute $(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"; })-db2" | awk '{print tolower($0)}')-migrate --project=google-project-id --region=europe-west6
2286
+ - collapseable_section_end "deploy"
2287
+ - collapseable_section_start "cleanup" "Cleanup"
2288
+ - 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"; })-db2" | 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
2289
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -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/db2/$([ -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
2290
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
2291
+ - set +e
2292
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2 --quiet --delete-tags
2293
+ - set -e
2294
+ - collapseable_section_end "cleanup"
2295
+ - echo 'Uploading SBOM to Dependency Track'
2296
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db2" "$ROOT_URL" "__sbom.json" vex.json || true
2297
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
2298
+ environment:
2299
+ name: review/$CI_COMMIT_REF_NAME/db2
2300
+ url: $CL_GITLAB_ENVIRONMENT_URL
2301
+ on_stop: 'db2 ๐Ÿ›‘ Stop โš ๏ธ | review '
2302
+ auto_stop_in: 1 week
2303
+ artifacts:
2304
+ reports:
2305
+ dotenv: gitlab_environment.env
2306
+ rules:
2307
+ - when: on_success
2308
+ if: $CI_MERGE_REQUEST_ID
2309
+ needs:
2310
+ - job: db2 ๐Ÿ‘ฎ lint
2311
+ artifacts: false
2312
+ - job: 'db2 ๐Ÿ”จ app | review '
2313
+ artifacts: false
2314
+ - job: 'db2 ๐Ÿ”จ docker | review '
2315
+ artifacts: false
2316
+ - job: db2 ๐Ÿงช test
2317
+ artifacts: false
2318
+ - job: 'db2 ๐Ÿงพ sbom | review '
2319
+ artifacts: true
2320
+ - job: db2 ๐Ÿ›ก audit
2321
+ artifacts: false
2322
+ retry: *a1
2323
+ interruptible: true
2324
+ allow_failure: false
2325
+ 'db2 ๐Ÿ›‘ Stop โš ๏ธ | review ':
2326
+ stage: stop review
2327
+ image: path/to/docker/gcloud:the-version
2328
+ variables:
2329
+ KUBERNETES_CPU_REQUEST: '0.22'
2330
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2331
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2332
+ GIT_STRATEGY: none
2333
+ script:
2334
+ - collapseable_section_start "injectvars" "Injecting variables"
2335
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2336
+ - collapseable_section_end "injectvars"
2337
+ - set +e
2338
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_db2_GCLOUD_DEPLOY_credentialsKey")
2339
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job $(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"; })-db2" | awk '{print tolower($0)}')-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
2340
+ - gcloud run jobs 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"; })-db2" | awk '{print tolower($0)}')-migrate --project=google-project-id --region=europe-west6
2341
+ - echo "deleting database 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"; })-db2..."
2342
+ - echo "๐Ÿ‘† this can take multiple attemps (3-5min), because google cloud run may still have a connection to the database after the cloud run service is shut down"
2343
+ - "\\n until gcloud sql databases delete 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\\"; })-db2 --instance=instancename --project projectId\\n do\\n echo \\"Trying again.\\"\\n sleep 10\\n done\\n "
2344
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2/$([ -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
2345
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
2346
+ - set +e
2347
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/db2 --quiet --delete-tags
2348
+ - set -e
2349
+ - echo 'Disabling component in Dependency Track'
2350
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db2" "$CI_ENVIRONMENT_URL" || true
2351
+ - set -e
2352
+ environment:
2353
+ name: review/$CI_COMMIT_REF_NAME/db2
2354
+ action: stop
2355
+ rules:
2356
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2357
+ when: on_success
2358
+ - when: manual
2359
+ if: $CI_MERGE_REQUEST_ID
2360
+ needs: []
2361
+ retry: *a1
2362
+ interruptible: true
2363
+ allow_failure: true
2364
+ 'db2 ๐Ÿ”จ app | stage ':
2365
+ stage: build
2366
+ image: path/to/docker/jobs-default:the-version
2367
+ variables:
2368
+ KUBERNETES_CPU_REQUEST: '0.45'
2369
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2370
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2371
+ script:
2372
+ - collapseable_section_start "injectvars" "Injecting variables"
2373
+ - export ENV_SHORT="stage"
2374
+ - export APP_DIR="packages/db2"
2375
+ - export ENV_TYPE="stage"
2376
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2377
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2378
+ - 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")"
2379
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2380
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2381
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2382
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2383
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2384
+ - export DB_NAME="pan-test-app-stage-db2"
2385
+ - export DB_USER="my-user"
2386
+ - export DB_PASSWORD="$CL_stage_db2_DB_PASSWORD"
2387
+ - export DATABASE_URL="postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename"
2388
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-stage-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db2_DB_PASSWORD"
2389
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db2-migrate:run"
2390
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2391
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2392
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey"
2393
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix"
2394
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2395
+ - collapseable_section_end "injectvars"
2396
+ - collapseable_section_start "write-dotenv-db2" "write dot env for db2"
2397
+ - |-
2398
+ cat <<EOF > packages/db2/.env
2399
+ ENV_SHORT=stage
2400
+ APP_DIR=packages/db2
2401
+ ENV_TYPE=stage
2402
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2403
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2404
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2405
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2406
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
2407
+ DB_NAME=pan-test-app-stage-db2
2408
+ DB_USER=my-user
2409
+ DB_PASSWORD=$(printf %s "$CL_stage_db2_DB_PASSWORD" | escapeForDotEnv)
2410
+ DATABASE_URL=postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename
2411
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-stage-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db2_DB_PASSWORD
2412
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db2-migrate:run
2413
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
2414
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
2415
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
2416
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
2417
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2418
+ EOF
2419
+ - collapseable_section_end "write-dotenv-db2"
2420
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db2/__build_info.json
2421
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2422
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2423
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2424
+ - collapseable_section_end "nodeinstall"
2425
+ - cd packages/db2
2426
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2427
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2428
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2429
+ - collapseable_section_end "nodeinstall"
2430
+ - collapseable_section_start "yarninstall" "Yarn install"
2431
+ - yarn install --immutable
2432
+ - collapseable_section_end "yarninstall"
2433
+ - yarn build
2434
+ cache:
2435
+ - key: packagesdb2-yarn
2436
+ policy: pull-push
2437
+ paths:
2438
+ - packages/db2/.yarn
2439
+ - key: packagesdb2-node-modules
2440
+ policy: pull-push
2441
+ paths:
2442
+ - packages/db2/node_modules
2443
+ artifacts:
2444
+ paths:
2445
+ - packages/db2/__build_info.json
2446
+ - packages/db2/.next
2447
+ - packages/db2/dist
2448
+ exclude:
2449
+ - packages/db2/.env
2450
+ expire_in: 1 day
2451
+ when: always
2452
+ reports: {}
2453
+ rules:
2454
+ - if: $CI_COMMIT_TAG
2455
+ needs: []
2456
+ retry: *a1
2457
+ interruptible: true
2458
+ 'db2 ๐Ÿ”จ docker | stage ':
2459
+ stage: build
2460
+ image: path/to/docker/docker-build:the-version
2461
+ services:
2462
+ - name: docker:24.0.6-dind
2463
+ command:
2464
+ - --tls=false
2465
+ - --registry-mirror=https://mirror.gcr.io
2466
+ variables:
2467
+ DOCKER_HOST: tcp://docker:2375
2468
+ DOCKER_TLS_CERTDIR: ''
2469
+ DOCKER_DRIVER: overlay2
2470
+ DOCKER_BUILDKIT: '1'
2471
+ KUBERNETES_CPU_REQUEST: '0.45'
2472
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2473
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2474
+ script:
2475
+ - collapseable_section_start "injectvars" "Injecting variables"
2476
+ - export APP_DIR="packages/db2"
2477
+ - export DOCKER_BUILD_CONTEXT="."
2478
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2479
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2"
2480
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2481
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2482
+ - |-
2483
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2484
+ RUN yarn plugin import workspace-tools
2485
+ RUN yarn workspaces focus --production && yarn rebuild"
2486
+ - |-
2487
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db2/package.json /app/packages/db2/package.json
2488
+ COPY --chown=node:node packages/db2/yarn.lock /app/packages/db2/yarn.lock
2489
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2490
+ COPY --chown=node:node .yarn /app/.yarn"
2491
+ - collapseable_section_end "injectvars"
2492
+ - ensureNodeDockerfile
2493
+ - collapseable_section_start "docker-login" "Docker Login"
2494
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey")
2495
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
2496
+ - collapseable_section_end "docker-login"
2497
+ - collapseable_section_start "docker-build" "Docker build"
2498
+ - 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
2499
+ - collapseable_section_end "docker-build"
2500
+ - collapseable_section_start "docker-push" "Docker push and tag"
2501
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2502
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2503
+ - docker push $DOCKER_CACHE_IMAGE
2504
+ - collapseable_section_end "docker-push"
2505
+ cache:
2506
+ - key: packagesdb2-yarn
2507
+ policy: pull
2508
+ paths:
2509
+ - packages/db2/.yarn
2510
+ rules:
2511
+ - if: $CI_COMMIT_TAG
2512
+ needs:
2513
+ - 'db2 ๐Ÿ”จ app | stage '
2514
+ retry: *a1
2515
+ interruptible: true
2516
+ 'db2 ๐Ÿงพ sbom | stage ':
2517
+ stage: build
2518
+ image:
2519
+ name: aquasec/trivy:0.58.2
2520
+ entrypoint:
2521
+ - ''
2522
+ variables: {}
2523
+ script:
2524
+ - collapseable_section_start "injectvars" "Injecting variables"
2525
+ - collapseable_section_end "injectvars"
2526
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db2
2527
+ artifacts:
2528
+ paths:
2529
+ - __sbom.json
2530
+ rules:
2531
+ - if: $CI_COMMIT_TAG
2532
+ needs: []
2533
+ retry: *a1
2534
+ interruptible: true
2535
+ allow_failure: true
2536
+ 'db2 ๐Ÿš€ Deploy | stage ':
2537
+ stage: deploy stage
2538
+ image: path/to/docker/gcloud:the-version
2539
+ variables:
2540
+ KUBERNETES_CPU_REQUEST: '0.22'
2541
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2542
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2543
+ script:
2544
+ - collapseable_section_start "injectvars" "Injecting variables"
2545
+ - export ENV_SHORT="stage"
2546
+ - export APP_DIR="packages/db2"
2547
+ - export ENV_TYPE="stage"
2548
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2549
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2550
+ - 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")"
2551
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2552
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2553
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2554
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2555
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2556
+ - export DB_NAME="pan-test-app-stage-db2"
2557
+ - export DB_USER="my-user"
2558
+ - export DB_PASSWORD="$CL_stage_db2_DB_PASSWORD"
2559
+ - export DATABASE_URL="postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename"
2560
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-stage-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db2_DB_PASSWORD"
2561
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db2-migrate:run"
2562
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2563
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2564
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey"
2565
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix"
2566
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2567
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2568
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2"
2569
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2570
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2571
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2572
+ - collapseable_section_end "injectvars"
2573
+ - collapseable_section_start "prepare" "Prepare..."
2574
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey")
2575
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2576
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2577
+ - collapseable_section_end "prepare"
2578
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
2579
+ - |
2580
+ cat > ____envvars.yaml <<EOF
2581
+ ENV_SHORT: |-
2582
+ stage
2583
+ APP_DIR: |-
2584
+ packages/db2
2585
+ ENV_TYPE: |-
2586
+ stage
2587
+ BUILD_INFO_BUILD_ID: |-
2588
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
2589
+ BUILD_INFO_BUILD_TIME: |-
2590
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
2591
+ BUILD_INFO_CURRENT_VERSION: |-
2592
+ $(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/^/ /')
2593
+ HOSTNAME: |-
2594
+ $(printf %s "$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2595
+ ROOT_URL: |-
2596
+ $(printf %s "https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2597
+ HOSTNAME_INTERNAL: |-
2598
+ $(printf %s "$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2599
+ ROOT_URL_INTERNAL: |-
2600
+ $(printf %s "https://$(printf %s "pan-test-app-stage-db2-$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2601
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2602
+ projectId:region:instancename
2603
+ DB_NAME: |-
2604
+ pan-test-app-stage-db2
2605
+ DB_USER: |-
2606
+ my-user
2607
+ DB_PASSWORD: |-
2608
+ $(printf %s "$CL_stage_db2_DB_PASSWORD" | sed '1!s/^/ /')
2609
+ DATABASE_URL: |-
2610
+ postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename
2611
+ DATABASE_JDBC_URL: |-
2612
+ jdbc:postgresql:///pan-test-app-stage-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_stage_db2_DB_PASSWORD
2613
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
2614
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-db2-migrate:run
2615
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2616
+ google-project-id
2617
+ DEPLOY_CLOUD_RUN_REGION: |-
2618
+ europe-west6
2619
+ GCLOUD_RUN_canonicalHostSuffix: |-
2620
+ $(printf %s "$CL_stage_db2_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
2621
+ _ALL_ENV_VAR_KEYS: |-
2622
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2623
+
2624
+ EOF
2625
+ - collapseable_section_end "writeenvvars"
2626
+ - collapseable_section_start "deploy" "Deploy to cloud run"
2627
+ - set +e
2628
+ - echo "ensuring Database..."
2629
+ - gcloud sql databases create pan-test-app-stage-db2 --instance=instancename --project projectId
2630
+ - set -e
2631
+ - |-
2632
+ exist_job_names="$(
2633
+ gcloud run jobs list --filter='metadata.name ~ stage.*db2' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
2634
+ )"
2635
+ current_job_name="pan-test-app-stage-db2-migrate"
2636
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
2637
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2638
+ else
2639
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2640
+ fi
2641
+ - gcloud run jobs execute pan-test-app-stage-db2-migrate --project=google-project-id --region=europe-west6
2642
+ - collapseable_section_end "deploy"
2643
+ - collapseable_section_start "cleanup" "Cleanup"
2644
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-stage-db2 --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
2645
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2 --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/db2@$version --quiet --delete-tags; done
2646
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
2647
+ - collapseable_section_end "cleanup"
2648
+ - echo 'Uploading SBOM to Dependency Track'
2649
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db2" "$ROOT_URL" "__sbom.json" vex.json || true
2650
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
2651
+ environment:
2652
+ name: stage/db2
2653
+ url: $CL_GITLAB_ENVIRONMENT_URL
2654
+ on_stop: 'db2 ๐Ÿ›‘ Stop โš ๏ธ | stage '
2655
+ artifacts:
2656
+ reports:
2657
+ dotenv: gitlab_environment.env
2658
+ rules:
2659
+ - when: on_success
2660
+ if: $CI_COMMIT_TAG
2661
+ needs:
2662
+ - job: 'db2 ๐Ÿ”จ app | stage '
2663
+ artifacts: false
2664
+ - job: 'db2 ๐Ÿ”จ docker | stage '
2665
+ artifacts: false
2666
+ - job: 'db2 ๐Ÿงพ sbom | stage '
2667
+ artifacts: true
2668
+ retry: *a1
2669
+ interruptible: true
2670
+ allow_failure: false
2671
+ 'db2 ๐Ÿ›‘ Stop โš ๏ธ | stage ':
2672
+ stage: stop stage
2673
+ image: path/to/docker/gcloud:the-version
2674
+ variables:
2675
+ KUBERNETES_CPU_REQUEST: '0.22'
2676
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2677
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2678
+ GIT_STRATEGY: none
2679
+ script:
2680
+ - collapseable_section_start "injectvars" "Injecting variables"
2681
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2682
+ - collapseable_section_end "injectvars"
2683
+ - set +e
2684
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_db2_GCLOUD_DEPLOY_credentialsKey")
2685
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-stage-db2-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
2686
+ - gcloud run jobs delete pan-test-app-stage-db2-migrate --project=google-project-id --region=europe-west6
2687
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/db2 --quiet --delete-tags
2688
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
2689
+ - echo 'Disabling component in Dependency Track'
2690
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db2" "$CI_ENVIRONMENT_URL" || true
2691
+ - set -e
2692
+ environment:
2693
+ name: stage/db2
2694
+ action: stop
2695
+ rules:
2696
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2697
+ when: on_success
2698
+ - when: manual
2699
+ if: $CI_COMMIT_TAG
2700
+ needs: []
2701
+ retry: *a1
2702
+ interruptible: true
2703
+ allow_failure: true
2704
+ 'db2 ๐Ÿ”จ app | prod ':
2705
+ stage: build
2706
+ image: path/to/docker/jobs-default:the-version
2707
+ variables:
2708
+ KUBERNETES_CPU_REQUEST: '0.45'
2709
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2710
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2711
+ script:
2712
+ - collapseable_section_start "injectvars" "Injecting variables"
2713
+ - export ENV_SHORT="prod"
2714
+ - export APP_DIR="packages/db2"
2715
+ - export ENV_TYPE="prod"
2716
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2717
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2718
+ - 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")"
2719
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2720
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2721
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2722
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2723
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2724
+ - export DB_NAME="pan-test-app-prod-db2"
2725
+ - export DB_USER="my-user"
2726
+ - export DB_PASSWORD="$CL_prod_db2_DB_PASSWORD"
2727
+ - export DATABASE_URL="postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename"
2728
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-prod-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db2_DB_PASSWORD"
2729
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db2-migrate:run"
2730
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2731
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2732
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey"
2733
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix"
2734
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2735
+ - collapseable_section_end "injectvars"
2736
+ - collapseable_section_start "write-dotenv-db2" "write dot env for db2"
2737
+ - |-
2738
+ cat <<EOF > packages/db2/.env
2739
+ ENV_SHORT=prod
2740
+ APP_DIR=packages/db2
2741
+ ENV_TYPE=prod
2742
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2743
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2744
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2745
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
2746
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
2747
+ DB_NAME=pan-test-app-prod-db2
2748
+ DB_USER=my-user
2749
+ DB_PASSWORD=$(printf %s "$CL_prod_db2_DB_PASSWORD" | escapeForDotEnv)
2750
+ DATABASE_URL=postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename
2751
+ DATABASE_JDBC_URL=jdbc:postgresql:///pan-test-app-prod-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db2_DB_PASSWORD
2752
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db2-migrate:run
2753
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
2754
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
2755
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
2756
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
2757
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2758
+ EOF
2759
+ - collapseable_section_end "write-dotenv-db2"
2760
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > packages/db2/__build_info.json
2761
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2762
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2763
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2764
+ - collapseable_section_end "nodeinstall"
2765
+ - cd packages/db2
2766
+ - collapseable_section_start "nodeinstall" "Ensure node version"
2767
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2768
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2769
+ - collapseable_section_end "nodeinstall"
2770
+ - collapseable_section_start "yarninstall" "Yarn install"
2771
+ - yarn install --immutable
2772
+ - collapseable_section_end "yarninstall"
2773
+ - yarn build
2774
+ cache:
2775
+ - key: packagesdb2-yarn
2776
+ policy: pull-push
2777
+ paths:
2778
+ - packages/db2/.yarn
2779
+ - key: packagesdb2-node-modules
2780
+ policy: pull-push
2781
+ paths:
2782
+ - packages/db2/node_modules
2783
+ artifacts:
2784
+ paths:
2785
+ - packages/db2/__build_info.json
2786
+ - packages/db2/.next
2787
+ - packages/db2/dist
2788
+ exclude:
2789
+ - packages/db2/.env
2790
+ expire_in: 1 day
2791
+ when: always
2792
+ reports: {}
2793
+ rules:
2794
+ - if: $CI_COMMIT_TAG
2795
+ needs: []
2796
+ retry: *a1
2797
+ interruptible: true
2798
+ 'db2 ๐Ÿ”จ docker | prod ':
2799
+ stage: build
2800
+ image: path/to/docker/docker-build:the-version
2801
+ services:
2802
+ - name: docker:24.0.6-dind
2803
+ command:
2804
+ - --tls=false
2805
+ - --registry-mirror=https://mirror.gcr.io
2806
+ variables:
2807
+ DOCKER_HOST: tcp://docker:2375
2808
+ DOCKER_TLS_CERTDIR: ''
2809
+ DOCKER_DRIVER: overlay2
2810
+ DOCKER_BUILDKIT: '1'
2811
+ KUBERNETES_CPU_REQUEST: '0.45'
2812
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2813
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2814
+ script:
2815
+ - collapseable_section_start "injectvars" "Injecting variables"
2816
+ - export APP_DIR="packages/db2"
2817
+ - export DOCKER_BUILD_CONTEXT="."
2818
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2819
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2"
2820
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2821
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2822
+ - |-
2823
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2824
+ RUN yarn plugin import workspace-tools
2825
+ RUN yarn workspaces focus --production && yarn rebuild"
2826
+ - |-
2827
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node packages/db2/package.json /app/packages/db2/package.json
2828
+ COPY --chown=node:node packages/db2/yarn.lock /app/packages/db2/yarn.lock
2829
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2830
+ COPY --chown=node:node .yarn /app/.yarn"
2831
+ - collapseable_section_end "injectvars"
2832
+ - ensureNodeDockerfile
2833
+ - collapseable_section_start "docker-login" "Docker Login"
2834
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey")
2835
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
2836
+ - collapseable_section_end "docker-login"
2837
+ - collapseable_section_start "docker-build" "Docker build"
2838
+ - 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
2839
+ - collapseable_section_end "docker-build"
2840
+ - collapseable_section_start "docker-push" "Docker push and tag"
2841
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2842
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2843
+ - docker push $DOCKER_CACHE_IMAGE
2844
+ - collapseable_section_end "docker-push"
2845
+ cache:
2846
+ - key: packagesdb2-yarn
2847
+ policy: pull
2848
+ paths:
2849
+ - packages/db2/.yarn
2850
+ rules:
2851
+ - if: $CI_COMMIT_TAG
2852
+ needs:
2853
+ - 'db2 ๐Ÿ”จ app | prod '
2854
+ retry: *a1
2855
+ interruptible: true
2856
+ 'db2 ๐Ÿงพ sbom | prod ':
2857
+ stage: build
2858
+ image:
2859
+ name: aquasec/trivy:0.58.2
2860
+ entrypoint:
2861
+ - ''
2862
+ variables: {}
2863
+ script:
2864
+ - collapseable_section_start "injectvars" "Injecting variables"
2865
+ - collapseable_section_end "injectvars"
2866
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" packages/db2
2867
+ artifacts:
2868
+ paths:
2869
+ - __sbom.json
2870
+ rules:
2871
+ - if: $CI_COMMIT_TAG
2872
+ needs: []
2873
+ retry: *a1
2874
+ interruptible: true
2875
+ allow_failure: true
2876
+ 'db2 ๐Ÿš€ Deploy | prod ':
2877
+ stage: deploy prod
2878
+ image: path/to/docker/gcloud:the-version
2879
+ variables:
2880
+ KUBERNETES_CPU_REQUEST: '0.22'
2881
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2882
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2883
+ script:
2884
+ - collapseable_section_start "injectvars" "Injecting variables"
2885
+ - export ENV_SHORT="prod"
2886
+ - export APP_DIR="packages/db2"
2887
+ - export ENV_TYPE="prod"
2888
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2889
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2890
+ - 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")"
2891
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2892
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2893
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2894
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2895
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2896
+ - export DB_NAME="pan-test-app-prod-db2"
2897
+ - export DB_USER="my-user"
2898
+ - export DB_PASSWORD="$CL_prod_db2_DB_PASSWORD"
2899
+ - export DATABASE_URL="postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename"
2900
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///pan-test-app-prod-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db2_DB_PASSWORD"
2901
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migrate="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db2-migrate:run"
2902
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2903
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2904
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey"
2905
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix"
2906
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migrate\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
2907
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2908
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2"
2909
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2"
2910
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2911
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2912
+ - collapseable_section_end "injectvars"
2913
+ - collapseable_section_start "prepare" "Prepare..."
2914
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey")
2915
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2916
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2917
+ - collapseable_section_end "prepare"
2918
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
2919
+ - |
2920
+ cat > ____envvars.yaml <<EOF
2921
+ ENV_SHORT: |-
2922
+ prod
2923
+ APP_DIR: |-
2924
+ packages/db2
2925
+ ENV_TYPE: |-
2926
+ prod
2927
+ BUILD_INFO_BUILD_ID: |-
2928
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
2929
+ BUILD_INFO_BUILD_TIME: |-
2930
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
2931
+ BUILD_INFO_CURRENT_VERSION: |-
2932
+ $(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/^/ /')
2933
+ HOSTNAME: |-
2934
+ $(printf %s "$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2935
+ ROOT_URL: |-
2936
+ $(printf %s "https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2937
+ HOSTNAME_INTERNAL: |-
2938
+ $(printf %s "$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2939
+ ROOT_URL_INTERNAL: |-
2940
+ $(printf %s "https://$(printf %s "pan-test-app-prod-db2-$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
2941
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2942
+ projectId:region:instancename
2943
+ DB_NAME: |-
2944
+ pan-test-app-prod-db2
2945
+ DB_USER: |-
2946
+ my-user
2947
+ DB_PASSWORD: |-
2948
+ $(printf %s "$CL_prod_db2_DB_PASSWORD" | sed '1!s/^/ /')
2949
+ DATABASE_URL: |-
2950
+ postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename
2951
+ DATABASE_JDBC_URL: |-
2952
+ jdbc:postgresql:///pan-test-app-prod-db2?cloudSqlInstance=projectId:region:instancename&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=my-user&password=$CL_prod_db2_DB_PASSWORD
2953
+ CLOUD_RUN_JOB_TRIGGER_URL_migrate: |-
2954
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-db2-migrate:run
2955
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2956
+ google-project-id
2957
+ DEPLOY_CLOUD_RUN_REGION: |-
2958
+ europe-west6
2959
+ GCLOUD_RUN_canonicalHostSuffix: |-
2960
+ $(printf %s "$CL_prod_db2_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
2961
+ _ALL_ENV_VAR_KEYS: |-
2962
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","CLOUD_RUN_JOB_TRIGGER_URL_migrate","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2963
+
2964
+ EOF
2965
+ - collapseable_section_end "writeenvvars"
2966
+ - collapseable_section_start "deploy" "Deploy to cloud run"
2967
+ - set +e
2968
+ - echo "ensuring Database..."
2969
+ - gcloud sql databases create pan-test-app-prod-db2 --instance=instancename --project projectId
2970
+ - set -e
2971
+ - |-
2972
+ exist_job_names="$(
2973
+ gcloud run jobs list --filter='metadata.name ~ prod.*db2' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
2974
+ )"
2975
+ current_job_name="pan-test-app-prod-db2-migrate"
2976
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
2977
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2978
+ else
2979
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=db2,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --image="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2:$DOCKER_IMAGE_TAG" --project=google-project-id --region=europe-west6 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
2980
+ fi
2981
+ - gcloud run jobs execute pan-test-app-prod-db2-migrate --project=google-project-id --region=europe-west6
2982
+ - collapseable_section_end "deploy"
2983
+ - collapseable_section_start "cleanup" "Cleanup"
2984
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-prod-db2 --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
2985
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2 --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/db2@$version --quiet --delete-tags; done
2986
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
2987
+ - collapseable_section_end "cleanup"
2988
+ - echo 'Uploading SBOM to Dependency Track'
2989
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/db2" "$ROOT_URL" "__sbom.json" vex.json || true
2990
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
2991
+ environment:
2992
+ name: prod/db2
2993
+ url: $CL_GITLAB_ENVIRONMENT_URL
2994
+ on_stop: 'db2 ๐Ÿ›‘ Stop โš ๏ธ | prod '
2995
+ artifacts:
2996
+ reports:
2997
+ dotenv: gitlab_environment.env
2998
+ rules:
2999
+ - when: manual
3000
+ if: $CI_COMMIT_TAG
3001
+ needs:
3002
+ - job: 'db2 ๐Ÿ”จ app | prod '
3003
+ artifacts: false
3004
+ - job: 'db2 ๐Ÿ”จ docker | prod '
3005
+ artifacts: false
3006
+ - job: 'db2 ๐Ÿงพ sbom | prod '
3007
+ artifacts: true
3008
+ retry: *a1
3009
+ interruptible: true
3010
+ allow_failure: true
3011
+ 'db2 ๐Ÿ›‘ Stop โš ๏ธ | prod ':
3012
+ stage: stop prod
3013
+ image: path/to/docker/gcloud:the-version
3014
+ variables:
3015
+ KUBERNETES_CPU_REQUEST: '0.22'
3016
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3017
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3018
+ GIT_STRATEGY: none
3019
+ script:
3020
+ - collapseable_section_start "injectvars" "Injecting variables"
3021
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
3022
+ - collapseable_section_end "injectvars"
3023
+ - set +e
3024
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_db2_GCLOUD_DEPLOY_credentialsKey")
3025
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-prod-db2-migrate --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
3026
+ - gcloud run jobs delete pan-test-app-prod-db2-migrate --project=google-project-id --region=europe-west6
3027
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/db2 --quiet --delete-tags
3028
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/db2 --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/db2@$version --quiet --delete-tags; done
3029
+ - echo 'Disabling component in Dependency Track'
3030
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/db2" "$CI_ENVIRONMENT_URL" || true
3031
+ - set -e
3032
+ environment:
3033
+ name: prod/db2
3034
+ action: stop
3035
+ rules:
3036
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
3037
+ when: on_success
3038
+ - when: manual
3039
+ if: $CI_COMMIT_TAG
3040
+ needs: []
3041
+ retry: *a1
3042
+ interruptible: true
3043
+ allow_failure: true
3044
+ api ๐Ÿ›ก audit:
3045
+ stage: test
3046
+ image: path/to/docker/jobs-default:the-version
3047
+ variables:
3048
+ KUBERNETES_CPU_REQUEST: '0.45'
3049
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3050
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3051
+ script:
3052
+ - collapseable_section_start "injectvars" "Injecting variables"
3053
+ - export APP_PATH="api"
3054
+ - collapseable_section_end "injectvars"
3055
+ - cd api
3056
+ - yarn npm audit --environment production
3057
+ rules:
3058
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3059
+ - if: $CI_MERGE_REQUEST_ID
3060
+ needs: []
3061
+ retry: *a1
3062
+ interruptible: true
3063
+ allow_failure: true
3064
+ api ๐Ÿ‘ฎ lint:
3065
+ stage: test
3066
+ image: path/to/docker/jobs-default:the-version
3067
+ variables:
3068
+ KUBERNETES_CPU_REQUEST: '0.45'
3069
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3070
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3071
+ script:
3072
+ - collapseable_section_start "injectvars" "Injecting variables"
3073
+ - export APP_PATH="api"
3074
+ - collapseable_section_end "injectvars"
3075
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3076
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3077
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3078
+ - collapseable_section_end "nodeinstall"
3079
+ - cd api
3080
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3081
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3082
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3083
+ - collapseable_section_end "nodeinstall"
3084
+ - collapseable_section_start "yarninstall" "Yarn install"
3085
+ - yarn install --immutable
3086
+ - collapseable_section_end "yarninstall"
3087
+ - yarn lint
3088
+ cache:
3089
+ - key: api-yarn
3090
+ policy: pull-push
3091
+ paths:
3092
+ - api/.yarn
3093
+ - key: api-node-modules
3094
+ policy: pull-push
3095
+ paths:
3096
+ - api/node_modules
3097
+ rules:
3098
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3099
+ - if: $CI_MERGE_REQUEST_ID
3100
+ needs: []
3101
+ retry: *a1
3102
+ interruptible: true
3103
+ api ๐Ÿงช test:
3104
+ stage: test
3105
+ image: path/to/docker/jobs-testing-chrome:the-version
3106
+ variables:
3107
+ KUBERNETES_CPU_REQUEST: '0.45'
3108
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3109
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3110
+ script:
3111
+ - collapseable_section_start "injectvars" "Injecting variables"
3112
+ - export APP_PATH="api"
3113
+ - collapseable_section_end "injectvars"
3114
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3115
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3116
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3117
+ - collapseable_section_end "nodeinstall"
3118
+ - cd api
3119
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3120
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3121
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3122
+ - collapseable_section_end "nodeinstall"
3123
+ - collapseable_section_start "yarninstall" "Yarn install"
3124
+ - yarn install --immutable
3125
+ - collapseable_section_end "yarninstall"
3126
+ - yarn test
3127
+ cache:
3128
+ - key: api-yarn
3129
+ policy: pull-push
3130
+ paths:
3131
+ - api/.yarn
3132
+ - key: api-node-modules
3133
+ policy: pull-push
3134
+ paths:
3135
+ - api/node_modules
3136
+ rules:
3137
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3138
+ - if: $CI_MERGE_REQUEST_ID
3139
+ needs: []
3140
+ retry: *a1
3141
+ interruptible: true
3142
+ 'api ๐Ÿ”จ app | dev ':
3143
+ stage: build
3144
+ image: path/to/docker/jobs-default:the-version
3145
+ variables:
3146
+ KUBERNETES_CPU_REQUEST: '0.45'
3147
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3148
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3149
+ script:
3150
+ - collapseable_section_start "injectvars" "Injecting variables"
3151
+ - export ENV_SHORT="dev"
3152
+ - export APP_DIR="api"
3153
+ - export ENV_TYPE="dev"
3154
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3155
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3156
+ - 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")"
3157
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3158
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3159
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3160
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3161
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
3162
+ - export DB_NAME="pan-test-app-dev-db1"
3163
+ - export DB_USER="my-user"
3164
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
3165
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
3166
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
3167
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
3168
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
3169
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
3170
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
3171
+ - export DATABASE_URL_2="postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename"
3172
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
3173
+ - collapseable_section_end "injectvars"
3174
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
3175
+ - |-
3176
+ cat <<EOF > api/.env
3177
+ ENV_SHORT=dev
3178
+ APP_DIR=api
3179
+ ENV_TYPE=dev
3180
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3181
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3182
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3183
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3184
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
3185
+ DB_NAME=pan-test-app-dev-db1
3186
+ DB_USER=my-user
3187
+ DB_PASSWORD=$(printf %s "$CL_dev_api_DB_PASSWORD" | escapeForDotEnv)
3188
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
3189
+ DATABASE_JDBC_URL=jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
3190
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
3191
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
3192
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
3193
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
3194
+ DATABASE_URL_2=postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename
3195
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
3196
+ EOF
3197
+ - collapseable_section_end "write-dotenv-api"
3198
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
3199
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3200
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3201
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3202
+ - collapseable_section_end "nodeinstall"
3203
+ - cd api
3204
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3205
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3206
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3207
+ - collapseable_section_end "nodeinstall"
3208
+ - collapseable_section_start "yarninstall" "Yarn install"
3209
+ - yarn install --immutable
3210
+ - collapseable_section_end "yarninstall"
3211
+ - yarn build:worker
3212
+ cache:
3213
+ - key: api-yarn
3214
+ policy: pull-push
3215
+ paths:
3216
+ - api/.yarn
3217
+ - key: api-node-modules
3218
+ policy: pull-push
3219
+ paths:
3220
+ - api/node_modules
3221
+ artifacts:
3222
+ paths:
3223
+ - api/__build_info.json
3224
+ - api/.next
3225
+ - api/dist
3226
+ exclude:
3227
+ - api/.env
3228
+ expire_in: 1 day
3229
+ when: always
3230
+ reports: {}
3231
+ rules:
3232
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3233
+ needs: []
3234
+ retry: *a1
3235
+ interruptible: true
3236
+ 'api ๐Ÿ”จ docker | dev ':
3237
+ stage: build
3238
+ image: path/to/docker/docker-build:the-version
3239
+ services:
3240
+ - name: docker:24.0.6-dind
3241
+ command:
3242
+ - --tls=false
3243
+ - --registry-mirror=https://mirror.gcr.io
3244
+ variables:
3245
+ DOCKER_HOST: tcp://docker:2375
3246
+ DOCKER_TLS_CERTDIR: ''
3247
+ DOCKER_DRIVER: overlay2
3248
+ DOCKER_BUILDKIT: '1'
3249
+ KUBERNETES_CPU_REQUEST: '0.45'
3250
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3251
+ KUBERNETES_MEMORY_LIMIT: 2Gi
3252
+ script:
3253
+ - collapseable_section_start "injectvars" "Injecting variables"
3254
+ - export APP_DIR="api"
3255
+ - export DOCKER_BUILD_CONTEXT="."
3256
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
3257
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
3258
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
3259
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3260
+ - |-
3261
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
3262
+ RUN yarn plugin import workspace-tools
3263
+ RUN yarn workspaces focus --production && yarn rebuild"
3264
+ - |-
3265
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
3266
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
3267
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
3268
+ COPY --chown=node:node .yarn /app/.yarn"
3269
+ - collapseable_section_end "injectvars"
3270
+ - ensureNodeDockerfile
3271
+ - collapseable_section_start "docker-login" "Docker Login"
3272
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
3273
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
3274
+ - collapseable_section_end "docker-login"
3275
+ - collapseable_section_start "docker-build" "Docker build"
3276
+ - 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
3277
+ - collapseable_section_end "docker-build"
3278
+ - collapseable_section_start "docker-push" "Docker push and tag"
3279
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
3280
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
3281
+ - docker push $DOCKER_CACHE_IMAGE
3282
+ - collapseable_section_end "docker-push"
3283
+ cache:
3284
+ - key: api-yarn
3285
+ policy: pull
3286
+ paths:
3287
+ - api/.yarn
3288
+ rules:
3289
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3290
+ needs:
3291
+ - 'api ๐Ÿ”จ app | dev '
3292
+ retry: *a1
3293
+ interruptible: true
3294
+ 'api ๐Ÿงพ sbom | dev ':
3295
+ stage: build
3296
+ image:
3297
+ name: aquasec/trivy:0.58.2
3298
+ entrypoint:
3299
+ - ''
3300
+ variables: {}
3301
+ script:
3302
+ - collapseable_section_start "injectvars" "Injecting variables"
3303
+ - collapseable_section_end "injectvars"
3304
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
3305
+ artifacts:
3306
+ paths:
3307
+ - __sbom.json
3308
+ rules:
3309
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3310
+ needs: []
3311
+ retry: *a1
3312
+ interruptible: true
3313
+ allow_failure: true
3314
+ 'api ๐Ÿš€ Deploy | dev ':
3315
+ stage: deploy dev
3316
+ image: path/to/docker/gcloud:the-version
3317
+ variables:
3318
+ KUBERNETES_CPU_REQUEST: '0.22'
3319
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3320
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3321
+ script:
3322
+ - collapseable_section_start "injectvars" "Injecting variables"
3323
+ - export ENV_SHORT="dev"
3324
+ - export APP_DIR="api"
3325
+ - export ENV_TYPE="dev"
3326
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3327
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3328
+ - 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")"
3329
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3330
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3331
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3332
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3333
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
3334
+ - export DB_NAME="pan-test-app-dev-db1"
3335
+ - export DB_USER="my-user"
3336
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
3337
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
3338
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
3339
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
3340
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
3341
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
3342
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
3343
+ - export DATABASE_URL_2="postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename"
3344
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
3345
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
3346
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
3347
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
3348
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3349
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
3350
+ - collapseable_section_end "injectvars"
3351
+ - collapseable_section_start "prepare" "Prepare..."
3352
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
3353
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
3354
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
3355
+ - collapseable_section_end "prepare"
3356
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
3357
+ - |
3358
+ cat > ____envvars.yaml <<EOF
3359
+ ENV_SHORT: |-
3360
+ dev
3361
+ APP_DIR: |-
3362
+ api
3363
+ ENV_TYPE: |-
3364
+ dev
3365
+ BUILD_INFO_BUILD_ID: |-
3366
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
3367
+ BUILD_INFO_BUILD_TIME: |-
3368
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
3369
+ BUILD_INFO_CURRENT_VERSION: |-
3370
+ $(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/^/ /')
3371
+ HOSTNAME: |-
3372
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3373
+ ROOT_URL: |-
3374
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3375
+ HOSTNAME_INTERNAL: |-
3376
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3377
+ ROOT_URL_INTERNAL: |-
3378
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3379
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
3380
+ projectId:region:instancename
3381
+ DB_NAME: |-
3382
+ pan-test-app-dev-db1
3383
+ DB_USER: |-
3384
+ my-user
3385
+ DB_PASSWORD: |-
3386
+ $(printf %s "$CL_dev_api_DB_PASSWORD" | sed '1!s/^/ /')
3387
+ DATABASE_URL: |-
3388
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
3389
+ DATABASE_JDBC_URL: |-
3390
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
3391
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
3392
+ google-project-id
3393
+ DEPLOY_CLOUD_RUN_REGION: |-
3394
+ europe-west6
3395
+ GCLOUD_RUN_canonicalHostSuffix: |-
3396
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
3397
+ DATABASE_URL_2: |-
3398
+ postgresql://my-user:$CL_dev_db2_DB_PASSWORD@localhost/pan-test-app-dev-db2?host=/cloudsql/projectId:region:instancename
3399
+ _ALL_ENV_VAR_KEYS: |-
3400
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
3401
+
3402
+ EOF
3403
+ - collapseable_section_end "writeenvvars"
3404
+ - collapseable_section_start "deploy" "Deploy to cloud run"
3405
+ - set +e
3406
+ - echo "ensuring Database..."
3407
+ - gcloud sql databases create pan-test-app-dev-db1 --instance=instancename --project projectId
3408
+ - set -e
3409
+ - 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 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-service-name=pan-test-app-dev-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
3410
+ - collapseable_section_end "deploy"
3411
+ - collapseable_section_start "cleanup" "Cleanup"
3412
+ - 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
3413
+ - 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
3414
+ - 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
3415
+ - collapseable_section_end "cleanup"
3416
+ - echo 'Uploading SBOM to Dependency Track'
3417
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
3418
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
3419
+ environment:
3420
+ name: dev/api
3421
+ url: $CL_GITLAB_ENVIRONMENT_URL
3422
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | dev '
3423
+ auto_stop_in: 4 weeks
3424
+ artifacts:
3425
+ reports:
3426
+ dotenv: gitlab_environment.env
3427
+ rules:
3428
+ - when: on_success
3429
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3430
+ needs:
3431
+ - job: api ๐Ÿ‘ฎ lint
3432
+ artifacts: false
3433
+ - job: 'api ๐Ÿ”จ app | dev '
3434
+ artifacts: false
3435
+ - job: 'api ๐Ÿ”จ docker | dev '
3436
+ artifacts: false
3437
+ - job: api ๐Ÿงช test
3438
+ artifacts: false
3439
+ - job: 'api ๐Ÿงพ sbom | dev '
3440
+ artifacts: true
3441
+ - job: api ๐Ÿ›ก audit
3442
+ artifacts: false
3443
+ retry: *a1
3444
+ interruptible: true
3445
+ allow_failure: false
3446
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | dev ':
3447
+ stage: stop dev
3448
+ image: path/to/docker/gcloud:the-version
3449
+ variables:
3450
+ KUBERNETES_CPU_REQUEST: '0.22'
3451
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3452
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3453
+ GIT_STRATEGY: none
3454
+ script:
3455
+ - collapseable_section_start "injectvars" "Injecting variables"
3456
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
3457
+ - collapseable_section_end "injectvars"
3458
+ - set +e
3459
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
3460
+ - gcloud run services delete pan-test-app-dev-api --project=google-project-id --region=europe-west6
3461
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
3462
+ - 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
3463
+ - echo 'Disabling component in Dependency Track'
3464
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
3465
+ - set -e
3466
+ environment:
3467
+ name: dev/api
3468
+ action: stop
3469
+ rules:
3470
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
3471
+ when: on_success
3472
+ - when: manual
3473
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
3474
+ needs: []
3475
+ retry: *a1
3476
+ interruptible: true
3477
+ allow_failure: true
3478
+ 'api ๐Ÿ”จ app | review ':
3479
+ stage: build
3480
+ image: path/to/docker/jobs-default:the-version
3481
+ variables:
3482
+ KUBERNETES_CPU_REQUEST: '0.45'
3483
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3484
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3485
+ script:
3486
+ - collapseable_section_start "injectvars" "Injecting variables"
3487
+ - export ENV_SHORT="review"
3488
+ - export APP_DIR="api"
3489
+ - export ENV_TYPE="review"
3490
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3491
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3492
+ - 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")"
3493
+ - export HOSTNAME="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3494
+ - 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)}')"
3495
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3496
+ - 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)}')"
3497
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
3498
+ - export DB_NAME="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"; })-db1"
3499
+ - export DB_USER="my-user"
3500
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
3501
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
3502
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
3503
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
3504
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
3505
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
3506
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
3507
+ - export DATABASE_URL_2="postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename"
3508
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
3509
+ - collapseable_section_end "injectvars"
3510
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
3511
+ - |-
3512
+ cat <<EOF > api/.env
3513
+ ENV_SHORT=review
3514
+ APP_DIR=api
3515
+ ENV_TYPE=review
3516
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3517
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3518
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3519
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3520
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
3521
+ DB_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"; })-db1" | escapeForDotEnv)
3522
+ DB_USER=my-user
3523
+ DB_PASSWORD=$(printf %s "$CL_review_api_DB_PASSWORD" | escapeForDotEnv)
3524
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
3525
+ DATABASE_JDBC_URL=jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
3526
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
3527
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
3528
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
3529
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
3530
+ DATABASE_URL_2=$(printf %s "postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename" | escapeForDotEnv)
3531
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
3532
+ EOF
3533
+ - collapseable_section_end "write-dotenv-api"
3534
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
3535
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3536
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3537
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3538
+ - collapseable_section_end "nodeinstall"
3539
+ - cd api
3540
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3541
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3542
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3543
+ - collapseable_section_end "nodeinstall"
3544
+ - collapseable_section_start "yarninstall" "Yarn install"
3545
+ - yarn install --immutable
3546
+ - collapseable_section_end "yarninstall"
3547
+ - yarn build:worker
3548
+ cache:
3549
+ - key: api-yarn
3550
+ policy: pull-push
3551
+ paths:
3552
+ - api/.yarn
3553
+ - key: api-node-modules
3554
+ policy: pull-push
3555
+ paths:
3556
+ - api/node_modules
3557
+ artifacts:
3558
+ paths:
3559
+ - api/__build_info.json
3560
+ - api/.next
3561
+ - api/dist
3562
+ exclude:
3563
+ - api/.env
3564
+ expire_in: 1 day
3565
+ when: always
3566
+ reports: {}
3567
+ rules:
3568
+ - if: $CI_MERGE_REQUEST_ID
3569
+ needs: []
3570
+ retry: *a1
3571
+ interruptible: true
3572
+ 'api ๐Ÿ”จ docker | review ':
3573
+ stage: build
3574
+ image: path/to/docker/docker-build:the-version
3575
+ services:
3576
+ - name: docker:24.0.6-dind
3577
+ command:
3578
+ - --tls=false
3579
+ - --registry-mirror=https://mirror.gcr.io
3580
+ variables:
3581
+ DOCKER_HOST: tcp://docker:2375
3582
+ DOCKER_TLS_CERTDIR: ''
3583
+ DOCKER_DRIVER: overlay2
3584
+ DOCKER_BUILDKIT: '1'
3585
+ KUBERNETES_CPU_REQUEST: '0.45'
3586
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3587
+ KUBERNETES_MEMORY_LIMIT: 2Gi
3588
+ script:
3589
+ - collapseable_section_start "injectvars" "Injecting variables"
3590
+ - export APP_DIR="api"
3591
+ - export DOCKER_BUILD_CONTEXT="."
3592
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
3593
+ - 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"; })"
3594
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
3595
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3596
+ - |-
3597
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
3598
+ RUN yarn plugin import workspace-tools
3599
+ RUN yarn workspaces focus --production && yarn rebuild"
3600
+ - |-
3601
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
3602
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
3603
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
3604
+ COPY --chown=node:node .yarn /app/.yarn"
3605
+ - collapseable_section_end "injectvars"
3606
+ - ensureNodeDockerfile
3607
+ - collapseable_section_start "docker-login" "Docker Login"
3608
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
3609
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
3610
+ - collapseable_section_end "docker-login"
3611
+ - collapseable_section_start "docker-build" "Docker build"
3612
+ - 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
3613
+ - collapseable_section_end "docker-build"
3614
+ - collapseable_section_start "docker-push" "Docker push and tag"
3615
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
3616
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
3617
+ - docker push $DOCKER_CACHE_IMAGE
3618
+ - collapseable_section_end "docker-push"
3619
+ cache:
3620
+ - key: api-yarn
3621
+ policy: pull
3622
+ paths:
3623
+ - api/.yarn
3624
+ rules:
3625
+ - if: $CI_MERGE_REQUEST_ID
3626
+ needs:
3627
+ - 'api ๐Ÿ”จ app | review '
3628
+ retry: *a1
3629
+ interruptible: true
3630
+ 'api ๐Ÿงพ sbom | review ':
3631
+ stage: build
3632
+ image:
3633
+ name: aquasec/trivy:0.58.2
3634
+ entrypoint:
3635
+ - ''
3636
+ variables: {}
3637
+ script:
3638
+ - collapseable_section_start "injectvars" "Injecting variables"
3639
+ - collapseable_section_end "injectvars"
3640
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
3641
+ artifacts:
3642
+ paths:
3643
+ - __sbom.json
3644
+ rules:
3645
+ - if: $CI_MERGE_REQUEST_ID
3646
+ needs: []
3647
+ retry: *a1
3648
+ interruptible: true
3649
+ allow_failure: true
3650
+ 'api ๐Ÿš€ Deploy | review ':
3651
+ stage: deploy review
3652
+ image: path/to/docker/gcloud:the-version
3653
+ variables:
3654
+ KUBERNETES_CPU_REQUEST: '0.22'
3655
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3656
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3657
+ script:
3658
+ - collapseable_section_start "injectvars" "Injecting variables"
3659
+ - export ENV_SHORT="review"
3660
+ - export APP_DIR="api"
3661
+ - export ENV_TYPE="review"
3662
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3663
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3664
+ - 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")"
3665
+ - export HOSTNAME="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3666
+ - 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)}')"
3667
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3668
+ - 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)}')"
3669
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
3670
+ - export DB_NAME="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"; })-db1"
3671
+ - export DB_USER="my-user"
3672
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
3673
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
3674
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
3675
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
3676
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
3677
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
3678
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
3679
+ - export DATABASE_URL_2="postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename"
3680
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
3681
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
3682
+ - 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"; })"
3683
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
3684
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3685
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
3686
+ - collapseable_section_end "injectvars"
3687
+ - collapseable_section_start "prepare" "Prepare..."
3688
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
3689
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
3690
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
3691
+ - collapseable_section_end "prepare"
3692
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
3693
+ - |
3694
+ cat > ____envvars.yaml <<EOF
3695
+ ENV_SHORT: |-
3696
+ review
3697
+ APP_DIR: |-
3698
+ api
3699
+ ENV_TYPE: |-
3700
+ review
3701
+ BUILD_INFO_BUILD_ID: |-
3702
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
3703
+ BUILD_INFO_BUILD_TIME: |-
3704
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
3705
+ BUILD_INFO_CURRENT_VERSION: |-
3706
+ $(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/^/ /')
3707
+ HOSTNAME: |-
3708
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3709
+ ROOT_URL: |-
3710
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3711
+ HOSTNAME_INTERNAL: |-
3712
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3713
+ ROOT_URL_INTERNAL: |-
3714
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
3715
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
3716
+ projectId:region:instancename
3717
+ DB_NAME: |-
3718
+ $(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"; })-db1" | sed '1!s/^/ /')
3719
+ DB_USER: |-
3720
+ my-user
3721
+ DB_PASSWORD: |-
3722
+ $(printf %s "$CL_review_api_DB_PASSWORD" | sed '1!s/^/ /')
3723
+ DATABASE_URL: |-
3724
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
3725
+ DATABASE_JDBC_URL: |-
3726
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
3727
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
3728
+ google-project-id
3729
+ DEPLOY_CLOUD_RUN_REGION: |-
3730
+ europe-west6
3731
+ GCLOUD_RUN_canonicalHostSuffix: |-
3732
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
3733
+ DATABASE_URL_2: |-
3734
+ $(printf %s "postgresql://my-user:$CL_review_db2_DB_PASSWORD@localhost/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"; })-db2?host=/cloudsql/projectId:region:instancename" | sed '1!s/^/ /')
3735
+ _ALL_ENV_VAR_KEYS: |-
3736
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
3737
+
3738
+ EOF
3739
+ - collapseable_section_end "writeenvvars"
3740
+ - collapseable_section_start "deploy" "Deploy to cloud run"
3741
+ - set +e
3742
+ - echo "ensuring Database..."
3743
+ - gcloud sql databases create 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"; })-db1 --instance=instancename --project projectId
3744
+ - set -e
3745
+ - 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 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-service-name=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
3746
+ - collapseable_section_end "deploy"
3747
+ - collapseable_section_start "cleanup" "Cleanup"
3748
+ - 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
3749
+ - 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
3750
+ - 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
3751
+ - set +e
3752
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
3753
+ - set -e
3754
+ - collapseable_section_end "cleanup"
3755
+ - echo 'Uploading SBOM to Dependency Track'
3756
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
3757
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
3758
+ environment:
3759
+ name: review/$CI_COMMIT_REF_NAME/api
3760
+ url: $CL_GITLAB_ENVIRONMENT_URL
3761
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | review '
3762
+ auto_stop_in: 1 week
3763
+ artifacts:
3764
+ reports:
3765
+ dotenv: gitlab_environment.env
3766
+ rules:
3767
+ - when: on_success
3768
+ if: $CI_MERGE_REQUEST_ID
3769
+ needs:
3770
+ - job: api ๐Ÿ‘ฎ lint
3771
+ artifacts: false
3772
+ - job: 'api ๐Ÿ”จ app | review '
3773
+ artifacts: false
3774
+ - job: 'api ๐Ÿ”จ docker | review '
3775
+ artifacts: false
3776
+ - job: api ๐Ÿงช test
3777
+ artifacts: false
3778
+ - job: 'api ๐Ÿงพ sbom | review '
3779
+ artifacts: true
3780
+ - job: api ๐Ÿ›ก audit
3781
+ artifacts: false
3782
+ retry: *a1
3783
+ interruptible: true
3784
+ allow_failure: false
3785
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | review ':
3786
+ stage: stop review
3787
+ image: path/to/docker/gcloud:the-version
3788
+ variables:
3789
+ KUBERNETES_CPU_REQUEST: '0.22'
3790
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3791
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3792
+ GIT_STRATEGY: none
3793
+ script:
3794
+ - collapseable_section_start "injectvars" "Injecting variables"
3795
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
3796
+ - collapseable_section_end "injectvars"
3797
+ - set +e
3798
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
3799
+ - 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
3800
+ - echo "deleting database 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"; })-db1..."
3801
+ - echo "๐Ÿ‘† this can take multiple attemps (3-5min), because google cloud run may still have a connection to the database after the cloud run service is shut down"
3802
+ - "\\n until gcloud sql databases delete 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\\"; })-db1 --instance=instancename --project projectId\\n do\\n echo \\"Trying again.\\"\\n sleep 10\\n done\\n "
3803
+ - 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
3804
+ - 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
3805
+ - set +e
3806
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
3807
+ - set -e
3808
+ - echo 'Disabling component in Dependency Track'
3809
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
3810
+ - set -e
3811
+ environment:
3812
+ name: review/$CI_COMMIT_REF_NAME/api
3813
+ action: stop
3814
+ rules:
3815
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
3816
+ when: on_success
3817
+ - when: manual
3818
+ if: $CI_MERGE_REQUEST_ID
3819
+ needs: []
3820
+ retry: *a1
3821
+ interruptible: true
3822
+ allow_failure: true
3823
+ 'api ๐Ÿ”จ app | stage ':
3824
+ stage: build
3825
+ image: path/to/docker/jobs-default:the-version
3826
+ variables:
3827
+ KUBERNETES_CPU_REQUEST: '0.45'
3828
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3829
+ KUBERNETES_MEMORY_LIMIT: 4Gi
3830
+ script:
3831
+ - collapseable_section_start "injectvars" "Injecting variables"
3832
+ - export ENV_SHORT="stage"
3833
+ - export APP_DIR="api"
3834
+ - export ENV_TYPE="stage"
3835
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3836
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3837
+ - 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")"
3838
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3839
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3840
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3841
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
3842
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
3843
+ - export DB_NAME="pan-test-app-stage-db1"
3844
+ - export DB_USER="my-user"
3845
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
3846
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
3847
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
3848
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
3849
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
3850
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
3851
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
3852
+ - export DATABASE_URL_2="postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename"
3853
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
3854
+ - collapseable_section_end "injectvars"
3855
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
3856
+ - |-
3857
+ cat <<EOF > api/.env
3858
+ ENV_SHORT=stage
3859
+ APP_DIR=api
3860
+ ENV_TYPE=stage
3861
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3862
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3863
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3864
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
3865
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
3866
+ DB_NAME=pan-test-app-stage-db1
3867
+ DB_USER=my-user
3868
+ DB_PASSWORD=$(printf %s "$CL_stage_api_DB_PASSWORD" | escapeForDotEnv)
3869
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
3870
+ DATABASE_JDBC_URL=jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
3871
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
3872
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
3873
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
3874
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
3875
+ DATABASE_URL_2=postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename
3876
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
3877
+ EOF
3878
+ - collapseable_section_end "write-dotenv-api"
3879
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
3880
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3881
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3882
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3883
+ - collapseable_section_end "nodeinstall"
3884
+ - cd api
3885
+ - collapseable_section_start "nodeinstall" "Ensure node version"
3886
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
3887
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
3888
+ - collapseable_section_end "nodeinstall"
3889
+ - collapseable_section_start "yarninstall" "Yarn install"
3890
+ - yarn install --immutable
3891
+ - collapseable_section_end "yarninstall"
3892
+ - yarn build:worker
3893
+ cache:
3894
+ - key: api-yarn
3895
+ policy: pull-push
3896
+ paths:
3897
+ - api/.yarn
3898
+ - key: api-node-modules
3899
+ policy: pull-push
3900
+ paths:
3901
+ - api/node_modules
3902
+ artifacts:
3903
+ paths:
3904
+ - api/__build_info.json
3905
+ - api/.next
3906
+ - api/dist
3907
+ exclude:
3908
+ - api/.env
3909
+ expire_in: 1 day
3910
+ when: always
3911
+ reports: {}
3912
+ rules:
3913
+ - if: $CI_COMMIT_TAG
3914
+ needs: []
3915
+ retry: *a1
3916
+ interruptible: true
3917
+ 'api ๐Ÿ”จ docker | stage ':
3918
+ stage: build
3919
+ image: path/to/docker/docker-build:the-version
3920
+ services:
3921
+ - name: docker:24.0.6-dind
3922
+ command:
3923
+ - --tls=false
3924
+ - --registry-mirror=https://mirror.gcr.io
3925
+ variables:
3926
+ DOCKER_HOST: tcp://docker:2375
3927
+ DOCKER_TLS_CERTDIR: ''
3928
+ DOCKER_DRIVER: overlay2
3929
+ DOCKER_BUILDKIT: '1'
3930
+ KUBERNETES_CPU_REQUEST: '0.45'
3931
+ KUBERNETES_MEMORY_REQUEST: 1Gi
3932
+ KUBERNETES_MEMORY_LIMIT: 2Gi
3933
+ script:
3934
+ - collapseable_section_start "injectvars" "Injecting variables"
3935
+ - export APP_DIR="api"
3936
+ - export DOCKER_BUILD_CONTEXT="."
3937
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
3938
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
3939
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
3940
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3941
+ - |-
3942
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
3943
+ RUN yarn plugin import workspace-tools
3944
+ RUN yarn workspaces focus --production && yarn rebuild"
3945
+ - |-
3946
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
3947
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
3948
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
3949
+ COPY --chown=node:node .yarn /app/.yarn"
3950
+ - collapseable_section_end "injectvars"
3951
+ - ensureNodeDockerfile
3952
+ - collapseable_section_start "docker-login" "Docker Login"
3953
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
3954
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
3955
+ - collapseable_section_end "docker-login"
3956
+ - collapseable_section_start "docker-build" "Docker build"
3957
+ - 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
3958
+ - collapseable_section_end "docker-build"
3959
+ - collapseable_section_start "docker-push" "Docker push and tag"
3960
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
3961
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
3962
+ - docker push $DOCKER_CACHE_IMAGE
3963
+ - collapseable_section_end "docker-push"
3964
+ cache:
3965
+ - key: api-yarn
3966
+ policy: pull
3967
+ paths:
3968
+ - api/.yarn
3969
+ rules:
3970
+ - if: $CI_COMMIT_TAG
3971
+ needs:
3972
+ - 'api ๐Ÿ”จ app | stage '
3973
+ retry: *a1
3974
+ interruptible: true
3975
+ 'api ๐Ÿงพ sbom | stage ':
3976
+ stage: build
3977
+ image:
3978
+ name: aquasec/trivy:0.58.2
3979
+ entrypoint:
3980
+ - ''
3981
+ variables: {}
3982
+ script:
3983
+ - collapseable_section_start "injectvars" "Injecting variables"
3984
+ - collapseable_section_end "injectvars"
3985
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
3986
+ artifacts:
3987
+ paths:
3988
+ - __sbom.json
3989
+ rules:
3990
+ - if: $CI_COMMIT_TAG
3991
+ needs: []
3992
+ retry: *a1
3993
+ interruptible: true
3994
+ allow_failure: true
3995
+ 'api ๐Ÿš€ Deploy | stage ':
3996
+ stage: deploy stage
3997
+ image: path/to/docker/gcloud:the-version
3998
+ variables:
3999
+ KUBERNETES_CPU_REQUEST: '0.22'
4000
+ KUBERNETES_MEMORY_REQUEST: 200Mi
4001
+ KUBERNETES_MEMORY_LIMIT: 400Mi
4002
+ script:
4003
+ - collapseable_section_start "injectvars" "Injecting variables"
4004
+ - export ENV_SHORT="stage"
4005
+ - export APP_DIR="api"
4006
+ - export ENV_TYPE="stage"
4007
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
4008
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
4009
+ - 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")"
4010
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4011
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4012
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4013
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4014
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
4015
+ - export DB_NAME="pan-test-app-stage-db1"
4016
+ - export DB_USER="my-user"
4017
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
4018
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
4019
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
4020
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
4021
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
4022
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
4023
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
4024
+ - export DATABASE_URL_2="postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename"
4025
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
4026
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
4027
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
4028
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
4029
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
4030
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
4031
+ - collapseable_section_end "injectvars"
4032
+ - collapseable_section_start "prepare" "Prepare..."
4033
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
4034
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
4035
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
4036
+ - collapseable_section_end "prepare"
4037
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
4038
+ - |
4039
+ cat > ____envvars.yaml <<EOF
4040
+ ENV_SHORT: |-
4041
+ stage
4042
+ APP_DIR: |-
4043
+ api
4044
+ ENV_TYPE: |-
4045
+ stage
4046
+ BUILD_INFO_BUILD_ID: |-
4047
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
4048
+ BUILD_INFO_BUILD_TIME: |-
4049
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
4050
+ BUILD_INFO_CURRENT_VERSION: |-
4051
+ $(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/^/ /')
4052
+ HOSTNAME: |-
4053
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4054
+ ROOT_URL: |-
4055
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4056
+ HOSTNAME_INTERNAL: |-
4057
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4058
+ ROOT_URL_INTERNAL: |-
4059
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4060
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
4061
+ projectId:region:instancename
4062
+ DB_NAME: |-
4063
+ pan-test-app-stage-db1
4064
+ DB_USER: |-
4065
+ my-user
4066
+ DB_PASSWORD: |-
4067
+ $(printf %s "$CL_stage_api_DB_PASSWORD" | sed '1!s/^/ /')
4068
+ DATABASE_URL: |-
4069
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
4070
+ DATABASE_JDBC_URL: |-
4071
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
4072
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
4073
+ google-project-id
4074
+ DEPLOY_CLOUD_RUN_REGION: |-
4075
+ europe-west6
4076
+ GCLOUD_RUN_canonicalHostSuffix: |-
4077
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
4078
+ DATABASE_URL_2: |-
4079
+ postgresql://my-user:$CL_stage_db2_DB_PASSWORD@localhost/pan-test-app-stage-db2?host=/cloudsql/projectId:region:instancename
4080
+ _ALL_ENV_VAR_KEYS: |-
4081
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
4082
+
4083
+ EOF
4084
+ - collapseable_section_end "writeenvvars"
4085
+ - collapseable_section_start "deploy" "Deploy to cloud run"
4086
+ - set +e
4087
+ - echo "ensuring Database..."
4088
+ - gcloud sql databases create pan-test-app-stage-db1 --instance=instancename --project projectId
4089
+ - set -e
4090
+ - 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 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-service-name=pan-test-app-stage-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
4091
+ - collapseable_section_end "deploy"
4092
+ - collapseable_section_start "cleanup" "Cleanup"
4093
+ - 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
4094
+ - 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
4095
+ - 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
4096
+ - collapseable_section_end "cleanup"
4097
+ - echo 'Uploading SBOM to Dependency Track'
4098
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
4099
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
4100
+ environment:
4101
+ name: stage/api
4102
+ url: $CL_GITLAB_ENVIRONMENT_URL
4103
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | stage '
4104
+ artifacts:
4105
+ reports:
4106
+ dotenv: gitlab_environment.env
4107
+ rules:
4108
+ - when: on_success
4109
+ if: $CI_COMMIT_TAG
4110
+ needs:
4111
+ - job: 'api ๐Ÿ”จ app | stage '
4112
+ artifacts: false
4113
+ - job: 'api ๐Ÿ”จ docker | stage '
4114
+ artifacts: false
4115
+ - job: 'api ๐Ÿงพ sbom | stage '
4116
+ artifacts: true
4117
+ retry: *a1
4118
+ interruptible: true
4119
+ allow_failure: false
4120
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | stage ':
4121
+ stage: stop stage
4122
+ image: path/to/docker/gcloud:the-version
4123
+ variables:
4124
+ KUBERNETES_CPU_REQUEST: '0.22'
4125
+ KUBERNETES_MEMORY_REQUEST: 200Mi
4126
+ KUBERNETES_MEMORY_LIMIT: 400Mi
4127
+ GIT_STRATEGY: none
4128
+ script:
4129
+ - collapseable_section_start "injectvars" "Injecting variables"
4130
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
4131
+ - collapseable_section_end "injectvars"
4132
+ - set +e
4133
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
4134
+ - gcloud run services delete pan-test-app-stage-api --project=google-project-id --region=europe-west6
4135
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
4136
+ - 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
4137
+ - echo 'Disabling component in Dependency Track'
4138
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
4139
+ - set -e
4140
+ environment:
4141
+ name: stage/api
4142
+ action: stop
4143
+ rules:
4144
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
4145
+ when: on_success
4146
+ - when: manual
4147
+ if: $CI_COMMIT_TAG
4148
+ needs: []
4149
+ retry: *a1
4150
+ interruptible: true
4151
+ allow_failure: true
4152
+ 'api ๐Ÿ”จ app | prod ':
4153
+ stage: build
4154
+ image: path/to/docker/jobs-default:the-version
4155
+ variables:
4156
+ KUBERNETES_CPU_REQUEST: '0.45'
4157
+ KUBERNETES_MEMORY_REQUEST: 1Gi
4158
+ KUBERNETES_MEMORY_LIMIT: 4Gi
4159
+ script:
4160
+ - collapseable_section_start "injectvars" "Injecting variables"
4161
+ - export ENV_SHORT="prod"
4162
+ - export APP_DIR="api"
4163
+ - export ENV_TYPE="prod"
4164
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
4165
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
4166
+ - 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")"
4167
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4168
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4169
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4170
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4171
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
4172
+ - export DB_NAME="pan-test-app-prod-db1"
4173
+ - export DB_USER="my-user"
4174
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
4175
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
4176
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
4177
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
4178
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
4179
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
4180
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
4181
+ - export DATABASE_URL_2="postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename"
4182
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
4183
+ - collapseable_section_end "injectvars"
4184
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
4185
+ - |-
4186
+ cat <<EOF > api/.env
4187
+ ENV_SHORT=prod
4188
+ APP_DIR=api
4189
+ ENV_TYPE=prod
4190
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
4191
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
4192
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
4193
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
4194
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
4195
+ DB_NAME=pan-test-app-prod-db1
4196
+ DB_USER=my-user
4197
+ DB_PASSWORD=$(printf %s "$CL_prod_api_DB_PASSWORD" | escapeForDotEnv)
4198
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
4199
+ DATABASE_JDBC_URL=jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
4200
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
4201
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
4202
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
4203
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
4204
+ DATABASE_URL_2=postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename
4205
+ _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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
4206
+ EOF
4207
+ - collapseable_section_end "write-dotenv-api"
4208
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
4209
+ - collapseable_section_start "nodeinstall" "Ensure node version"
4210
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
4211
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
4212
+ - collapseable_section_end "nodeinstall"
4213
+ - cd api
4214
+ - collapseable_section_start "nodeinstall" "Ensure node version"
4215
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
4216
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
4217
+ - collapseable_section_end "nodeinstall"
4218
+ - collapseable_section_start "yarninstall" "Yarn install"
4219
+ - yarn install --immutable
4220
+ - collapseable_section_end "yarninstall"
4221
+ - yarn build:worker
4222
+ cache:
4223
+ - key: api-yarn
4224
+ policy: pull-push
4225
+ paths:
4226
+ - api/.yarn
4227
+ - key: api-node-modules
4228
+ policy: pull-push
4229
+ paths:
4230
+ - api/node_modules
4231
+ artifacts:
4232
+ paths:
4233
+ - api/__build_info.json
4234
+ - api/.next
4235
+ - api/dist
4236
+ exclude:
4237
+ - api/.env
4238
+ expire_in: 1 day
4239
+ when: always
4240
+ reports: {}
4241
+ rules:
4242
+ - if: $CI_COMMIT_TAG
4243
+ needs: []
4244
+ retry: *a1
4245
+ interruptible: true
4246
+ 'api ๐Ÿ”จ docker | prod ':
4247
+ stage: build
4248
+ image: path/to/docker/docker-build:the-version
4249
+ services:
4250
+ - name: docker:24.0.6-dind
4251
+ command:
4252
+ - --tls=false
4253
+ - --registry-mirror=https://mirror.gcr.io
4254
+ variables:
4255
+ DOCKER_HOST: tcp://docker:2375
4256
+ DOCKER_TLS_CERTDIR: ''
4257
+ DOCKER_DRIVER: overlay2
4258
+ DOCKER_BUILDKIT: '1'
4259
+ KUBERNETES_CPU_REQUEST: '0.45'
4260
+ KUBERNETES_MEMORY_REQUEST: 1Gi
4261
+ KUBERNETES_MEMORY_LIMIT: 2Gi
4262
+ script:
4263
+ - collapseable_section_start "injectvars" "Injecting variables"
4264
+ - export APP_DIR="api"
4265
+ - export DOCKER_BUILD_CONTEXT="."
4266
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
4267
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
4268
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
4269
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
4270
+ - |-
4271
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
4272
+ RUN yarn plugin import workspace-tools
4273
+ RUN yarn workspaces focus --production && yarn rebuild"
4274
+ - |-
4275
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
4276
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
4277
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
4278
+ COPY --chown=node:node .yarn /app/.yarn"
4279
+ - collapseable_section_end "injectvars"
4280
+ - ensureNodeDockerfile
4281
+ - collapseable_section_start "docker-login" "Docker Login"
4282
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
4283
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
4284
+ - collapseable_section_end "docker-login"
4285
+ - collapseable_section_start "docker-build" "Docker build"
4286
+ - 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
4287
+ - collapseable_section_end "docker-build"
4288
+ - collapseable_section_start "docker-push" "Docker push and tag"
4289
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
4290
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
4291
+ - docker push $DOCKER_CACHE_IMAGE
4292
+ - collapseable_section_end "docker-push"
4293
+ cache:
4294
+ - key: api-yarn
4295
+ policy: pull
4296
+ paths:
4297
+ - api/.yarn
4298
+ rules:
4299
+ - if: $CI_COMMIT_TAG
4300
+ needs:
4301
+ - 'api ๐Ÿ”จ app | prod '
4302
+ retry: *a1
4303
+ interruptible: true
4304
+ 'api ๐Ÿงพ sbom | prod ':
4305
+ stage: build
4306
+ image:
4307
+ name: aquasec/trivy:0.58.2
4308
+ entrypoint:
4309
+ - ''
4310
+ variables: {}
4311
+ script:
4312
+ - collapseable_section_start "injectvars" "Injecting variables"
4313
+ - collapseable_section_end "injectvars"
4314
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
4315
+ artifacts:
4316
+ paths:
4317
+ - __sbom.json
4318
+ rules:
4319
+ - if: $CI_COMMIT_TAG
4320
+ needs: []
4321
+ retry: *a1
4322
+ interruptible: true
4323
+ allow_failure: true
4324
+ 'api ๐Ÿš€ Deploy | prod ':
4325
+ stage: deploy prod
4326
+ image: path/to/docker/gcloud:the-version
4327
+ variables:
4328
+ KUBERNETES_CPU_REQUEST: '0.22'
4329
+ KUBERNETES_MEMORY_REQUEST: 200Mi
4330
+ KUBERNETES_MEMORY_LIMIT: 400Mi
4331
+ script:
4332
+ - collapseable_section_start "injectvars" "Injecting variables"
4333
+ - export ENV_SHORT="prod"
4334
+ - export APP_DIR="api"
4335
+ - export ENV_TYPE="prod"
4336
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
4337
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
4338
+ - 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")"
4339
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4340
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4341
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4342
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
4343
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
4344
+ - export DB_NAME="pan-test-app-prod-db1"
4345
+ - export DB_USER="my-user"
4346
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
4347
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
4348
+ - export DATABASE_JDBC_URL="jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD"
4349
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
4350
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
4351
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
4352
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
4353
+ - export DATABASE_URL_2="postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename"
4354
+ - 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\\",\\"CLOUD_SQL_INSTANCE_CONNECTION_NAME\\",\\"DB_NAME\\",\\"DB_USER\\",\\"DB_PASSWORD\\",\\"DATABASE_URL\\",\\"DATABASE_JDBC_URL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"DATABASE_URL_2\\"]"
4355
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
4356
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
4357
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
4358
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
4359
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
4360
+ - collapseable_section_end "injectvars"
4361
+ - collapseable_section_start "prepare" "Prepare..."
4362
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
4363
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
4364
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
4365
+ - collapseable_section_end "prepare"
4366
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
4367
+ - |
4368
+ cat > ____envvars.yaml <<EOF
4369
+ ENV_SHORT: |-
4370
+ prod
4371
+ APP_DIR: |-
4372
+ api
4373
+ ENV_TYPE: |-
4374
+ prod
4375
+ BUILD_INFO_BUILD_ID: |-
4376
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
4377
+ BUILD_INFO_BUILD_TIME: |-
4378
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
4379
+ BUILD_INFO_CURRENT_VERSION: |-
4380
+ $(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/^/ /')
4381
+ HOSTNAME: |-
4382
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4383
+ ROOT_URL: |-
4384
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4385
+ HOSTNAME_INTERNAL: |-
4386
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4387
+ ROOT_URL_INTERNAL: |-
4388
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
4389
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
4390
+ projectId:region:instancename
4391
+ DB_NAME: |-
4392
+ pan-test-app-prod-db1
4393
+ DB_USER: |-
4394
+ my-user
4395
+ DB_PASSWORD: |-
4396
+ $(printf %s "$CL_prod_api_DB_PASSWORD" | sed '1!s/^/ /')
4397
+ DATABASE_URL: |-
4398
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
4399
+ DATABASE_JDBC_URL: |-
4400
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
4401
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
4402
+ google-project-id
4403
+ DEPLOY_CLOUD_RUN_REGION: |-
4404
+ europe-west6
4405
+ GCLOUD_RUN_canonicalHostSuffix: |-
4406
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
4407
+ DATABASE_URL_2: |-
4408
+ postgresql://my-user:$CL_prod_db2_DB_PASSWORD@localhost/pan-test-app-prod-db2?host=/cloudsql/projectId:region:instancename
4409
+ _ALL_ENV_VAR_KEYS: |-
4410
+ ["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","CLOUD_SQL_INSTANCE_CONNECTION_NAME","DB_NAME","DB_USER","DB_PASSWORD","DATABASE_URL","DATABASE_JDBC_URL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","DATABASE_URL_2"]
4411
+
4412
+ EOF
4413
+ - collapseable_section_end "writeenvvars"
4414
+ - collapseable_section_start "deploy" "Deploy to cloud run"
4415
+ - set +e
4416
+ - echo "ensuring Database..."
4417
+ - gcloud sql databases create pan-test-app-prod-db1 --instance=instancename --project projectId
4418
+ - set -e
4419
+ - 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 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-service-name=pan-test-app-prod-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
4420
+ - collapseable_section_end "deploy"
4421
+ - collapseable_section_start "cleanup" "Cleanup"
4422
+ - 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
4423
+ - 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
4424
+ - 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
4425
+ - collapseable_section_end "cleanup"
4426
+ - echo 'Uploading SBOM to Dependency Track'
4427
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
4428
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
4429
+ environment:
4430
+ name: prod/api
4431
+ url: $CL_GITLAB_ENVIRONMENT_URL
4432
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | prod '
4433
+ artifacts:
4434
+ reports:
4435
+ dotenv: gitlab_environment.env
4436
+ rules:
4437
+ - when: manual
4438
+ if: $CI_COMMIT_TAG
4439
+ needs:
4440
+ - job: 'api ๐Ÿ”จ app | prod '
4441
+ artifacts: false
4442
+ - job: 'api ๐Ÿ”จ docker | prod '
4443
+ artifacts: false
4444
+ - job: 'api ๐Ÿงพ sbom | prod '
4445
+ artifacts: true
4446
+ retry: *a1
4447
+ interruptible: true
4448
+ allow_failure: true
4449
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | prod ':
4450
+ stage: stop prod
4451
+ image: path/to/docker/gcloud:the-version
4452
+ variables:
4453
+ KUBERNETES_CPU_REQUEST: '0.22'
4454
+ KUBERNETES_MEMORY_REQUEST: 200Mi
4455
+ KUBERNETES_MEMORY_LIMIT: 400Mi
4456
+ GIT_STRATEGY: none
4457
+ script:
4458
+ - collapseable_section_start "injectvars" "Injecting variables"
4459
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
4460
+ - collapseable_section_end "injectvars"
4461
+ - set +e
4462
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
4463
+ - gcloud run services delete pan-test-app-prod-api --project=google-project-id --region=europe-west6
4464
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
4465
+ - 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
4466
+ - echo 'Disabling component in Dependency Track'
4467
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
4468
+ - set -e
4469
+ environment:
4470
+ name: prod/api
4471
+ action: stop
4472
+ rules:
4473
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
4474
+ when: on_success
4475
+ - when: manual
4476
+ if: $CI_COMMIT_TAG
4477
+ needs: []
4478
+ retry: *a1
4479
+ interruptible: true
4480
+ allow_failure: true
4481
+ create release:
4482
+ stage: release
4483
+ image: path/to/docker/semantic-release:the-version
4484
+ script:
4485
+ - semanticRelease
4486
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
4487
+ rules:
4488
+ - &a2
4489
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
4490
+ when: never
4491
+ - &a3
4492
+ if: $CI_PIPELINE_SOURCE == "schedule"
4493
+ when: never
4494
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $AUTO_RELEASE == "true"
4495
+ when: on_success
4496
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
4497
+ when: manual
4498
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
4499
+ when: manual
4500
+ โš ๏ธ force create release:
4501
+ stage: release
4502
+ image: path/to/docker/semantic-release:the-version
4503
+ script:
4504
+ - semanticRelease
4505
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
4506
+ rules:
4507
+ - *a2
4508
+ - *a3
4509
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
4510
+ when: manual
4511
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
4512
+ when: manual
4513
+ needs: []
4514
+ "
4515
+ `;