@catladder/pipeline 1.162.0 โ†’ 1.163.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +15 -1
  2. package/dist/build/types.d.ts +6 -0
  3. package/dist/bundles/catladder-gitlab/index.js +2 -2
  4. package/dist/constants.js +1 -1
  5. package/dist/pipeline/generatePipelineFiles.d.ts +38 -0
  6. package/dist/pipeline/generatePipelineFiles.js +44 -23
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/examples/__snapshots__/cloud-run-memory-limit.test.ts.snap +1341 -0
  9. package/examples/__snapshots__/cloud-run-meteor-with-worker.test.ts.snap +1325 -0
  10. package/examples/__snapshots__/cloud-run-no-cpu-throttling.test.ts.snap +1341 -0
  11. package/examples/__snapshots__/cloud-run-no-service.test.ts.snap +1393 -0
  12. package/examples/__snapshots__/cloud-run-non-public.test.ts.snap +1341 -0
  13. package/examples/__snapshots__/cloud-run-post-stop-job.test.ts.snap +1352 -0
  14. package/examples/__snapshots__/cloud-run-service-gen2.test.ts.snap +1341 -0
  15. package/examples/__snapshots__/cloud-run-service-increase-timout.test.ts.snap +1341 -0
  16. package/examples/__snapshots__/cloud-run-service-with-volumes.test.ts.snap +1385 -0
  17. package/examples/__snapshots__/cloud-run-storybook.test.ts.snap +1233 -4
  18. package/examples/__snapshots__/cloud-run-with-ngnix.test.ts.snap +1349 -4
  19. package/examples/__snapshots__/cloud-run-with-sql-reuse-db.test.ts.snap +2825 -0
  20. package/examples/__snapshots__/cloud-run-with-sql.test.ts.snap +2572 -0
  21. package/examples/__snapshots__/cloud-run-with-worker.test.ts.snap +1349 -0
  22. package/examples/__snapshots__/custom-build-job-with-tests.test.ts.snap +1196 -0
  23. package/examples/__snapshots__/custom-build-job.test.ts.snap +1085 -0
  24. package/examples/__snapshots__/custom-deploy.test.ts.snap +1103 -0
  25. package/examples/__snapshots__/custom-envs.test.ts.snap +709 -0
  26. package/examples/__snapshots__/custom-sbom-java.test.ts.snap +1093 -0
  27. package/examples/__snapshots__/git-submodule.test.ts.snap +1342 -0
  28. package/examples/__snapshots__/kubernetes-application-customization.test.ts.snap +1778 -0
  29. package/examples/__snapshots__/kubernetes-with-cloud-sql-legacy.test.ts.snap +1790 -0
  30. package/examples/__snapshots__/kubernetes-with-cloud-sql.test.ts.snap +1798 -0
  31. package/examples/__snapshots__/kubernetes-with-jobs.test.ts.snap +3352 -0
  32. package/examples/__snapshots__/kubernetes-with-mongodb.test.ts.snap +1902 -0
  33. package/examples/__snapshots__/local-dot-env.test.ts.snap +1341 -0
  34. package/examples/__snapshots__/meteor-kubernetes.test.ts.snap +1839 -0
  35. package/examples/__snapshots__/multiline-var.test.ts.snap +3376 -0
  36. package/examples/__snapshots__/native-app.test.ts.snap +2149 -0
  37. package/examples/__snapshots__/node-build-with-custom-image.test.ts.snap +1341 -0
  38. package/examples/__snapshots__/node-build-with-docker-additions.test.ts.snap +1349 -0
  39. package/examples/__snapshots__/rails-k8s-with-worker.test.ts.snap +1470 -0
  40. package/examples/__snapshots__/wait-for-other-deploy.test.ts.snap +1275 -0
  41. package/examples/__utils__/helpers.ts +14 -1
  42. package/examples/cloud-run-memory-limit.test.ts +9 -1
  43. package/examples/cloud-run-meteor-with-worker.test.ts +9 -1
  44. package/examples/cloud-run-no-cpu-throttling.test.ts +9 -1
  45. package/examples/cloud-run-no-service.test.ts +9 -1
  46. package/examples/cloud-run-non-public.test.ts +9 -1
  47. package/examples/cloud-run-post-stop-job.test.ts +9 -1
  48. package/examples/cloud-run-service-gen2.test.ts +9 -1
  49. package/examples/cloud-run-service-increase-timout.test.ts +9 -1
  50. package/examples/cloud-run-service-with-volumes.test.ts +9 -1
  51. package/examples/cloud-run-storybook.test.ts +9 -1
  52. package/examples/cloud-run-storybook.ts +9 -1
  53. package/examples/cloud-run-with-ngnix.test.ts +9 -1
  54. package/examples/cloud-run-with-ngnix.ts +5 -1
  55. package/examples/cloud-run-with-sql-reuse-db.test.ts +9 -1
  56. package/examples/cloud-run-with-sql.test.ts +9 -1
  57. package/examples/cloud-run-with-worker.test.ts +9 -1
  58. package/examples/custom-build-job-with-tests.test.ts +9 -1
  59. package/examples/custom-build-job.test.ts +9 -1
  60. package/examples/custom-deploy.test.ts +9 -1
  61. package/examples/custom-envs.test.ts +9 -1
  62. package/examples/custom-sbom-java.test.ts +9 -1
  63. package/examples/git-submodule.test.ts +9 -1
  64. package/examples/kubernetes-application-customization.test.ts +9 -1
  65. package/examples/kubernetes-with-cloud-sql-legacy.test.ts +9 -1
  66. package/examples/kubernetes-with-cloud-sql.test.ts +9 -1
  67. package/examples/kubernetes-with-jobs.test.ts +9 -1
  68. package/examples/kubernetes-with-mongodb.test.ts +9 -1
  69. package/examples/local-dot-env.test.ts +9 -1
  70. package/examples/meteor-kubernetes.test.ts +9 -1
  71. package/examples/multiline-var.test.ts +9 -1
  72. package/examples/native-app.test.ts +9 -1
  73. package/examples/node-build-with-custom-image.test.ts +9 -1
  74. package/examples/node-build-with-docker-additions.test.ts +9 -1
  75. package/examples/rails-k8s-with-worker.test.ts +9 -1
  76. package/examples/wait-for-other-deploy.test.ts +9 -1
  77. package/package.json +4 -3
  78. package/scripts/generate-examples-test.ts +7 -5
  79. package/src/build/types.ts +6 -0
  80. package/src/pipeline/generatePipelineFiles.ts +61 -36
@@ -1,5 +1,2830 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`matches snapshot for cloud-run-memory-limit local pipeline YAML 1`] = `
4
+ "image: path/to/docker/jobs-default:the-version
5
+ stages:
6
+ - setup
7
+ - setup dev
8
+ - setup review
9
+ - setup stage
10
+ - setup prod
11
+ - test
12
+ - test dev
13
+ - test review
14
+ - test stage
15
+ - test prod
16
+ - build
17
+ - build dev
18
+ - build review
19
+ - build stage
20
+ - build prod
21
+ - deploy
22
+ - deploy dev
23
+ - deploy review
24
+ - deploy stage
25
+ - deploy prod
26
+ - verify
27
+ - verify dev
28
+ - verify review
29
+ - verify stage
30
+ - verify prod
31
+ - rollback
32
+ - rollback dev
33
+ - rollback review
34
+ - rollback stage
35
+ - rollback prod
36
+ - stop
37
+ - stop dev
38
+ - stop review
39
+ - stop stage
40
+ - stop prod
41
+ - release
42
+ variables:
43
+ FF_USE_FASTZIP: 'true'
44
+ ARTIFACT_COMPRESSION_LEVEL: fast
45
+ CACHE_COMPRESSION_LEVEL: fast
46
+ TRANSFER_METER_FREQUENCY: 5s
47
+ GIT_DEPTH: '1'
48
+ api ๐Ÿ›ก audit:
49
+ stage: test
50
+ image: path/to/docker/jobs-default:the-version
51
+ variables:
52
+ KUBERNETES_CPU_REQUEST: '0.45'
53
+ KUBERNETES_MEMORY_REQUEST: 1Gi
54
+ KUBERNETES_MEMORY_LIMIT: 4Gi
55
+ script:
56
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
57
+ - export APP_PATH="api"
58
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
59
+ - cd api
60
+ - yarn npm audit --environment production
61
+ rules:
62
+ - when: never
63
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
64
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
65
+ - if: $CI_MERGE_REQUEST_ID
66
+ needs: []
67
+ retry: &a1
68
+ max: 2
69
+ when:
70
+ - runner_system_failure
71
+ - stuck_or_timeout_failure
72
+ interruptible: true
73
+ allow_failure: true
74
+ api ๐Ÿ‘ฎ lint:
75
+ stage: test
76
+ image: path/to/docker/jobs-default:the-version
77
+ variables:
78
+ KUBERNETES_CPU_REQUEST: '0.45'
79
+ KUBERNETES_MEMORY_REQUEST: 1Gi
80
+ KUBERNETES_MEMORY_LIMIT: 4Gi
81
+ script:
82
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
83
+ - export APP_PATH="api"
84
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
85
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
86
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
87
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
88
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
89
+ - cd api
90
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
91
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
92
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
93
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
94
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
95
+ - yarn install --immutable
96
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
97
+ - yarn lint
98
+ cache:
99
+ - key: api-yarn
100
+ policy: pull-push
101
+ paths:
102
+ - api/.yarn
103
+ - key: api-node-modules
104
+ policy: pull-push
105
+ paths:
106
+ - api/node_modules
107
+ rules:
108
+ - when: never
109
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
110
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
111
+ - if: $CI_MERGE_REQUEST_ID
112
+ needs: []
113
+ retry: *a1
114
+ interruptible: true
115
+ api ๐Ÿงช test:
116
+ stage: test
117
+ image: path/to/docker/jobs-testing-chrome:the-version
118
+ variables:
119
+ KUBERNETES_CPU_REQUEST: '0.45'
120
+ KUBERNETES_MEMORY_REQUEST: 1Gi
121
+ KUBERNETES_MEMORY_LIMIT: 4Gi
122
+ script:
123
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
124
+ - export APP_PATH="api"
125
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
126
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
127
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
128
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
129
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
130
+ - cd api
131
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
132
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
133
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
134
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
135
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
136
+ - yarn install --immutable
137
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
138
+ - yarn test
139
+ cache:
140
+ - key: api-yarn
141
+ policy: pull-push
142
+ paths:
143
+ - api/.yarn
144
+ - key: api-node-modules
145
+ policy: pull-push
146
+ paths:
147
+ - api/node_modules
148
+ rules:
149
+ - when: never
150
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
151
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
152
+ - if: $CI_MERGE_REQUEST_ID
153
+ needs: []
154
+ retry: *a1
155
+ interruptible: true
156
+ 'api ๐Ÿ”จ app | dev ':
157
+ stage: build
158
+ image: path/to/docker/jobs-default:the-version
159
+ variables:
160
+ KUBERNETES_CPU_REQUEST: '0.45'
161
+ KUBERNETES_MEMORY_REQUEST: 1Gi
162
+ KUBERNETES_MEMORY_LIMIT: 4Gi
163
+ script:
164
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
165
+ - export ENV_SHORT="dev"
166
+ - export APP_DIR="api"
167
+ - export ENV_TYPE="dev"
168
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
169
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
170
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
171
+ - export HOST="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
172
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
173
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
174
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
175
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
176
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
177
+ - export DB_NAME="pan-test-app-dev-api"
178
+ - export DB_USER="my-user"
179
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
180
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
181
+ - 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"
182
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
183
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
184
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
185
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
186
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
187
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
188
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
189
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
190
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
191
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
192
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
193
+ - cd api
194
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
195
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
196
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
197
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
198
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
199
+ - yarn install --immutable
200
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
201
+ - yarn build
202
+ cache:
203
+ - key: api-yarn
204
+ policy: pull-push
205
+ paths:
206
+ - api/.yarn
207
+ - key: api-node-modules
208
+ policy: pull-push
209
+ paths:
210
+ - api/node_modules
211
+ - key: api-next-cache
212
+ policy: pull-push
213
+ paths:
214
+ - api/.next/cache
215
+ artifacts:
216
+ paths:
217
+ - api/__build_info.json
218
+ - api/.next
219
+ - api/dist
220
+ expire_in: 1 day
221
+ when: always
222
+ reports: {}
223
+ rules:
224
+ - when: never
225
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
226
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
227
+ needs: []
228
+ retry: *a1
229
+ interruptible: true
230
+ 'api ๐Ÿ”จ docker | dev ':
231
+ stage: build
232
+ image: path/to/docker/docker-build:the-version
233
+ services:
234
+ - name: docker:24.0.6-dind
235
+ command:
236
+ - --tls=false
237
+ variables:
238
+ DOCKER_HOST: tcp://0.0.0.0:2375
239
+ DOCKER_TLS_CERTDIR: ''
240
+ DOCKER_DRIVER: overlay2
241
+ DOCKER_BUILDKIT: '1'
242
+ KUBERNETES_CPU_REQUEST: '0.45'
243
+ KUBERNETES_MEMORY_REQUEST: 1Gi
244
+ KUBERNETES_MEMORY_LIMIT: 2Gi
245
+ script:
246
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
247
+ - export APP_DIR="api"
248
+ - export DOCKER_BUILD_CONTEXT="."
249
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
250
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
251
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
252
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
253
+ - |-
254
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
255
+ RUN yarn plugin import workspace-tools
256
+ RUN yarn workspaces focus --production && yarn rebuild"
257
+ - |-
258
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
259
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
260
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
261
+ COPY --chown=node:node .yarn /app/.yarn"
262
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
263
+ - ensureNodeDockerfile
264
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
265
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
266
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
267
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
268
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
269
+ - 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
270
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
271
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
272
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
273
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
274
+ - docker push $DOCKER_CACHE_IMAGE
275
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
276
+ cache:
277
+ - key: api-yarn
278
+ policy: pull
279
+ paths:
280
+ - api/.yarn
281
+ rules:
282
+ - when: never
283
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
284
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
285
+ needs:
286
+ - 'api ๐Ÿ”จ app | dev '
287
+ retry: *a1
288
+ interruptible: true
289
+ 'api ๐Ÿงพ sbom | dev ':
290
+ stage: build
291
+ image: aquasec/trivy:0.38.3
292
+ variables: {}
293
+ script:
294
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
295
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
296
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
297
+ artifacts:
298
+ paths:
299
+ - __sbom.json
300
+ rules:
301
+ - when: never
302
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
303
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
304
+ needs: []
305
+ retry: *a1
306
+ interruptible: true
307
+ allow_failure: true
308
+ 'api ๐Ÿš€ Deploy | dev ':
309
+ stage: deploy dev
310
+ image: path/to/docker/gcloud:the-version
311
+ variables:
312
+ KUBERNETES_CPU_REQUEST: '0.22'
313
+ KUBERNETES_MEMORY_REQUEST: 200Mi
314
+ KUBERNETES_MEMORY_LIMIT: 400Mi
315
+ script:
316
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
317
+ - export ENV_SHORT="dev"
318
+ - export APP_DIR="api"
319
+ - export ENV_TYPE="dev"
320
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
321
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
322
+ - 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")"
323
+ - export HOST="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
324
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
325
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
326
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
327
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
328
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
329
+ - export DB_NAME="pan-test-app-dev-api"
330
+ - export DB_USER="my-user"
331
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
332
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
333
+ - 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"
334
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
335
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
336
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
337
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
338
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
339
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
340
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
341
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
342
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
343
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
344
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
345
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
346
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
347
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
348
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
349
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
350
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
351
+ - |
352
+ cat > ____envvars.yaml <<EOF
353
+ ENV_SHORT: |-
354
+ dev
355
+ APP_DIR: |-
356
+ api
357
+ ENV_TYPE: |-
358
+ dev
359
+ BUILD_INFO_BUILD_ID: |-
360
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
361
+ BUILD_INFO_BUILD_TIME: |-
362
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
363
+ BUILD_INFO_CURRENT_VERSION: |-
364
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
365
+ HOST: |-
366
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
367
+ ROOT_URL: |-
368
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
369
+ HOST_INTERNAL: |-
370
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
371
+ HOST_CANONICAL: |-
372
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
373
+ ROOT_URL_INTERNAL: |-
374
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
375
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
376
+ projectId:region:instancename
377
+ DB_NAME: |-
378
+ pan-test-app-dev-api
379
+ DB_USER: |-
380
+ my-user
381
+ DB_PASSWORD: |-
382
+ $(printf %s "$CL_dev_api_DB_PASSWORD" | sed 's/^/ /')
383
+ DATABASE_URL: |-
384
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
385
+ DATABASE_JDBC_URL: |-
386
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
387
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
388
+ google-project-id
389
+ DEPLOY_CLOUD_RUN_REGION: |-
390
+ europe-west6
391
+ GCLOUD_RUN_canonicalHostSuffix: |-
392
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
393
+ _ALL_ENV_VAR_KEYS: |-
394
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
395
+
396
+ EOF
397
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
398
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
399
+ - set +e
400
+ - echo "ensuring Database..."
401
+ - gcloud sql databases create pan-test-app-dev-api --instance=instancename --project projectId
402
+ - set -e
403
+ - 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
404
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
405
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
406
+ - 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
407
+ - 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
408
+ - 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
409
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
410
+ - echo 'Uploading SBOM to Dependency Track'
411
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
412
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
413
+ environment:
414
+ name: dev/api
415
+ url: $CL_GITLAB_ENVIRONMENT_URL
416
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | dev '
417
+ auto_stop_in: 4 weeks
418
+ artifacts:
419
+ reports:
420
+ dotenv: gitlab_environment.env
421
+ rules:
422
+ - when: never
423
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
424
+ - when: on_success
425
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
426
+ needs:
427
+ - job: api ๐Ÿ‘ฎ lint
428
+ artifacts: false
429
+ - job: 'api ๐Ÿ”จ app | dev '
430
+ artifacts: false
431
+ - job: 'api ๐Ÿ”จ docker | dev '
432
+ artifacts: false
433
+ - job: api ๐Ÿงช test
434
+ artifacts: false
435
+ - job: 'api ๐Ÿงพ sbom | dev '
436
+ artifacts: true
437
+ - job: api ๐Ÿ›ก audit
438
+ artifacts: false
439
+ retry: *a1
440
+ interruptible: true
441
+ allow_failure: false
442
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | dev ':
443
+ stage: stop dev
444
+ image: path/to/docker/gcloud:the-version
445
+ variables:
446
+ KUBERNETES_CPU_REQUEST: '0.22'
447
+ KUBERNETES_MEMORY_REQUEST: 200Mi
448
+ KUBERNETES_MEMORY_LIMIT: 400Mi
449
+ GIT_STRATEGY: none
450
+ script:
451
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
452
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
453
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
454
+ - set +e
455
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
456
+ - gcloud run services delete pan-test-app-dev-api --project=google-project-id --region=europe-west6
457
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
458
+ - 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
459
+ - echo 'Disabling component in Dependency Track'
460
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
461
+ - set -e
462
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
463
+ environment:
464
+ name: dev/api
465
+ url: $CL_GITLAB_ENVIRONMENT_URL
466
+ action: stop
467
+ artifacts:
468
+ reports:
469
+ dotenv: gitlab_environment.env
470
+ rules:
471
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
472
+ when: on_success
473
+ - when: never
474
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
475
+ - when: manual
476
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
477
+ needs: []
478
+ retry: *a1
479
+ interruptible: true
480
+ allow_failure: true
481
+ 'api ๐Ÿ”จ app | review ':
482
+ stage: build
483
+ image: path/to/docker/jobs-default:the-version
484
+ variables:
485
+ KUBERNETES_CPU_REQUEST: '0.45'
486
+ KUBERNETES_MEMORY_REQUEST: 1Gi
487
+ KUBERNETES_MEMORY_LIMIT: 4Gi
488
+ script:
489
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
490
+ - export ENV_SHORT="review"
491
+ - export APP_DIR="api"
492
+ - export ENV_TYPE="review"
493
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
494
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
495
+ - 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")"
496
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
497
+ - 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)}')"
498
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
499
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
500
+ - 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)}')"
501
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
502
+ - 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"; })-api"
503
+ - export DB_USER="my-user"
504
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
505
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
506
+ - 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"
507
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
508
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
509
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
510
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
511
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
512
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
513
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
514
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
515
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
516
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
517
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
518
+ - cd api
519
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
520
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
521
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
522
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
523
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
524
+ - yarn install --immutable
525
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
526
+ - yarn build
527
+ cache:
528
+ - key: api-yarn
529
+ policy: pull-push
530
+ paths:
531
+ - api/.yarn
532
+ - key: api-node-modules
533
+ policy: pull-push
534
+ paths:
535
+ - api/node_modules
536
+ - key: api-next-cache
537
+ policy: pull-push
538
+ paths:
539
+ - api/.next/cache
540
+ artifacts:
541
+ paths:
542
+ - api/__build_info.json
543
+ - api/.next
544
+ - api/dist
545
+ expire_in: 1 day
546
+ when: always
547
+ reports: {}
548
+ rules:
549
+ - if: $CI_MERGE_REQUEST_ID
550
+ needs: []
551
+ retry: *a1
552
+ interruptible: true
553
+ 'api ๐Ÿ”จ docker | review ':
554
+ stage: build
555
+ image: path/to/docker/docker-build:the-version
556
+ services:
557
+ - name: docker:24.0.6-dind
558
+ command:
559
+ - --tls=false
560
+ variables:
561
+ DOCKER_HOST: tcp://0.0.0.0:2375
562
+ DOCKER_TLS_CERTDIR: ''
563
+ DOCKER_DRIVER: overlay2
564
+ DOCKER_BUILDKIT: '1'
565
+ KUBERNETES_CPU_REQUEST: '0.45'
566
+ KUBERNETES_MEMORY_REQUEST: 1Gi
567
+ KUBERNETES_MEMORY_LIMIT: 2Gi
568
+ script:
569
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
570
+ - export APP_DIR="api"
571
+ - export DOCKER_BUILD_CONTEXT="."
572
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
573
+ - 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"; })"
574
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
575
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
576
+ - |-
577
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
578
+ RUN yarn plugin import workspace-tools
579
+ RUN yarn workspaces focus --production && yarn rebuild"
580
+ - |-
581
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
582
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
583
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
584
+ COPY --chown=node:node .yarn /app/.yarn"
585
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
586
+ - ensureNodeDockerfile
587
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
588
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
589
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
590
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
591
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
592
+ - 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
593
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
594
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
595
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
596
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
597
+ - docker push $DOCKER_CACHE_IMAGE
598
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
599
+ cache:
600
+ - key: api-yarn
601
+ policy: pull
602
+ paths:
603
+ - api/.yarn
604
+ rules:
605
+ - if: $CI_MERGE_REQUEST_ID
606
+ needs:
607
+ - 'api ๐Ÿ”จ app | review '
608
+ retry: *a1
609
+ interruptible: true
610
+ 'api ๐Ÿงพ sbom | review ':
611
+ stage: build
612
+ image: aquasec/trivy:0.38.3
613
+ variables: {}
614
+ script:
615
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
616
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
617
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
618
+ artifacts:
619
+ paths:
620
+ - __sbom.json
621
+ rules:
622
+ - if: $CI_MERGE_REQUEST_ID
623
+ needs: []
624
+ retry: *a1
625
+ interruptible: true
626
+ allow_failure: true
627
+ 'api ๐Ÿš€ Deploy | review ':
628
+ stage: deploy review
629
+ image: path/to/docker/gcloud:the-version
630
+ variables:
631
+ KUBERNETES_CPU_REQUEST: '0.22'
632
+ KUBERNETES_MEMORY_REQUEST: 200Mi
633
+ KUBERNETES_MEMORY_LIMIT: 400Mi
634
+ script:
635
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
636
+ - export ENV_SHORT="review"
637
+ - export APP_DIR="api"
638
+ - export ENV_TYPE="review"
639
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
640
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
641
+ - 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")"
642
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
643
+ - 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)}')"
644
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
645
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
646
+ - 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)}')"
647
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
648
+ - 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"; })-api"
649
+ - export DB_USER="my-user"
650
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
651
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
652
+ - 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"
653
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
654
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
655
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
656
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
657
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
658
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
659
+ - 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"; })"
660
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
661
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
662
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
663
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
664
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
665
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
666
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
667
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
668
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
669
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
670
+ - |
671
+ cat > ____envvars.yaml <<EOF
672
+ ENV_SHORT: |-
673
+ review
674
+ APP_DIR: |-
675
+ api
676
+ ENV_TYPE: |-
677
+ review
678
+ BUILD_INFO_BUILD_ID: |-
679
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
680
+ BUILD_INFO_BUILD_TIME: |-
681
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
682
+ BUILD_INFO_CURRENT_VERSION: |-
683
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
684
+ HOST: |-
685
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
686
+ ROOT_URL: |-
687
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
688
+ HOST_INTERNAL: |-
689
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
690
+ HOST_CANONICAL: |-
691
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
692
+ ROOT_URL_INTERNAL: |-
693
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
694
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
695
+ projectId:region:instancename
696
+ DB_NAME: |-
697
+ $(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" | sed 's/^/ /')
698
+ DB_USER: |-
699
+ my-user
700
+ DB_PASSWORD: |-
701
+ $(printf %s "$CL_review_api_DB_PASSWORD" | sed 's/^/ /')
702
+ DATABASE_URL: |-
703
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
704
+ DATABASE_JDBC_URL: |-
705
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
706
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
707
+ google-project-id
708
+ DEPLOY_CLOUD_RUN_REGION: |-
709
+ europe-west6
710
+ GCLOUD_RUN_canonicalHostSuffix: |-
711
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
712
+ _ALL_ENV_VAR_KEYS: |-
713
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
714
+
715
+ EOF
716
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
717
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
718
+ - set +e
719
+ - echo "ensuring Database..."
720
+ - 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"; })-api --instance=instancename --project projectId
721
+ - set -e
722
+ - 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
723
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
724
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
725
+ - 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
726
+ - 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
727
+ - 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
728
+ - set +e
729
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
730
+ - set -e
731
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
732
+ - echo 'Uploading SBOM to Dependency Track'
733
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
734
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
735
+ environment:
736
+ name: review/$CI_COMMIT_REF_NAME/api
737
+ url: $CL_GITLAB_ENVIRONMENT_URL
738
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | review '
739
+ auto_stop_in: 1 week
740
+ artifacts:
741
+ reports:
742
+ dotenv: gitlab_environment.env
743
+ rules:
744
+ - when: on_success
745
+ if: $CI_MERGE_REQUEST_ID
746
+ needs:
747
+ - job: api ๐Ÿ‘ฎ lint
748
+ artifacts: false
749
+ - job: 'api ๐Ÿ”จ app | review '
750
+ artifacts: false
751
+ - job: 'api ๐Ÿ”จ docker | review '
752
+ artifacts: false
753
+ - job: api ๐Ÿงช test
754
+ artifacts: false
755
+ - job: 'api ๐Ÿงพ sbom | review '
756
+ artifacts: true
757
+ - job: api ๐Ÿ›ก audit
758
+ artifacts: false
759
+ retry: *a1
760
+ interruptible: true
761
+ allow_failure: false
762
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | review ':
763
+ stage: stop review
764
+ image: path/to/docker/gcloud:the-version
765
+ variables:
766
+ KUBERNETES_CPU_REQUEST: '0.22'
767
+ KUBERNETES_MEMORY_REQUEST: 200Mi
768
+ KUBERNETES_MEMORY_LIMIT: 400Mi
769
+ GIT_STRATEGY: none
770
+ script:
771
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
772
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
773
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
774
+ - set +e
775
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
776
+ - 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
777
+ - 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"; })-api..."
778
+ - 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"
779
+ - "\\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\\"; })-api --instance=instancename --project projectId\\n do\\n echo \\"Trying again.\\"\\n sleep 10\\n done\\n "
780
+ - 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
781
+ - 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
782
+ - set +e
783
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
784
+ - set -e
785
+ - echo 'Disabling component in Dependency Track'
786
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
787
+ - set -e
788
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
789
+ environment:
790
+ name: review/$CI_COMMIT_REF_NAME/api
791
+ url: $CL_GITLAB_ENVIRONMENT_URL
792
+ action: stop
793
+ artifacts:
794
+ reports:
795
+ dotenv: gitlab_environment.env
796
+ rules:
797
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
798
+ when: on_success
799
+ - when: manual
800
+ if: $CI_MERGE_REQUEST_ID
801
+ needs: []
802
+ retry: *a1
803
+ interruptible: true
804
+ allow_failure: true
805
+ 'api ๐Ÿ”จ app | stage ':
806
+ stage: build
807
+ image: path/to/docker/jobs-default:the-version
808
+ variables:
809
+ KUBERNETES_CPU_REQUEST: '0.45'
810
+ KUBERNETES_MEMORY_REQUEST: 1Gi
811
+ KUBERNETES_MEMORY_LIMIT: 4Gi
812
+ script:
813
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
814
+ - export ENV_SHORT="stage"
815
+ - export APP_DIR="api"
816
+ - export ENV_TYPE="stage"
817
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
818
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
819
+ - 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")"
820
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
821
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
822
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
823
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
824
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
825
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
826
+ - export DB_NAME="pan-test-app-stage-api"
827
+ - export DB_USER="my-user"
828
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
829
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
830
+ - 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"
831
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
832
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
833
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
834
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
835
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
836
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
837
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
838
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
839
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
840
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
841
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
842
+ - cd api
843
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
844
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
845
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
846
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
847
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
848
+ - yarn install --immutable
849
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
850
+ - yarn build
851
+ cache:
852
+ - key: api-yarn
853
+ policy: pull-push
854
+ paths:
855
+ - api/.yarn
856
+ - key: api-node-modules
857
+ policy: pull-push
858
+ paths:
859
+ - api/node_modules
860
+ - key: api-next-cache
861
+ policy: pull-push
862
+ paths:
863
+ - api/.next/cache
864
+ artifacts:
865
+ paths:
866
+ - api/__build_info.json
867
+ - api/.next
868
+ - api/dist
869
+ expire_in: 1 day
870
+ when: always
871
+ reports: {}
872
+ rules:
873
+ - if: $CI_COMMIT_TAG
874
+ needs: []
875
+ retry: *a1
876
+ interruptible: true
877
+ 'api ๐Ÿ”จ docker | stage ':
878
+ stage: build
879
+ image: path/to/docker/docker-build:the-version
880
+ services:
881
+ - name: docker:24.0.6-dind
882
+ command:
883
+ - --tls=false
884
+ variables:
885
+ DOCKER_HOST: tcp://0.0.0.0:2375
886
+ DOCKER_TLS_CERTDIR: ''
887
+ DOCKER_DRIVER: overlay2
888
+ DOCKER_BUILDKIT: '1'
889
+ KUBERNETES_CPU_REQUEST: '0.45'
890
+ KUBERNETES_MEMORY_REQUEST: 1Gi
891
+ KUBERNETES_MEMORY_LIMIT: 2Gi
892
+ script:
893
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
894
+ - export APP_DIR="api"
895
+ - export DOCKER_BUILD_CONTEXT="."
896
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
897
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
898
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
899
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
900
+ - |-
901
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
902
+ RUN yarn plugin import workspace-tools
903
+ RUN yarn workspaces focus --production && yarn rebuild"
904
+ - |-
905
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
906
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
907
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
908
+ COPY --chown=node:node .yarn /app/.yarn"
909
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
910
+ - ensureNodeDockerfile
911
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
912
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
913
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
914
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
915
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
916
+ - 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
917
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
918
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
919
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
920
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
921
+ - docker push $DOCKER_CACHE_IMAGE
922
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
923
+ cache:
924
+ - key: api-yarn
925
+ policy: pull
926
+ paths:
927
+ - api/.yarn
928
+ rules:
929
+ - if: $CI_COMMIT_TAG
930
+ needs:
931
+ - 'api ๐Ÿ”จ app | stage '
932
+ retry: *a1
933
+ interruptible: true
934
+ 'api ๐Ÿงพ sbom | stage ':
935
+ stage: build
936
+ image: aquasec/trivy:0.38.3
937
+ variables: {}
938
+ script:
939
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
940
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
941
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
942
+ artifacts:
943
+ paths:
944
+ - __sbom.json
945
+ rules:
946
+ - if: $CI_COMMIT_TAG
947
+ needs: []
948
+ retry: *a1
949
+ interruptible: true
950
+ allow_failure: true
951
+ 'api ๐Ÿš€ Deploy | stage ':
952
+ stage: deploy stage
953
+ image: path/to/docker/gcloud:the-version
954
+ variables:
955
+ KUBERNETES_CPU_REQUEST: '0.22'
956
+ KUBERNETES_MEMORY_REQUEST: 200Mi
957
+ KUBERNETES_MEMORY_LIMIT: 400Mi
958
+ script:
959
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
960
+ - export ENV_SHORT="stage"
961
+ - export APP_DIR="api"
962
+ - export ENV_TYPE="stage"
963
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
964
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
965
+ - 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")"
966
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
967
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
968
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
969
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
970
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
971
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
972
+ - export DB_NAME="pan-test-app-stage-api"
973
+ - export DB_USER="my-user"
974
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
975
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
976
+ - 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"
977
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
978
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
979
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
980
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
981
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
982
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
983
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
984
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
985
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
986
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
987
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
988
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
989
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
990
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
991
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
992
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
993
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
994
+ - |
995
+ cat > ____envvars.yaml <<EOF
996
+ ENV_SHORT: |-
997
+ stage
998
+ APP_DIR: |-
999
+ api
1000
+ ENV_TYPE: |-
1001
+ stage
1002
+ BUILD_INFO_BUILD_ID: |-
1003
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1004
+ BUILD_INFO_BUILD_TIME: |-
1005
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1006
+ BUILD_INFO_CURRENT_VERSION: |-
1007
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
1008
+ HOST: |-
1009
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1010
+ ROOT_URL: |-
1011
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1012
+ HOST_INTERNAL: |-
1013
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1014
+ HOST_CANONICAL: |-
1015
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1016
+ ROOT_URL_INTERNAL: |-
1017
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1018
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1019
+ projectId:region:instancename
1020
+ DB_NAME: |-
1021
+ pan-test-app-stage-api
1022
+ DB_USER: |-
1023
+ my-user
1024
+ DB_PASSWORD: |-
1025
+ $(printf %s "$CL_stage_api_DB_PASSWORD" | sed 's/^/ /')
1026
+ DATABASE_URL: |-
1027
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1028
+ DATABASE_JDBC_URL: |-
1029
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
1030
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1031
+ google-project-id
1032
+ DEPLOY_CLOUD_RUN_REGION: |-
1033
+ europe-west6
1034
+ GCLOUD_RUN_canonicalHostSuffix: |-
1035
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1036
+ _ALL_ENV_VAR_KEYS: |-
1037
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
1038
+
1039
+ EOF
1040
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1041
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1042
+ - set +e
1043
+ - echo "ensuring Database..."
1044
+ - gcloud sql databases create pan-test-app-stage-api --instance=instancename --project projectId
1045
+ - set -e
1046
+ - 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
1047
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1048
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1049
+ - 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
1050
+ - 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
1051
+ - 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
1052
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1053
+ - echo 'Uploading SBOM to Dependency Track'
1054
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1055
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1056
+ environment:
1057
+ name: stage/api
1058
+ url: $CL_GITLAB_ENVIRONMENT_URL
1059
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | stage '
1060
+ artifacts:
1061
+ reports:
1062
+ dotenv: gitlab_environment.env
1063
+ rules:
1064
+ - when: on_success
1065
+ if: $CI_COMMIT_TAG
1066
+ needs:
1067
+ - job: 'api ๐Ÿ”จ app | stage '
1068
+ artifacts: false
1069
+ - job: 'api ๐Ÿ”จ docker | stage '
1070
+ artifacts: false
1071
+ - job: 'api ๐Ÿงพ sbom | stage '
1072
+ artifacts: true
1073
+ retry: *a1
1074
+ interruptible: true
1075
+ allow_failure: false
1076
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | stage ':
1077
+ stage: stop stage
1078
+ image: path/to/docker/gcloud:the-version
1079
+ variables:
1080
+ KUBERNETES_CPU_REQUEST: '0.22'
1081
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1082
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1083
+ GIT_STRATEGY: none
1084
+ script:
1085
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1086
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1087
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1088
+ - set +e
1089
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1090
+ - gcloud run services delete pan-test-app-stage-api --project=google-project-id --region=europe-west6
1091
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1092
+ - 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
1093
+ - echo 'Disabling component in Dependency Track'
1094
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1095
+ - set -e
1096
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1097
+ environment:
1098
+ name: stage/api
1099
+ url: $CL_GITLAB_ENVIRONMENT_URL
1100
+ action: stop
1101
+ artifacts:
1102
+ reports:
1103
+ dotenv: gitlab_environment.env
1104
+ rules:
1105
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1106
+ when: on_success
1107
+ - when: manual
1108
+ if: $CI_COMMIT_TAG
1109
+ needs: []
1110
+ retry: *a1
1111
+ interruptible: true
1112
+ allow_failure: true
1113
+ 'api ๐Ÿ”จ app | prod ':
1114
+ stage: build
1115
+ image: path/to/docker/jobs-default:the-version
1116
+ variables:
1117
+ KUBERNETES_CPU_REQUEST: '0.45'
1118
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1119
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1120
+ script:
1121
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1122
+ - export ENV_SHORT="prod"
1123
+ - export APP_DIR="api"
1124
+ - export ENV_TYPE="prod"
1125
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1126
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1127
+ - 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")"
1128
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1129
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1130
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1131
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1132
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1133
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1134
+ - export DB_NAME="pan-test-app-prod-api"
1135
+ - export DB_USER="my-user"
1136
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
1137
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1138
+ - 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"
1139
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1140
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1141
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1142
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1143
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
1144
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1145
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1146
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1147
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1148
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1149
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1150
+ - cd api
1151
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1152
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1153
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1154
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1155
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1156
+ - yarn install --immutable
1157
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1158
+ - yarn build
1159
+ cache:
1160
+ - key: api-yarn
1161
+ policy: pull-push
1162
+ paths:
1163
+ - api/.yarn
1164
+ - key: api-node-modules
1165
+ policy: pull-push
1166
+ paths:
1167
+ - api/node_modules
1168
+ - key: api-next-cache
1169
+ policy: pull-push
1170
+ paths:
1171
+ - api/.next/cache
1172
+ artifacts:
1173
+ paths:
1174
+ - api/__build_info.json
1175
+ - api/.next
1176
+ - api/dist
1177
+ expire_in: 1 day
1178
+ when: always
1179
+ reports: {}
1180
+ rules:
1181
+ - if: $CI_COMMIT_TAG
1182
+ needs: []
1183
+ retry: *a1
1184
+ interruptible: true
1185
+ 'api ๐Ÿ”จ docker | prod ':
1186
+ stage: build
1187
+ image: path/to/docker/docker-build:the-version
1188
+ services:
1189
+ - name: docker:24.0.6-dind
1190
+ command:
1191
+ - --tls=false
1192
+ variables:
1193
+ DOCKER_HOST: tcp://0.0.0.0:2375
1194
+ DOCKER_TLS_CERTDIR: ''
1195
+ DOCKER_DRIVER: overlay2
1196
+ DOCKER_BUILDKIT: '1'
1197
+ KUBERNETES_CPU_REQUEST: '0.45'
1198
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1199
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1200
+ script:
1201
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1202
+ - export APP_DIR="api"
1203
+ - export DOCKER_BUILD_CONTEXT="."
1204
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1205
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1206
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1207
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1208
+ - |-
1209
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1210
+ RUN yarn plugin import workspace-tools
1211
+ RUN yarn workspaces focus --production && yarn rebuild"
1212
+ - |-
1213
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1214
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1215
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1216
+ COPY --chown=node:node .yarn /app/.yarn"
1217
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1218
+ - ensureNodeDockerfile
1219
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1220
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1221
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1222
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1223
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1224
+ - 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
1225
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1226
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1227
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1228
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1229
+ - docker push $DOCKER_CACHE_IMAGE
1230
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1231
+ cache:
1232
+ - key: api-yarn
1233
+ policy: pull
1234
+ paths:
1235
+ - api/.yarn
1236
+ rules:
1237
+ - if: $CI_COMMIT_TAG
1238
+ needs:
1239
+ - 'api ๐Ÿ”จ app | prod '
1240
+ retry: *a1
1241
+ interruptible: true
1242
+ 'api ๐Ÿงพ sbom | prod ':
1243
+ stage: build
1244
+ image: aquasec/trivy:0.38.3
1245
+ variables: {}
1246
+ script:
1247
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1248
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1249
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1250
+ artifacts:
1251
+ paths:
1252
+ - __sbom.json
1253
+ rules:
1254
+ - if: $CI_COMMIT_TAG
1255
+ needs: []
1256
+ retry: *a1
1257
+ interruptible: true
1258
+ allow_failure: true
1259
+ 'api ๐Ÿš€ Deploy | prod ':
1260
+ stage: deploy prod
1261
+ image: path/to/docker/gcloud:the-version
1262
+ variables:
1263
+ KUBERNETES_CPU_REQUEST: '0.22'
1264
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1265
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1266
+ script:
1267
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1268
+ - export ENV_SHORT="prod"
1269
+ - export APP_DIR="api"
1270
+ - export ENV_TYPE="prod"
1271
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1272
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1273
+ - 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")"
1274
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1275
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1276
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1277
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1278
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1279
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1280
+ - export DB_NAME="pan-test-app-prod-api"
1281
+ - export DB_USER="my-user"
1282
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
1283
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1284
+ - 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"
1285
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1286
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1287
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1288
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1289
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
1290
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1291
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1292
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1293
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1294
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1295
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1296
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
1297
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1298
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1299
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1300
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
1301
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
1302
+ - |
1303
+ cat > ____envvars.yaml <<EOF
1304
+ ENV_SHORT: |-
1305
+ prod
1306
+ APP_DIR: |-
1307
+ api
1308
+ ENV_TYPE: |-
1309
+ prod
1310
+ BUILD_INFO_BUILD_ID: |-
1311
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1312
+ BUILD_INFO_BUILD_TIME: |-
1313
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1314
+ BUILD_INFO_CURRENT_VERSION: |-
1315
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
1316
+ HOST: |-
1317
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1318
+ ROOT_URL: |-
1319
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1320
+ HOST_INTERNAL: |-
1321
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1322
+ HOST_CANONICAL: |-
1323
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1324
+ ROOT_URL_INTERNAL: |-
1325
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1326
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1327
+ projectId:region:instancename
1328
+ DB_NAME: |-
1329
+ pan-test-app-prod-api
1330
+ DB_USER: |-
1331
+ my-user
1332
+ DB_PASSWORD: |-
1333
+ $(printf %s "$CL_prod_api_DB_PASSWORD" | sed 's/^/ /')
1334
+ DATABASE_URL: |-
1335
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1336
+ DATABASE_JDBC_URL: |-
1337
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
1338
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1339
+ google-project-id
1340
+ DEPLOY_CLOUD_RUN_REGION: |-
1341
+ europe-west6
1342
+ GCLOUD_RUN_canonicalHostSuffix: |-
1343
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1344
+ _ALL_ENV_VAR_KEYS: |-
1345
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
1346
+
1347
+ EOF
1348
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1349
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1350
+ - set +e
1351
+ - echo "ensuring Database..."
1352
+ - gcloud sql databases create pan-test-app-prod-api --instance=instancename --project projectId
1353
+ - set -e
1354
+ - 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
1355
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1356
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1357
+ - 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
1358
+ - 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
1359
+ - 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
1360
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1361
+ - echo 'Uploading SBOM to Dependency Track'
1362
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1363
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1364
+ environment:
1365
+ name: prod/api
1366
+ url: $CL_GITLAB_ENVIRONMENT_URL
1367
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | prod '
1368
+ artifacts:
1369
+ reports:
1370
+ dotenv: gitlab_environment.env
1371
+ rules:
1372
+ - when: manual
1373
+ if: $CI_COMMIT_TAG
1374
+ needs:
1375
+ - job: 'api ๐Ÿ”จ app | prod '
1376
+ artifacts: false
1377
+ - job: 'api ๐Ÿ”จ docker | prod '
1378
+ artifacts: false
1379
+ - job: 'api ๐Ÿงพ sbom | prod '
1380
+ artifacts: true
1381
+ retry: *a1
1382
+ interruptible: true
1383
+ allow_failure: true
1384
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | prod ':
1385
+ stage: stop prod
1386
+ image: path/to/docker/gcloud:the-version
1387
+ variables:
1388
+ KUBERNETES_CPU_REQUEST: '0.22'
1389
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1390
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1391
+ GIT_STRATEGY: none
1392
+ script:
1393
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1394
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1395
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1396
+ - set +e
1397
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1398
+ - gcloud run services delete pan-test-app-prod-api --project=google-project-id --region=europe-west6
1399
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
1400
+ - 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
1401
+ - echo 'Disabling component in Dependency Track'
1402
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1403
+ - set -e
1404
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1405
+ environment:
1406
+ name: prod/api
1407
+ url: $CL_GITLAB_ENVIRONMENT_URL
1408
+ action: stop
1409
+ artifacts:
1410
+ reports:
1411
+ dotenv: gitlab_environment.env
1412
+ rules:
1413
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1414
+ when: on_success
1415
+ - when: manual
1416
+ if: $CI_COMMIT_TAG
1417
+ needs: []
1418
+ retry: *a1
1419
+ interruptible: true
1420
+ allow_failure: true
1421
+ worker ๐Ÿ›ก audit:
1422
+ stage: test
1423
+ image: path/to/docker/jobs-default:the-version
1424
+ variables:
1425
+ KUBERNETES_CPU_REQUEST: '0.45'
1426
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1427
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1428
+ script:
1429
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1430
+ - export APP_PATH="api"
1431
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1432
+ - cd api
1433
+ - yarn npm audit --environment production
1434
+ rules:
1435
+ - when: never
1436
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1437
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1438
+ - if: $CI_MERGE_REQUEST_ID
1439
+ needs: []
1440
+ retry: *a1
1441
+ interruptible: true
1442
+ allow_failure: true
1443
+ worker ๐Ÿ‘ฎ lint:
1444
+ stage: test
1445
+ image: path/to/docker/jobs-default:the-version
1446
+ variables:
1447
+ KUBERNETES_CPU_REQUEST: '0.45'
1448
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1449
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1450
+ script:
1451
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1452
+ - export APP_PATH="api"
1453
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1454
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1455
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1456
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1457
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1458
+ - cd api
1459
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1460
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1461
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1462
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1463
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1464
+ - yarn install --immutable
1465
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1466
+ - yarn lint
1467
+ cache:
1468
+ - key: api-yarn
1469
+ policy: pull-push
1470
+ paths:
1471
+ - api/.yarn
1472
+ - key: api-node-modules
1473
+ policy: pull-push
1474
+ paths:
1475
+ - api/node_modules
1476
+ rules:
1477
+ - when: never
1478
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1479
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1480
+ - if: $CI_MERGE_REQUEST_ID
1481
+ needs: []
1482
+ retry: *a1
1483
+ interruptible: true
1484
+ worker ๐Ÿงช test:
1485
+ stage: test
1486
+ image: path/to/docker/jobs-testing-chrome:the-version
1487
+ variables:
1488
+ KUBERNETES_CPU_REQUEST: '0.45'
1489
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1490
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1491
+ script:
1492
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1493
+ - export APP_PATH="api"
1494
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1495
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1496
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1497
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1498
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1499
+ - cd api
1500
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1501
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1502
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1503
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1504
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1505
+ - yarn install --immutable
1506
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1507
+ - yarn test
1508
+ cache:
1509
+ - key: api-yarn
1510
+ policy: pull-push
1511
+ paths:
1512
+ - api/.yarn
1513
+ - key: api-node-modules
1514
+ policy: pull-push
1515
+ paths:
1516
+ - api/node_modules
1517
+ rules:
1518
+ - when: never
1519
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1520
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1521
+ - if: $CI_MERGE_REQUEST_ID
1522
+ needs: []
1523
+ retry: *a1
1524
+ interruptible: true
1525
+ 'worker ๐Ÿ”จ app | dev ':
1526
+ stage: build
1527
+ image: path/to/docker/jobs-default:the-version
1528
+ variables:
1529
+ KUBERNETES_CPU_REQUEST: '0.45'
1530
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1531
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1532
+ script:
1533
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1534
+ - export ENV_SHORT="dev"
1535
+ - export APP_DIR="api"
1536
+ - export ENV_TYPE="dev"
1537
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1538
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1539
+ - 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")"
1540
+ - export HOST="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1541
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1542
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1543
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1544
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1545
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1546
+ - export DB_NAME="pan-test-app-dev-api"
1547
+ - export DB_USER="my-user"
1548
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
1549
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1550
+ - 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"
1551
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1552
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1553
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_worker_GCLOUD_DEPLOY_credentialsKey"
1554
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix"
1555
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
1556
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1557
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1558
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1559
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1560
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1561
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1562
+ - cd api
1563
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1564
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1565
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1566
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1567
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1568
+ - yarn install --immutable
1569
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1570
+ - yarn build:worker
1571
+ cache:
1572
+ - key: api-yarn
1573
+ policy: pull-push
1574
+ paths:
1575
+ - api/.yarn
1576
+ - key: api-node-modules
1577
+ policy: pull-push
1578
+ paths:
1579
+ - api/node_modules
1580
+ - key: worker-next-cache
1581
+ policy: pull-push
1582
+ paths:
1583
+ - api/.next/cache
1584
+ artifacts:
1585
+ paths:
1586
+ - api/__build_info.json
1587
+ - api/.next
1588
+ - api/dist
1589
+ expire_in: 1 day
1590
+ when: always
1591
+ reports: {}
1592
+ rules:
1593
+ - when: never
1594
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1595
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1596
+ needs: []
1597
+ retry: *a1
1598
+ interruptible: true
1599
+ 'worker ๐Ÿ”จ docker | dev ':
1600
+ stage: build
1601
+ image: path/to/docker/docker-build:the-version
1602
+ services:
1603
+ - name: docker:24.0.6-dind
1604
+ command:
1605
+ - --tls=false
1606
+ variables:
1607
+ DOCKER_HOST: tcp://0.0.0.0:2375
1608
+ DOCKER_TLS_CERTDIR: ''
1609
+ DOCKER_DRIVER: overlay2
1610
+ DOCKER_BUILDKIT: '1'
1611
+ KUBERNETES_CPU_REQUEST: '0.45'
1612
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1613
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1614
+ script:
1615
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1616
+ - export APP_DIR="api"
1617
+ - export DOCKER_BUILD_CONTEXT="."
1618
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1619
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/worker"
1620
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
1621
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1622
+ - |-
1623
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1624
+ RUN yarn plugin import workspace-tools
1625
+ RUN yarn workspaces focus --production && yarn rebuild"
1626
+ - |-
1627
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1628
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1629
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1630
+ COPY --chown=node:node .yarn /app/.yarn"
1631
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1632
+ - ensureNodeDockerfile
1633
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1634
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_worker_GCLOUD_DEPLOY_credentialsKey")
1635
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1636
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1637
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1638
+ - 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
1639
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1640
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1641
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1642
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1643
+ - docker push $DOCKER_CACHE_IMAGE
1644
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1645
+ cache:
1646
+ - key: api-yarn
1647
+ policy: pull
1648
+ paths:
1649
+ - api/.yarn
1650
+ rules:
1651
+ - when: never
1652
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1653
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1654
+ needs:
1655
+ - 'worker ๐Ÿ”จ app | dev '
1656
+ retry: *a1
1657
+ interruptible: true
1658
+ 'worker ๐Ÿงพ sbom | dev ':
1659
+ stage: build
1660
+ image: aquasec/trivy:0.38.3
1661
+ variables: {}
1662
+ script:
1663
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1664
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1665
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1666
+ artifacts:
1667
+ paths:
1668
+ - __sbom.json
1669
+ rules:
1670
+ - when: never
1671
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1672
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1673
+ needs: []
1674
+ retry: *a1
1675
+ interruptible: true
1676
+ allow_failure: true
1677
+ 'worker ๐Ÿš€ Deploy | dev ':
1678
+ stage: deploy dev
1679
+ image: path/to/docker/gcloud:the-version
1680
+ variables:
1681
+ KUBERNETES_CPU_REQUEST: '0.22'
1682
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1683
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1684
+ script:
1685
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1686
+ - export ENV_SHORT="dev"
1687
+ - export APP_DIR="api"
1688
+ - export ENV_TYPE="dev"
1689
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1690
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1691
+ - 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")"
1692
+ - export HOST="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1693
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1694
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1695
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1696
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1697
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1698
+ - export DB_NAME="pan-test-app-dev-api"
1699
+ - export DB_USER="my-user"
1700
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
1701
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1702
+ - 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"
1703
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1704
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1705
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_worker_GCLOUD_DEPLOY_credentialsKey"
1706
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix"
1707
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
1708
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1709
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/worker"
1710
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
1711
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1712
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1713
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1714
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
1715
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_worker_GCLOUD_DEPLOY_credentialsKey")
1716
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1717
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1718
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
1719
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
1720
+ - |
1721
+ cat > ____envvars.yaml <<EOF
1722
+ ENV_SHORT: |-
1723
+ dev
1724
+ APP_DIR: |-
1725
+ api
1726
+ ENV_TYPE: |-
1727
+ dev
1728
+ BUILD_INFO_BUILD_ID: |-
1729
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1730
+ BUILD_INFO_BUILD_TIME: |-
1731
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1732
+ BUILD_INFO_CURRENT_VERSION: |-
1733
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
1734
+ HOST: |-
1735
+ $(printf %s "$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1736
+ ROOT_URL: |-
1737
+ $(printf %s "https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1738
+ HOST_INTERNAL: |-
1739
+ $(printf %s "$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1740
+ HOST_CANONICAL: |-
1741
+ $(printf %s "$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1742
+ ROOT_URL_INTERNAL: |-
1743
+ $(printf %s "https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1744
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1745
+ projectId:region:instancename
1746
+ DB_NAME: |-
1747
+ pan-test-app-dev-api
1748
+ DB_USER: |-
1749
+ my-user
1750
+ DB_PASSWORD: |-
1751
+ $(printf %s "$CL_dev_api_DB_PASSWORD" | sed 's/^/ /')
1752
+ DATABASE_URL: |-
1753
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1754
+ DATABASE_JDBC_URL: |-
1755
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
1756
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1757
+ google-project-id
1758
+ DEPLOY_CLOUD_RUN_REGION: |-
1759
+ europe-west6
1760
+ GCLOUD_RUN_canonicalHostSuffix: |-
1761
+ $(printf %s "$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1762
+ _ALL_ENV_VAR_KEYS: |-
1763
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
1764
+
1765
+ EOF
1766
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1767
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1768
+ - set +e
1769
+ - echo "ensuring Database..."
1770
+ - gcloud sql databases create pan-test-app-dev-api --instance=instancename --project projectId
1771
+ - set -e
1772
+ - gcloud run deploy pan-test-app-dev-worker --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/worker:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=worker,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-service-name=pan-test-app-dev-worker --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1773
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1774
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1775
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-dev-worker --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
1776
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/worker --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/worker@$version --quiet --delete-tags; done
1777
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
1778
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1779
+ - echo 'Uploading SBOM to Dependency Track'
1780
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/worker" "https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1781
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1782
+ environment:
1783
+ name: dev/worker
1784
+ url: $CL_GITLAB_ENVIRONMENT_URL
1785
+ on_stop: 'worker ๐Ÿ›‘ Stop โš ๏ธ | dev '
1786
+ auto_stop_in: 4 weeks
1787
+ artifacts:
1788
+ reports:
1789
+ dotenv: gitlab_environment.env
1790
+ rules:
1791
+ - when: never
1792
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1793
+ - when: on_success
1794
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1795
+ needs:
1796
+ - job: worker ๐Ÿ‘ฎ lint
1797
+ artifacts: false
1798
+ - job: 'worker ๐Ÿ”จ app | dev '
1799
+ artifacts: false
1800
+ - job: 'worker ๐Ÿ”จ docker | dev '
1801
+ artifacts: false
1802
+ - job: worker ๐Ÿงช test
1803
+ artifacts: false
1804
+ - job: 'worker ๐Ÿงพ sbom | dev '
1805
+ artifacts: true
1806
+ - job: worker ๐Ÿ›ก audit
1807
+ artifacts: false
1808
+ retry: *a1
1809
+ interruptible: true
1810
+ allow_failure: false
1811
+ 'worker ๐Ÿ›‘ Stop โš ๏ธ | dev ':
1812
+ stage: stop dev
1813
+ image: path/to/docker/gcloud:the-version
1814
+ variables:
1815
+ KUBERNETES_CPU_REQUEST: '0.22'
1816
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1817
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1818
+ GIT_STRATEGY: none
1819
+ script:
1820
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1821
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1822
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1823
+ - set +e
1824
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_worker_GCLOUD_DEPLOY_credentialsKey")
1825
+ - gcloud run services delete pan-test-app-dev-worker --project=google-project-id --region=europe-west6
1826
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/worker --quiet --delete-tags
1827
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
1828
+ - echo 'Disabling component in Dependency Track'
1829
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/worker" "https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1830
+ - set -e
1831
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-worker-$CL_dev_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1832
+ environment:
1833
+ name: dev/worker
1834
+ url: $CL_GITLAB_ENVIRONMENT_URL
1835
+ action: stop
1836
+ artifacts:
1837
+ reports:
1838
+ dotenv: gitlab_environment.env
1839
+ rules:
1840
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1841
+ when: on_success
1842
+ - when: never
1843
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1844
+ - when: manual
1845
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1846
+ needs: []
1847
+ retry: *a1
1848
+ interruptible: true
1849
+ allow_failure: true
1850
+ 'worker ๐Ÿ”จ app | review ':
1851
+ stage: build
1852
+ image: path/to/docker/jobs-default:the-version
1853
+ variables:
1854
+ KUBERNETES_CPU_REQUEST: '0.45'
1855
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1856
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1857
+ script:
1858
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1859
+ - export ENV_SHORT="review"
1860
+ - export APP_DIR="api"
1861
+ - export ENV_TYPE="review"
1862
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1863
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1864
+ - 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")"
1865
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1866
+ - 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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1867
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1868
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1869
+ - 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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1870
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1871
+ - 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"; })-api"
1872
+ - export DB_USER="my-user"
1873
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
1874
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1875
+ - 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"
1876
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1877
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1878
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_worker_GCLOUD_DEPLOY_credentialsKey"
1879
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix"
1880
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
1881
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1882
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1883
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1884
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1885
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1886
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1887
+ - cd api
1888
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1889
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1890
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1891
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1892
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1893
+ - yarn install --immutable
1894
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1895
+ - yarn build:worker
1896
+ cache:
1897
+ - key: api-yarn
1898
+ policy: pull-push
1899
+ paths:
1900
+ - api/.yarn
1901
+ - key: api-node-modules
1902
+ policy: pull-push
1903
+ paths:
1904
+ - api/node_modules
1905
+ - key: worker-next-cache
1906
+ policy: pull-push
1907
+ paths:
1908
+ - api/.next/cache
1909
+ artifacts:
1910
+ paths:
1911
+ - api/__build_info.json
1912
+ - api/.next
1913
+ - api/dist
1914
+ expire_in: 1 day
1915
+ when: always
1916
+ reports: {}
1917
+ rules:
1918
+ - if: $CI_MERGE_REQUEST_ID
1919
+ needs: []
1920
+ retry: *a1
1921
+ interruptible: true
1922
+ 'worker ๐Ÿ”จ docker | review ':
1923
+ stage: build
1924
+ image: path/to/docker/docker-build:the-version
1925
+ services:
1926
+ - name: docker:24.0.6-dind
1927
+ command:
1928
+ - --tls=false
1929
+ variables:
1930
+ DOCKER_HOST: tcp://0.0.0.0:2375
1931
+ DOCKER_TLS_CERTDIR: ''
1932
+ DOCKER_DRIVER: overlay2
1933
+ DOCKER_BUILDKIT: '1'
1934
+ KUBERNETES_CPU_REQUEST: '0.45'
1935
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1936
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1937
+ script:
1938
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1939
+ - export APP_DIR="api"
1940
+ - export DOCKER_BUILD_CONTEXT="."
1941
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1942
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
1943
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
1944
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1945
+ - |-
1946
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1947
+ RUN yarn plugin import workspace-tools
1948
+ RUN yarn workspaces focus --production && yarn rebuild"
1949
+ - |-
1950
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1951
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1952
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1953
+ COPY --chown=node:node .yarn /app/.yarn"
1954
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1955
+ - ensureNodeDockerfile
1956
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1957
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_worker_GCLOUD_DEPLOY_credentialsKey")
1958
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1959
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1960
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1961
+ - 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
1962
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1963
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1964
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1965
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1966
+ - docker push $DOCKER_CACHE_IMAGE
1967
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1968
+ cache:
1969
+ - key: api-yarn
1970
+ policy: pull
1971
+ paths:
1972
+ - api/.yarn
1973
+ rules:
1974
+ - if: $CI_MERGE_REQUEST_ID
1975
+ needs:
1976
+ - 'worker ๐Ÿ”จ app | review '
1977
+ retry: *a1
1978
+ interruptible: true
1979
+ 'worker ๐Ÿงพ sbom | review ':
1980
+ stage: build
1981
+ image: aquasec/trivy:0.38.3
1982
+ variables: {}
1983
+ script:
1984
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1985
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1986
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1987
+ artifacts:
1988
+ paths:
1989
+ - __sbom.json
1990
+ rules:
1991
+ - if: $CI_MERGE_REQUEST_ID
1992
+ needs: []
1993
+ retry: *a1
1994
+ interruptible: true
1995
+ allow_failure: true
1996
+ 'worker ๐Ÿš€ Deploy | review ':
1997
+ stage: deploy review
1998
+ image: path/to/docker/gcloud:the-version
1999
+ variables:
2000
+ KUBERNETES_CPU_REQUEST: '0.22'
2001
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2002
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2003
+ script:
2004
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2005
+ - export ENV_SHORT="review"
2006
+ - export APP_DIR="api"
2007
+ - export ENV_TYPE="review"
2008
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2009
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2010
+ - 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")"
2011
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2012
+ - 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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2013
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2014
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2015
+ - 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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2016
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2017
+ - 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"; })-api"
2018
+ - export DB_USER="my-user"
2019
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
2020
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
2021
+ - 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"
2022
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2023
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2024
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_worker_GCLOUD_DEPLOY_credentialsKey"
2025
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix"
2026
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
2027
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2028
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
2029
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
2030
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2031
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2032
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2033
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
2034
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_worker_GCLOUD_DEPLOY_credentialsKey")
2035
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2036
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2037
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
2038
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
2039
+ - |
2040
+ cat > ____envvars.yaml <<EOF
2041
+ ENV_SHORT: |-
2042
+ review
2043
+ APP_DIR: |-
2044
+ api
2045
+ ENV_TYPE: |-
2046
+ review
2047
+ BUILD_INFO_BUILD_ID: |-
2048
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2049
+ BUILD_INFO_BUILD_TIME: |-
2050
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2051
+ BUILD_INFO_CURRENT_VERSION: |-
2052
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
2053
+ HOST: |-
2054
+ $(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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2055
+ ROOT_URL: |-
2056
+ $(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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2057
+ HOST_INTERNAL: |-
2058
+ $(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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2059
+ HOST_CANONICAL: |-
2060
+ $(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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2061
+ ROOT_URL_INTERNAL: |-
2062
+ $(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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2063
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2064
+ projectId:region:instancename
2065
+ DB_NAME: |-
2066
+ $(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" | sed 's/^/ /')
2067
+ DB_USER: |-
2068
+ my-user
2069
+ DB_PASSWORD: |-
2070
+ $(printf %s "$CL_review_api_DB_PASSWORD" | sed 's/^/ /')
2071
+ DATABASE_URL: |-
2072
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
2073
+ DATABASE_JDBC_URL: |-
2074
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
2075
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2076
+ google-project-id
2077
+ DEPLOY_CLOUD_RUN_REGION: |-
2078
+ europe-west6
2079
+ GCLOUD_RUN_canonicalHostSuffix: |-
2080
+ $(printf %s "$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
2081
+ _ALL_ENV_VAR_KEYS: |-
2082
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
2083
+
2084
+ EOF
2085
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
2086
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
2087
+ - set +e
2088
+ - echo "ensuring Database..."
2089
+ - 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"; })-api --instance=instancename --project projectId
2090
+ - set -e
2091
+ - 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"; })-worker" | awk '{print tolower($0)}') --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker/$([ -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=worker,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"; })-worker" | awk '{print tolower($0)}') --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
2092
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
2093
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
2094
+ - 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"; })-worker" | 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
2095
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker/$([ -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/worker/$([ -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
2096
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2097
+ - set +e
2098
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker --quiet --delete-tags
2099
+ - set -e
2100
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
2101
+ - echo 'Uploading SBOM to Dependency Track'
2102
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/worker" "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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
2103
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2104
+ environment:
2105
+ name: review/$CI_COMMIT_REF_NAME/worker
2106
+ url: $CL_GITLAB_ENVIRONMENT_URL
2107
+ on_stop: 'worker ๐Ÿ›‘ Stop โš ๏ธ | review '
2108
+ auto_stop_in: 1 week
2109
+ artifacts:
2110
+ reports:
2111
+ dotenv: gitlab_environment.env
2112
+ rules:
2113
+ - when: on_success
2114
+ if: $CI_MERGE_REQUEST_ID
2115
+ needs:
2116
+ - job: worker ๐Ÿ‘ฎ lint
2117
+ artifacts: false
2118
+ - job: 'worker ๐Ÿ”จ app | review '
2119
+ artifacts: false
2120
+ - job: 'worker ๐Ÿ”จ docker | review '
2121
+ artifacts: false
2122
+ - job: worker ๐Ÿงช test
2123
+ artifacts: false
2124
+ - job: 'worker ๐Ÿงพ sbom | review '
2125
+ artifacts: true
2126
+ - job: worker ๐Ÿ›ก audit
2127
+ artifacts: false
2128
+ retry: *a1
2129
+ interruptible: true
2130
+ allow_failure: false
2131
+ 'worker ๐Ÿ›‘ Stop โš ๏ธ | review ':
2132
+ stage: stop review
2133
+ image: path/to/docker/gcloud:the-version
2134
+ variables:
2135
+ KUBERNETES_CPU_REQUEST: '0.22'
2136
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2137
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2138
+ GIT_STRATEGY: none
2139
+ script:
2140
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2141
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2142
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2143
+ - set +e
2144
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_worker_GCLOUD_DEPLOY_credentialsKey")
2145
+ - 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"; })-worker" | awk '{print tolower($0)}') --project=google-project-id --region=europe-west6
2146
+ - 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"; })-api..."
2147
+ - 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"
2148
+ - "\\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\\"; })-api --instance=instancename --project projectId\\n do\\n echo \\"Trying again.\\"\\n sleep 10\\n done\\n "
2149
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker/$([ -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
2150
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2151
+ - set +e
2152
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/worker --quiet --delete-tags
2153
+ - set -e
2154
+ - echo 'Disabling component in Dependency Track'
2155
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/worker" "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"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
2156
+ - set -e
2157
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-worker-$CL_review_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2158
+ environment:
2159
+ name: review/$CI_COMMIT_REF_NAME/worker
2160
+ url: $CL_GITLAB_ENVIRONMENT_URL
2161
+ action: stop
2162
+ artifacts:
2163
+ reports:
2164
+ dotenv: gitlab_environment.env
2165
+ rules:
2166
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2167
+ when: on_success
2168
+ - when: manual
2169
+ if: $CI_MERGE_REQUEST_ID
2170
+ needs: []
2171
+ retry: *a1
2172
+ interruptible: true
2173
+ allow_failure: true
2174
+ 'worker ๐Ÿ”จ app | stage ':
2175
+ stage: build
2176
+ image: path/to/docker/jobs-default:the-version
2177
+ variables:
2178
+ KUBERNETES_CPU_REQUEST: '0.45'
2179
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2180
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2181
+ script:
2182
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2183
+ - export ENV_SHORT="stage"
2184
+ - export APP_DIR="api"
2185
+ - export ENV_TYPE="stage"
2186
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2187
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2188
+ - 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")"
2189
+ - export HOST="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2190
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2191
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2192
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2193
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2194
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2195
+ - export DB_NAME="pan-test-app-stage-api"
2196
+ - export DB_USER="my-user"
2197
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
2198
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
2199
+ - 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"
2200
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2201
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2202
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_worker_GCLOUD_DEPLOY_credentialsKey"
2203
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix"
2204
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
2205
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2206
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
2207
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2208
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2209
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2210
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2211
+ - cd api
2212
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2213
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2214
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2215
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2216
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
2217
+ - yarn install --immutable
2218
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
2219
+ - yarn build:worker
2220
+ cache:
2221
+ - key: api-yarn
2222
+ policy: pull-push
2223
+ paths:
2224
+ - api/.yarn
2225
+ - key: api-node-modules
2226
+ policy: pull-push
2227
+ paths:
2228
+ - api/node_modules
2229
+ - key: worker-next-cache
2230
+ policy: pull-push
2231
+ paths:
2232
+ - api/.next/cache
2233
+ artifacts:
2234
+ paths:
2235
+ - api/__build_info.json
2236
+ - api/.next
2237
+ - api/dist
2238
+ expire_in: 1 day
2239
+ when: always
2240
+ reports: {}
2241
+ rules:
2242
+ - if: $CI_COMMIT_TAG
2243
+ needs: []
2244
+ retry: *a1
2245
+ interruptible: true
2246
+ 'worker ๐Ÿ”จ docker | stage ':
2247
+ stage: build
2248
+ image: path/to/docker/docker-build:the-version
2249
+ services:
2250
+ - name: docker:24.0.6-dind
2251
+ command:
2252
+ - --tls=false
2253
+ variables:
2254
+ DOCKER_HOST: tcp://0.0.0.0:2375
2255
+ DOCKER_TLS_CERTDIR: ''
2256
+ DOCKER_DRIVER: overlay2
2257
+ DOCKER_BUILDKIT: '1'
2258
+ KUBERNETES_CPU_REQUEST: '0.45'
2259
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2260
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2261
+ script:
2262
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2263
+ - export APP_DIR="api"
2264
+ - export DOCKER_BUILD_CONTEXT="."
2265
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2266
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/worker"
2267
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
2268
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2269
+ - |-
2270
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2271
+ RUN yarn plugin import workspace-tools
2272
+ RUN yarn workspaces focus --production && yarn rebuild"
2273
+ - |-
2274
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
2275
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
2276
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2277
+ COPY --chown=node:node .yarn /app/.yarn"
2278
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2279
+ - ensureNodeDockerfile
2280
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
2281
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_worker_GCLOUD_DEPLOY_credentialsKey")
2282
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
2283
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
2284
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
2285
+ - 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
2286
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
2287
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
2288
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2289
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2290
+ - docker push $DOCKER_CACHE_IMAGE
2291
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
2292
+ cache:
2293
+ - key: api-yarn
2294
+ policy: pull
2295
+ paths:
2296
+ - api/.yarn
2297
+ rules:
2298
+ - if: $CI_COMMIT_TAG
2299
+ needs:
2300
+ - 'worker ๐Ÿ”จ app | stage '
2301
+ retry: *a1
2302
+ interruptible: true
2303
+ 'worker ๐Ÿงพ sbom | stage ':
2304
+ stage: build
2305
+ image: aquasec/trivy:0.38.3
2306
+ variables: {}
2307
+ script:
2308
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2309
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2310
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
2311
+ artifacts:
2312
+ paths:
2313
+ - __sbom.json
2314
+ rules:
2315
+ - if: $CI_COMMIT_TAG
2316
+ needs: []
2317
+ retry: *a1
2318
+ interruptible: true
2319
+ allow_failure: true
2320
+ 'worker ๐Ÿš€ Deploy | stage ':
2321
+ stage: deploy stage
2322
+ image: path/to/docker/gcloud:the-version
2323
+ variables:
2324
+ KUBERNETES_CPU_REQUEST: '0.22'
2325
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2326
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2327
+ script:
2328
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2329
+ - export ENV_SHORT="stage"
2330
+ - export APP_DIR="api"
2331
+ - export ENV_TYPE="stage"
2332
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2333
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2334
+ - 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")"
2335
+ - export HOST="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2336
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2337
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2338
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2339
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2340
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2341
+ - export DB_NAME="pan-test-app-stage-api"
2342
+ - export DB_USER="my-user"
2343
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
2344
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
2345
+ - 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"
2346
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2347
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2348
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_worker_GCLOUD_DEPLOY_credentialsKey"
2349
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix"
2350
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
2351
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2352
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/worker"
2353
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
2354
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2355
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2356
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2357
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
2358
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_worker_GCLOUD_DEPLOY_credentialsKey")
2359
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2360
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2361
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
2362
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
2363
+ - |
2364
+ cat > ____envvars.yaml <<EOF
2365
+ ENV_SHORT: |-
2366
+ stage
2367
+ APP_DIR: |-
2368
+ api
2369
+ ENV_TYPE: |-
2370
+ stage
2371
+ BUILD_INFO_BUILD_ID: |-
2372
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2373
+ BUILD_INFO_BUILD_TIME: |-
2374
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2375
+ BUILD_INFO_CURRENT_VERSION: |-
2376
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
2377
+ HOST: |-
2378
+ $(printf %s "$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2379
+ ROOT_URL: |-
2380
+ $(printf %s "https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2381
+ HOST_INTERNAL: |-
2382
+ $(printf %s "$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2383
+ HOST_CANONICAL: |-
2384
+ $(printf %s "$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2385
+ ROOT_URL_INTERNAL: |-
2386
+ $(printf %s "https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2387
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2388
+ projectId:region:instancename
2389
+ DB_NAME: |-
2390
+ pan-test-app-stage-api
2391
+ DB_USER: |-
2392
+ my-user
2393
+ DB_PASSWORD: |-
2394
+ $(printf %s "$CL_stage_api_DB_PASSWORD" | sed 's/^/ /')
2395
+ DATABASE_URL: |-
2396
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
2397
+ DATABASE_JDBC_URL: |-
2398
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
2399
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2400
+ google-project-id
2401
+ DEPLOY_CLOUD_RUN_REGION: |-
2402
+ europe-west6
2403
+ GCLOUD_RUN_canonicalHostSuffix: |-
2404
+ $(printf %s "$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
2405
+ _ALL_ENV_VAR_KEYS: |-
2406
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
2407
+
2408
+ EOF
2409
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
2410
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
2411
+ - set +e
2412
+ - echo "ensuring Database..."
2413
+ - gcloud sql databases create pan-test-app-stage-api --instance=instancename --project projectId
2414
+ - set -e
2415
+ - gcloud run deploy pan-test-app-stage-worker --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/worker:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=worker,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-service-name=pan-test-app-stage-worker --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
2416
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
2417
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
2418
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-stage-worker --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
2419
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/worker --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/worker@$version --quiet --delete-tags; done
2420
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2421
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
2422
+ - echo 'Uploading SBOM to Dependency Track'
2423
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/worker" "https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
2424
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2425
+ environment:
2426
+ name: stage/worker
2427
+ url: $CL_GITLAB_ENVIRONMENT_URL
2428
+ on_stop: 'worker ๐Ÿ›‘ Stop โš ๏ธ | stage '
2429
+ artifacts:
2430
+ reports:
2431
+ dotenv: gitlab_environment.env
2432
+ rules:
2433
+ - when: on_success
2434
+ if: $CI_COMMIT_TAG
2435
+ needs:
2436
+ - job: 'worker ๐Ÿ”จ app | stage '
2437
+ artifacts: false
2438
+ - job: 'worker ๐Ÿ”จ docker | stage '
2439
+ artifacts: false
2440
+ - job: 'worker ๐Ÿงพ sbom | stage '
2441
+ artifacts: true
2442
+ retry: *a1
2443
+ interruptible: true
2444
+ allow_failure: false
2445
+ 'worker ๐Ÿ›‘ Stop โš ๏ธ | stage ':
2446
+ stage: stop stage
2447
+ image: path/to/docker/gcloud:the-version
2448
+ variables:
2449
+ KUBERNETES_CPU_REQUEST: '0.22'
2450
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2451
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2452
+ GIT_STRATEGY: none
2453
+ script:
2454
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2455
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2456
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2457
+ - set +e
2458
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_worker_GCLOUD_DEPLOY_credentialsKey")
2459
+ - gcloud run services delete pan-test-app-stage-worker --project=google-project-id --region=europe-west6
2460
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/worker --quiet --delete-tags
2461
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2462
+ - echo 'Disabling component in Dependency Track'
2463
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/worker" "https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
2464
+ - set -e
2465
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-worker-$CL_stage_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2466
+ environment:
2467
+ name: stage/worker
2468
+ url: $CL_GITLAB_ENVIRONMENT_URL
2469
+ action: stop
2470
+ artifacts:
2471
+ reports:
2472
+ dotenv: gitlab_environment.env
2473
+ rules:
2474
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2475
+ when: on_success
2476
+ - when: manual
2477
+ if: $CI_COMMIT_TAG
2478
+ needs: []
2479
+ retry: *a1
2480
+ interruptible: true
2481
+ allow_failure: true
2482
+ 'worker ๐Ÿ”จ app | prod ':
2483
+ stage: build
2484
+ image: path/to/docker/jobs-default:the-version
2485
+ variables:
2486
+ KUBERNETES_CPU_REQUEST: '0.45'
2487
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2488
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2489
+ script:
2490
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2491
+ - export ENV_SHORT="prod"
2492
+ - export APP_DIR="api"
2493
+ - export ENV_TYPE="prod"
2494
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2495
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2496
+ - 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")"
2497
+ - export HOST="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2498
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2499
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2500
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2501
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2502
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2503
+ - export DB_NAME="pan-test-app-prod-api"
2504
+ - export DB_USER="my-user"
2505
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
2506
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
2507
+ - 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"
2508
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2509
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2510
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_worker_GCLOUD_DEPLOY_credentialsKey"
2511
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix"
2512
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
2513
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2514
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
2515
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2516
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2517
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2518
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2519
+ - cd api
2520
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2521
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2522
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2523
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2524
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
2525
+ - yarn install --immutable
2526
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
2527
+ - yarn build:worker
2528
+ cache:
2529
+ - key: api-yarn
2530
+ policy: pull-push
2531
+ paths:
2532
+ - api/.yarn
2533
+ - key: api-node-modules
2534
+ policy: pull-push
2535
+ paths:
2536
+ - api/node_modules
2537
+ - key: worker-next-cache
2538
+ policy: pull-push
2539
+ paths:
2540
+ - api/.next/cache
2541
+ artifacts:
2542
+ paths:
2543
+ - api/__build_info.json
2544
+ - api/.next
2545
+ - api/dist
2546
+ expire_in: 1 day
2547
+ when: always
2548
+ reports: {}
2549
+ rules:
2550
+ - if: $CI_COMMIT_TAG
2551
+ needs: []
2552
+ retry: *a1
2553
+ interruptible: true
2554
+ 'worker ๐Ÿ”จ docker | prod ':
2555
+ stage: build
2556
+ image: path/to/docker/docker-build:the-version
2557
+ services:
2558
+ - name: docker:24.0.6-dind
2559
+ command:
2560
+ - --tls=false
2561
+ variables:
2562
+ DOCKER_HOST: tcp://0.0.0.0:2375
2563
+ DOCKER_TLS_CERTDIR: ''
2564
+ DOCKER_DRIVER: overlay2
2565
+ DOCKER_BUILDKIT: '1'
2566
+ KUBERNETES_CPU_REQUEST: '0.45'
2567
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2568
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2569
+ script:
2570
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2571
+ - export APP_DIR="api"
2572
+ - export DOCKER_BUILD_CONTEXT="."
2573
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2574
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/worker"
2575
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
2576
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2577
+ - |-
2578
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2579
+ RUN yarn plugin import workspace-tools
2580
+ RUN yarn workspaces focus --production && yarn rebuild"
2581
+ - |-
2582
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
2583
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
2584
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2585
+ COPY --chown=node:node .yarn /app/.yarn"
2586
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2587
+ - ensureNodeDockerfile
2588
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
2589
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_worker_GCLOUD_DEPLOY_credentialsKey")
2590
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
2591
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
2592
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
2593
+ - 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
2594
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
2595
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
2596
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2597
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2598
+ - docker push $DOCKER_CACHE_IMAGE
2599
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
2600
+ cache:
2601
+ - key: api-yarn
2602
+ policy: pull
2603
+ paths:
2604
+ - api/.yarn
2605
+ rules:
2606
+ - if: $CI_COMMIT_TAG
2607
+ needs:
2608
+ - 'worker ๐Ÿ”จ app | prod '
2609
+ retry: *a1
2610
+ interruptible: true
2611
+ 'worker ๐Ÿงพ sbom | prod ':
2612
+ stage: build
2613
+ image: aquasec/trivy:0.38.3
2614
+ variables: {}
2615
+ script:
2616
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2617
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2618
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
2619
+ artifacts:
2620
+ paths:
2621
+ - __sbom.json
2622
+ rules:
2623
+ - if: $CI_COMMIT_TAG
2624
+ needs: []
2625
+ retry: *a1
2626
+ interruptible: true
2627
+ allow_failure: true
2628
+ 'worker ๐Ÿš€ Deploy | prod ':
2629
+ stage: deploy prod
2630
+ image: path/to/docker/gcloud:the-version
2631
+ variables:
2632
+ KUBERNETES_CPU_REQUEST: '0.22'
2633
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2634
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2635
+ script:
2636
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2637
+ - export ENV_SHORT="prod"
2638
+ - export APP_DIR="api"
2639
+ - export ENV_TYPE="prod"
2640
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2641
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2642
+ - 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")"
2643
+ - export HOST="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2644
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2645
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2646
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2647
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
2648
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
2649
+ - export DB_NAME="pan-test-app-prod-api"
2650
+ - export DB_USER="my-user"
2651
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
2652
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
2653
+ - 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"
2654
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
2655
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
2656
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_worker_GCLOUD_DEPLOY_credentialsKey"
2657
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix"
2658
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"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\\"]"
2659
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
2660
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/worker"
2661
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker"
2662
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2663
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2664
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2665
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
2666
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_worker_GCLOUD_DEPLOY_credentialsKey")
2667
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
2668
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2669
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
2670
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
2671
+ - |
2672
+ cat > ____envvars.yaml <<EOF
2673
+ ENV_SHORT: |-
2674
+ prod
2675
+ APP_DIR: |-
2676
+ api
2677
+ ENV_TYPE: |-
2678
+ prod
2679
+ BUILD_INFO_BUILD_ID: |-
2680
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2681
+ BUILD_INFO_BUILD_TIME: |-
2682
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2683
+ BUILD_INFO_CURRENT_VERSION: |-
2684
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
2685
+ HOST: |-
2686
+ $(printf %s "$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2687
+ ROOT_URL: |-
2688
+ $(printf %s "https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2689
+ HOST_INTERNAL: |-
2690
+ $(printf %s "$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2691
+ HOST_CANONICAL: |-
2692
+ $(printf %s "$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2693
+ ROOT_URL_INTERNAL: |-
2694
+ $(printf %s "https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2695
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
2696
+ projectId:region:instancename
2697
+ DB_NAME: |-
2698
+ pan-test-app-prod-api
2699
+ DB_USER: |-
2700
+ my-user
2701
+ DB_PASSWORD: |-
2702
+ $(printf %s "$CL_prod_api_DB_PASSWORD" | sed 's/^/ /')
2703
+ DATABASE_URL: |-
2704
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
2705
+ DATABASE_JDBC_URL: |-
2706
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
2707
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2708
+ google-project-id
2709
+ DEPLOY_CLOUD_RUN_REGION: |-
2710
+ europe-west6
2711
+ GCLOUD_RUN_canonicalHostSuffix: |-
2712
+ $(printf %s "$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
2713
+ _ALL_ENV_VAR_KEYS: |-
2714
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","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"]
2715
+
2716
+ EOF
2717
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
2718
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
2719
+ - set +e
2720
+ - echo "ensuring Database..."
2721
+ - gcloud sql databases create pan-test-app-prod-api --instance=instancename --project projectId
2722
+ - set -e
2723
+ - gcloud run deploy pan-test-app-prod-worker --command="yarn,start" --image=europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/worker:$DOCKER_IMAGE_TAG --project=google-project-id --region=europe-west6 --set-cloudsql-instances=projectId:region:instancename --labels=customer-name=pan,component-name=worker,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-service-name=pan-test-app-prod-worker --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
2724
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
2725
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
2726
+ - gcloud run revisions list --project=google-project-id --region=europe-west6 --service=pan-test-app-prod-worker --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
2727
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/worker --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/worker@$version --quiet --delete-tags; done
2728
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2729
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
2730
+ - echo 'Uploading SBOM to Dependency Track'
2731
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/worker" "https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
2732
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2733
+ environment:
2734
+ name: prod/worker
2735
+ url: $CL_GITLAB_ENVIRONMENT_URL
2736
+ on_stop: 'worker ๐Ÿ›‘ Stop โš ๏ธ | prod '
2737
+ artifacts:
2738
+ reports:
2739
+ dotenv: gitlab_environment.env
2740
+ rules:
2741
+ - when: manual
2742
+ if: $CI_COMMIT_TAG
2743
+ needs:
2744
+ - job: 'worker ๐Ÿ”จ app | prod '
2745
+ artifacts: false
2746
+ - job: 'worker ๐Ÿ”จ docker | prod '
2747
+ artifacts: false
2748
+ - job: 'worker ๐Ÿงพ sbom | prod '
2749
+ artifacts: true
2750
+ retry: *a1
2751
+ interruptible: true
2752
+ allow_failure: true
2753
+ 'worker ๐Ÿ›‘ Stop โš ๏ธ | prod ':
2754
+ stage: stop prod
2755
+ image: path/to/docker/gcloud:the-version
2756
+ variables:
2757
+ KUBERNETES_CPU_REQUEST: '0.22'
2758
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2759
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2760
+ GIT_STRATEGY: none
2761
+ script:
2762
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2763
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2764
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2765
+ - set +e
2766
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_worker_GCLOUD_DEPLOY_credentialsKey")
2767
+ - gcloud run services delete pan-test-app-prod-worker --project=google-project-id --region=europe-west6
2768
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/worker --quiet --delete-tags
2769
+ - gcloud artifacts docker images list europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/worker --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/worker@$version --quiet --delete-tags; done
2770
+ - echo 'Disabling component in Dependency Track'
2771
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/worker" "https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
2772
+ - set -e
2773
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-worker-$CL_prod_worker_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2774
+ environment:
2775
+ name: prod/worker
2776
+ url: $CL_GITLAB_ENVIRONMENT_URL
2777
+ action: stop
2778
+ artifacts:
2779
+ reports:
2780
+ dotenv: gitlab_environment.env
2781
+ rules:
2782
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2783
+ when: on_success
2784
+ - when: manual
2785
+ if: $CI_COMMIT_TAG
2786
+ needs: []
2787
+ retry: *a1
2788
+ interruptible: true
2789
+ allow_failure: true
2790
+ create release:
2791
+ stage: release
2792
+ image: path/to/docker/semantic-release:the-version
2793
+ script:
2794
+ - semanticRelease
2795
+ after_script:
2796
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
2797
+ rules:
2798
+ - &a2
2799
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
2800
+ when: never
2801
+ - &a3
2802
+ if: $CI_PIPELINE_SOURCE == "schedule"
2803
+ when: never
2804
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $AUTO_RELEASE == "true"
2805
+ when: on_success
2806
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
2807
+ when: manual
2808
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
2809
+ when: manual
2810
+ โš ๏ธ force create release:
2811
+ stage: release
2812
+ image: path/to/docker/semantic-release:the-version
2813
+ script:
2814
+ - semanticRelease
2815
+ after_script:
2816
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
2817
+ rules:
2818
+ - *a2
2819
+ - *a3
2820
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
2821
+ when: manual
2822
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
2823
+ when: manual
2824
+ needs: []
2825
+ "
2826
+ `;
2827
+
3
2828
  exports[`matches snapshot for cloud-run-with-sql-reuse-db 1`] = `
4
2829
  {
5
2830
  "mainBranch": {