@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,3381 @@
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 DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
177
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
178
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
179
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
180
+ - export foo="foo-value"
181
+ - |-
182
+ export multiline="line1
183
+ line2
184
+ line3
185
+
186
+ single quote: '
187
+ doouble quote: \\"
188
+ "
189
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
190
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
191
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
192
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
193
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
194
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
195
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
196
+ - cd api
197
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
198
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
199
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
200
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
201
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
202
+ - yarn install --immutable
203
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
204
+ - yarn build
205
+ cache:
206
+ - key: api-yarn
207
+ policy: pull-push
208
+ paths:
209
+ - api/.yarn
210
+ - key: api-node-modules
211
+ policy: pull-push
212
+ paths:
213
+ - api/node_modules
214
+ - key: api-next-cache
215
+ policy: pull-push
216
+ paths:
217
+ - api/.next/cache
218
+ artifacts:
219
+ paths:
220
+ - api/__build_info.json
221
+ - api/.next
222
+ - api/dist
223
+ expire_in: 1 day
224
+ when: always
225
+ reports: {}
226
+ rules:
227
+ - when: never
228
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
229
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
230
+ needs: []
231
+ retry: *a1
232
+ interruptible: true
233
+ 'api 🔨 docker | dev ':
234
+ stage: build
235
+ image: path/to/docker/docker-build:the-version
236
+ services:
237
+ - name: docker:24.0.6-dind
238
+ command:
239
+ - --tls=false
240
+ variables:
241
+ DOCKER_HOST: tcp://0.0.0.0:2375
242
+ DOCKER_TLS_CERTDIR: ''
243
+ DOCKER_DRIVER: overlay2
244
+ DOCKER_BUILDKIT: '1'
245
+ KUBERNETES_CPU_REQUEST: '0.45'
246
+ KUBERNETES_MEMORY_REQUEST: 1Gi
247
+ KUBERNETES_MEMORY_LIMIT: 2Gi
248
+ script:
249
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
250
+ - export APP_DIR="api"
251
+ - export DOCKER_BUILD_CONTEXT="."
252
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
253
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api"
254
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
255
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
256
+ - |-
257
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
258
+ RUN yarn plugin import workspace-tools
259
+ RUN yarn workspaces focus --production && yarn rebuild"
260
+ - |-
261
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
262
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
263
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
264
+ COPY --chown=node:node .yarn /app/.yarn"
265
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
266
+ - ensureNodeDockerfile
267
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
268
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
269
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
270
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
271
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
272
+ - 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
273
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
274
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
275
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
276
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
277
+ - docker push $DOCKER_CACHE_IMAGE
278
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
279
+ cache:
280
+ - key: api-yarn
281
+ policy: pull
282
+ paths:
283
+ - api/.yarn
284
+ rules:
285
+ - when: never
286
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
287
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
288
+ needs:
289
+ - 'api 🔨 app | dev '
290
+ retry: *a1
291
+ interruptible: true
292
+ 'api 🧾 sbom | dev ':
293
+ stage: build
294
+ image: aquasec/trivy:0.38.3
295
+ variables: {}
296
+ script:
297
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
298
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
299
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
300
+ artifacts:
301
+ paths:
302
+ - __sbom.json
303
+ rules:
304
+ - when: never
305
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
306
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
307
+ needs: []
308
+ retry: *a1
309
+ interruptible: true
310
+ allow_failure: true
311
+ 'api 🚀 Deploy | dev ':
312
+ stage: deploy dev
313
+ image: path/to/docker/gcloud:the-version
314
+ variables:
315
+ KUBERNETES_CPU_REQUEST: '0.22'
316
+ KUBERNETES_MEMORY_REQUEST: 200Mi
317
+ KUBERNETES_MEMORY_LIMIT: 400Mi
318
+ script:
319
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
320
+ - export ENV_SHORT="dev"
321
+ - export APP_DIR="api"
322
+ - export ENV_TYPE="dev"
323
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
324
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
325
+ - 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")"
326
+ - export HOST="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
327
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
328
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
329
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
330
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
331
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
332
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
333
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
334
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
335
+ - export foo="foo-value"
336
+ - |-
337
+ export multiline="line1
338
+ line2
339
+ line3
340
+
341
+ single quote: '
342
+ doouble quote: \\"
343
+ "
344
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
345
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
346
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api"
347
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
348
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
349
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
350
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
351
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
352
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
353
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
354
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
355
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
356
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
357
+ - |
358
+ cat > ____envvars.yaml <<EOF
359
+ ENV_SHORT: |-
360
+ dev
361
+ APP_DIR: |-
362
+ api
363
+ ENV_TYPE: |-
364
+ dev
365
+ BUILD_INFO_BUILD_ID: |-
366
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
367
+ BUILD_INFO_BUILD_TIME: |-
368
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
369
+ BUILD_INFO_CURRENT_VERSION: |-
370
+ $(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/^/ /')
371
+ HOST: |-
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: |-
374
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
375
+ HOST_INTERNAL: |-
376
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
377
+ HOST_CANONICAL: |-
378
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
379
+ ROOT_URL_INTERNAL: |-
380
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
381
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
382
+ asdf
383
+ DEPLOY_CLOUD_RUN_REGION: |-
384
+ asia-east1
385
+ GCLOUD_RUN_canonicalHostSuffix: |-
386
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
387
+ foo: |-
388
+ foo-value
389
+ multiline: |
390
+ line1
391
+ line2
392
+ line3
393
+
394
+ single quote: '
395
+ doouble quote: "
396
+ _ALL_ENV_VAR_KEYS: |-
397
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","foo","multiline"]
398
+
399
+ EOF
400
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
401
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
402
+ - gcloud run deploy pan-test-app-dev-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --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
403
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
404
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
405
+ - gcloud run revisions list --project=asdf --region=asia-east1 --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=asdf --region=asia-east1 --quiet $revisionname ; done
406
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api@$version --quiet --delete-tags; done
407
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
408
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
409
+ - echo 'Uploading SBOM to Dependency Track'
410
+ - /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
411
+ - 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
412
+ environment:
413
+ name: dev/api
414
+ url: $CL_GITLAB_ENVIRONMENT_URL
415
+ on_stop: 'api 🛑 Stop ⚠️ | dev '
416
+ auto_stop_in: 4 weeks
417
+ artifacts:
418
+ reports:
419
+ dotenv: gitlab_environment.env
420
+ rules:
421
+ - when: never
422
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
423
+ - when: on_success
424
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
425
+ needs:
426
+ - job: api 👮 lint
427
+ artifacts: false
428
+ - job: 'api 🔨 app | dev '
429
+ artifacts: false
430
+ - job: 'api 🔨 docker | dev '
431
+ artifacts: false
432
+ - job: api 🧪 test
433
+ artifacts: false
434
+ - job: 'api 🧾 sbom | dev '
435
+ artifacts: true
436
+ - job: api 🛡 audit
437
+ artifacts: false
438
+ retry: *a1
439
+ interruptible: true
440
+ allow_failure: false
441
+ 'api 🛑 Stop ⚠️ | dev ':
442
+ stage: stop dev
443
+ image: path/to/docker/gcloud:the-version
444
+ variables:
445
+ KUBERNETES_CPU_REQUEST: '0.22'
446
+ KUBERNETES_MEMORY_REQUEST: 200Mi
447
+ KUBERNETES_MEMORY_LIMIT: 400Mi
448
+ GIT_STRATEGY: none
449
+ script:
450
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
451
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
452
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
453
+ - set +e
454
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
455
+ - gcloud run services delete pan-test-app-dev-api --project=asdf --region=asia-east1
456
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
457
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
458
+ - echo 'Disabling component in Dependency Track'
459
+ - /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
460
+ - set -e
461
+ - 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
462
+ environment:
463
+ name: dev/api
464
+ url: $CL_GITLAB_ENVIRONMENT_URL
465
+ action: stop
466
+ artifacts:
467
+ reports:
468
+ dotenv: gitlab_environment.env
469
+ rules:
470
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
471
+ when: on_success
472
+ - when: never
473
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
474
+ - when: manual
475
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
476
+ needs: []
477
+ retry: *a1
478
+ interruptible: true
479
+ allow_failure: true
480
+ 'api 🔨 app | review ':
481
+ stage: build
482
+ image: path/to/docker/jobs-default:the-version
483
+ variables:
484
+ KUBERNETES_CPU_REQUEST: '0.45'
485
+ KUBERNETES_MEMORY_REQUEST: 1Gi
486
+ KUBERNETES_MEMORY_LIMIT: 4Gi
487
+ script:
488
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
489
+ - export ENV_SHORT="review"
490
+ - export APP_DIR="api"
491
+ - export ENV_TYPE="review"
492
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
493
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
494
+ - 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")"
495
+ - 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)}')"
496
+ - 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)}')"
497
+ - 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)}')"
498
+ - 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)}')"
499
+ - 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)}')"
500
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
501
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
502
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
503
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
504
+ - export foo="foo-value"
505
+ - |-
506
+ export multiline="line1
507
+ line2
508
+ line3
509
+
510
+ single quote: '
511
+ doouble quote: \\"
512
+ "
513
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
514
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
515
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
516
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
517
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
518
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
519
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
520
+ - cd api
521
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
522
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
523
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
524
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
525
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
526
+ - yarn install --immutable
527
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
528
+ - yarn build
529
+ cache:
530
+ - key: api-yarn
531
+ policy: pull-push
532
+ paths:
533
+ - api/.yarn
534
+ - key: api-node-modules
535
+ policy: pull-push
536
+ paths:
537
+ - api/node_modules
538
+ - key: api-next-cache
539
+ policy: pull-push
540
+ paths:
541
+ - api/.next/cache
542
+ artifacts:
543
+ paths:
544
+ - api/__build_info.json
545
+ - api/.next
546
+ - api/dist
547
+ expire_in: 1 day
548
+ when: always
549
+ reports: {}
550
+ rules:
551
+ - if: $CI_MERGE_REQUEST_ID
552
+ needs: []
553
+ retry: *a1
554
+ interruptible: true
555
+ 'api 🔨 docker | review ':
556
+ stage: build
557
+ image: path/to/docker/docker-build:the-version
558
+ services:
559
+ - name: docker:24.0.6-dind
560
+ command:
561
+ - --tls=false
562
+ variables:
563
+ DOCKER_HOST: tcp://0.0.0.0:2375
564
+ DOCKER_TLS_CERTDIR: ''
565
+ DOCKER_DRIVER: overlay2
566
+ DOCKER_BUILDKIT: '1'
567
+ KUBERNETES_CPU_REQUEST: '0.45'
568
+ KUBERNETES_MEMORY_REQUEST: 1Gi
569
+ KUBERNETES_MEMORY_LIMIT: 2Gi
570
+ script:
571
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
572
+ - export APP_DIR="api"
573
+ - export DOCKER_BUILD_CONTEXT="."
574
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
575
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/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"; })"
576
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
577
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
578
+ - |-
579
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
580
+ RUN yarn plugin import workspace-tools
581
+ RUN yarn workspaces focus --production && yarn rebuild"
582
+ - |-
583
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
584
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
585
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
586
+ COPY --chown=node:node .yarn /app/.yarn"
587
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
588
+ - ensureNodeDockerfile
589
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
590
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
591
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
592
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
593
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
594
+ - docker build --network host --cache-from $DOCKER_CACHE_IMAGE --tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG -f $APP_DIR/Dockerfile $DOCKER_BUILD_CONTEXT --build-arg BUILDKIT_INLINE_CACHE=1
595
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
596
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
597
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
598
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
599
+ - docker push $DOCKER_CACHE_IMAGE
600
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
601
+ cache:
602
+ - key: api-yarn
603
+ policy: pull
604
+ paths:
605
+ - api/.yarn
606
+ rules:
607
+ - if: $CI_MERGE_REQUEST_ID
608
+ needs:
609
+ - 'api 🔨 app | review '
610
+ retry: *a1
611
+ interruptible: true
612
+ 'api 🧾 sbom | review ':
613
+ stage: build
614
+ image: aquasec/trivy:0.38.3
615
+ variables: {}
616
+ script:
617
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
618
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
619
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
620
+ artifacts:
621
+ paths:
622
+ - __sbom.json
623
+ rules:
624
+ - if: $CI_MERGE_REQUEST_ID
625
+ needs: []
626
+ retry: *a1
627
+ interruptible: true
628
+ allow_failure: true
629
+ 'api 🚀 Deploy | review ':
630
+ stage: deploy review
631
+ image: path/to/docker/gcloud:the-version
632
+ variables:
633
+ KUBERNETES_CPU_REQUEST: '0.22'
634
+ KUBERNETES_MEMORY_REQUEST: 200Mi
635
+ KUBERNETES_MEMORY_LIMIT: 400Mi
636
+ script:
637
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
638
+ - export ENV_SHORT="review"
639
+ - export APP_DIR="api"
640
+ - export ENV_TYPE="review"
641
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
642
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
643
+ - export BUILD_INFO_CURRENT_VERSION="$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")"
644
+ - export 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)}')"
645
+ - export ROOT_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
646
+ - 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)}')"
647
+ - 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)}')"
648
+ - 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)}')"
649
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
650
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
651
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
652
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
653
+ - export foo="foo-value"
654
+ - |-
655
+ export multiline="line1
656
+ line2
657
+ line3
658
+
659
+ single quote: '
660
+ doouble quote: \\"
661
+ "
662
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
663
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
664
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/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"; })"
665
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
666
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
667
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
668
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
669
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
670
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
671
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
672
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
673
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
674
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
675
+ - |
676
+ cat > ____envvars.yaml <<EOF
677
+ ENV_SHORT: |-
678
+ review
679
+ APP_DIR: |-
680
+ api
681
+ ENV_TYPE: |-
682
+ review
683
+ BUILD_INFO_BUILD_ID: |-
684
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
685
+ BUILD_INFO_BUILD_TIME: |-
686
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
687
+ BUILD_INFO_CURRENT_VERSION: |-
688
+ $(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/^/ /')
689
+ HOST: |-
690
+ $(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/^/ /')
691
+ ROOT_URL: |-
692
+ $(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/^/ /')
693
+ HOST_INTERNAL: |-
694
+ $(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/^/ /')
695
+ HOST_CANONICAL: |-
696
+ $(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/^/ /')
697
+ ROOT_URL_INTERNAL: |-
698
+ $(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/^/ /')
699
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
700
+ asdf
701
+ DEPLOY_CLOUD_RUN_REGION: |-
702
+ asia-east1
703
+ GCLOUD_RUN_canonicalHostSuffix: |-
704
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
705
+ foo: |-
706
+ foo-value
707
+ multiline: |
708
+ line1
709
+ line2
710
+ line3
711
+
712
+ single quote: '
713
+ doouble quote: "
714
+ _ALL_ENV_VAR_KEYS: |-
715
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","foo","multiline"]
716
+
717
+ EOF
718
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
719
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
720
+ - 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=asia-east1-docker.pkg.dev/asdf/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=asdf --region=asia-east1 --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
721
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
722
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
723
+ - gcloud run revisions list --project=asdf --region=asia-east1 --service=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-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=asdf --region=asia-east1 --quiet $revisionname ; done
724
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/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
725
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
726
+ - set +e
727
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
728
+ - set -e
729
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
730
+ - echo 'Uploading SBOM to Dependency Track'
731
+ - /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
732
+ - 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
733
+ environment:
734
+ name: review/$CI_COMMIT_REF_NAME/api
735
+ url: $CL_GITLAB_ENVIRONMENT_URL
736
+ on_stop: 'api 🛑 Stop ⚠️ | review '
737
+ auto_stop_in: 1 week
738
+ artifacts:
739
+ reports:
740
+ dotenv: gitlab_environment.env
741
+ rules:
742
+ - when: on_success
743
+ if: $CI_MERGE_REQUEST_ID
744
+ needs:
745
+ - job: api 👮 lint
746
+ artifacts: false
747
+ - job: 'api 🔨 app | review '
748
+ artifacts: false
749
+ - job: 'api 🔨 docker | review '
750
+ artifacts: false
751
+ - job: api 🧪 test
752
+ artifacts: false
753
+ - job: 'api 🧾 sbom | review '
754
+ artifacts: true
755
+ - job: api 🛡 audit
756
+ artifacts: false
757
+ retry: *a1
758
+ interruptible: true
759
+ allow_failure: false
760
+ 'api 🛑 Stop ⚠️ | review ':
761
+ stage: stop review
762
+ image: path/to/docker/gcloud:the-version
763
+ variables:
764
+ KUBERNETES_CPU_REQUEST: '0.22'
765
+ KUBERNETES_MEMORY_REQUEST: 200Mi
766
+ KUBERNETES_MEMORY_LIMIT: 400Mi
767
+ GIT_STRATEGY: none
768
+ script:
769
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
770
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
771
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
772
+ - set +e
773
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
774
+ - 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=asdf --region=asia-east1
775
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/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
776
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
777
+ - set +e
778
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
779
+ - set -e
780
+ - echo 'Disabling component in Dependency Track'
781
+ - /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
782
+ - set -e
783
+ - 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
784
+ environment:
785
+ name: review/$CI_COMMIT_REF_NAME/api
786
+ url: $CL_GITLAB_ENVIRONMENT_URL
787
+ action: stop
788
+ artifacts:
789
+ reports:
790
+ dotenv: gitlab_environment.env
791
+ rules:
792
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
793
+ when: on_success
794
+ - when: manual
795
+ if: $CI_MERGE_REQUEST_ID
796
+ needs: []
797
+ retry: *a1
798
+ interruptible: true
799
+ allow_failure: true
800
+ 'api 🔨 app | stage ':
801
+ stage: build
802
+ image: path/to/docker/jobs-default:the-version
803
+ variables:
804
+ KUBERNETES_CPU_REQUEST: '0.45'
805
+ KUBERNETES_MEMORY_REQUEST: 1Gi
806
+ KUBERNETES_MEMORY_LIMIT: 4Gi
807
+ script:
808
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
809
+ - export ENV_SHORT="stage"
810
+ - export APP_DIR="api"
811
+ - export ENV_TYPE="stage"
812
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
813
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
814
+ - 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")"
815
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
816
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
817
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
818
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
819
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
820
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
821
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
822
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
823
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
824
+ - export foo="foo-value"
825
+ - |-
826
+ export multiline="line1
827
+ line2
828
+ line3
829
+
830
+ single quote: '
831
+ doouble quote: \\"
832
+ "
833
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
834
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
835
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
836
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
837
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
838
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
839
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
840
+ - cd api
841
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
842
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
843
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
844
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
845
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
846
+ - yarn install --immutable
847
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
848
+ - yarn build
849
+ cache:
850
+ - key: api-yarn
851
+ policy: pull-push
852
+ paths:
853
+ - api/.yarn
854
+ - key: api-node-modules
855
+ policy: pull-push
856
+ paths:
857
+ - api/node_modules
858
+ - key: api-next-cache
859
+ policy: pull-push
860
+ paths:
861
+ - api/.next/cache
862
+ artifacts:
863
+ paths:
864
+ - api/__build_info.json
865
+ - api/.next
866
+ - api/dist
867
+ expire_in: 1 day
868
+ when: always
869
+ reports: {}
870
+ rules:
871
+ - if: $CI_COMMIT_TAG
872
+ needs: []
873
+ retry: *a1
874
+ interruptible: true
875
+ 'api 🔨 docker | stage ':
876
+ stage: build
877
+ image: path/to/docker/docker-build:the-version
878
+ services:
879
+ - name: docker:24.0.6-dind
880
+ command:
881
+ - --tls=false
882
+ variables:
883
+ DOCKER_HOST: tcp://0.0.0.0:2375
884
+ DOCKER_TLS_CERTDIR: ''
885
+ DOCKER_DRIVER: overlay2
886
+ DOCKER_BUILDKIT: '1'
887
+ KUBERNETES_CPU_REQUEST: '0.45'
888
+ KUBERNETES_MEMORY_REQUEST: 1Gi
889
+ KUBERNETES_MEMORY_LIMIT: 2Gi
890
+ script:
891
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
892
+ - export APP_DIR="api"
893
+ - export DOCKER_BUILD_CONTEXT="."
894
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
895
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api"
896
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
897
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
898
+ - |-
899
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
900
+ RUN yarn plugin import workspace-tools
901
+ RUN yarn workspaces focus --production && yarn rebuild"
902
+ - |-
903
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
904
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
905
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
906
+ COPY --chown=node:node .yarn /app/.yarn"
907
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
908
+ - ensureNodeDockerfile
909
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
910
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
911
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
912
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
913
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
914
+ - 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
915
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
916
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
917
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
918
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
919
+ - docker push $DOCKER_CACHE_IMAGE
920
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
921
+ cache:
922
+ - key: api-yarn
923
+ policy: pull
924
+ paths:
925
+ - api/.yarn
926
+ rules:
927
+ - if: $CI_COMMIT_TAG
928
+ needs:
929
+ - 'api 🔨 app | stage '
930
+ retry: *a1
931
+ interruptible: true
932
+ 'api 🧾 sbom | stage ':
933
+ stage: build
934
+ image: aquasec/trivy:0.38.3
935
+ variables: {}
936
+ script:
937
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
938
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
939
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
940
+ artifacts:
941
+ paths:
942
+ - __sbom.json
943
+ rules:
944
+ - if: $CI_COMMIT_TAG
945
+ needs: []
946
+ retry: *a1
947
+ interruptible: true
948
+ allow_failure: true
949
+ 'api 🚀 Deploy | stage ':
950
+ stage: deploy stage
951
+ image: path/to/docker/gcloud:the-version
952
+ variables:
953
+ KUBERNETES_CPU_REQUEST: '0.22'
954
+ KUBERNETES_MEMORY_REQUEST: 200Mi
955
+ KUBERNETES_MEMORY_LIMIT: 400Mi
956
+ script:
957
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
958
+ - export ENV_SHORT="stage"
959
+ - export APP_DIR="api"
960
+ - export ENV_TYPE="stage"
961
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
962
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
963
+ - 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")"
964
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
965
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
966
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
967
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
968
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
969
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
970
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
971
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
972
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
973
+ - export foo="foo-value"
974
+ - |-
975
+ export multiline="line1
976
+ line2
977
+ line3
978
+
979
+ single quote: '
980
+ doouble quote: \\"
981
+ "
982
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
983
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
984
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api"
985
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
986
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
987
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
988
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
989
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
990
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
991
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
992
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
993
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
994
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
995
+ - |
996
+ cat > ____envvars.yaml <<EOF
997
+ ENV_SHORT: |-
998
+ stage
999
+ APP_DIR: |-
1000
+ api
1001
+ ENV_TYPE: |-
1002
+ stage
1003
+ BUILD_INFO_BUILD_ID: |-
1004
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1005
+ BUILD_INFO_BUILD_TIME: |-
1006
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1007
+ BUILD_INFO_CURRENT_VERSION: |-
1008
+ $(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/^/ /')
1009
+ HOST: |-
1010
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1011
+ ROOT_URL: |-
1012
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1013
+ HOST_INTERNAL: |-
1014
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1015
+ HOST_CANONICAL: |-
1016
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1017
+ ROOT_URL_INTERNAL: |-
1018
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1019
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1020
+ asdf
1021
+ DEPLOY_CLOUD_RUN_REGION: |-
1022
+ asia-east1
1023
+ GCLOUD_RUN_canonicalHostSuffix: |-
1024
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1025
+ foo: |-
1026
+ foo-value
1027
+ multiline: |
1028
+ line1
1029
+ line2
1030
+ line3
1031
+
1032
+ single quote: '
1033
+ doouble quote: "
1034
+ _ALL_ENV_VAR_KEYS: |-
1035
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","foo","multiline"]
1036
+
1037
+ EOF
1038
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1039
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1040
+ - gcloud run deploy pan-test-app-stage-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --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
1041
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1042
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1043
+ - gcloud run revisions list --project=asdf --region=asia-east1 --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=asdf --region=asia-east1 --quiet $revisionname ; done
1044
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api@$version --quiet --delete-tags; done
1045
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1046
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1047
+ - echo 'Uploading SBOM to Dependency Track'
1048
+ - /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
1049
+ - 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
1050
+ environment:
1051
+ name: stage/api
1052
+ url: $CL_GITLAB_ENVIRONMENT_URL
1053
+ on_stop: 'api 🛑 Stop ⚠️ | stage '
1054
+ artifacts:
1055
+ reports:
1056
+ dotenv: gitlab_environment.env
1057
+ rules:
1058
+ - when: on_success
1059
+ if: $CI_COMMIT_TAG
1060
+ needs:
1061
+ - job: 'api 🔨 app | stage '
1062
+ artifacts: false
1063
+ - job: 'api 🔨 docker | stage '
1064
+ artifacts: false
1065
+ - job: 'api 🧾 sbom | stage '
1066
+ artifacts: true
1067
+ retry: *a1
1068
+ interruptible: true
1069
+ allow_failure: false
1070
+ 'api 🛑 Stop ⚠️ | stage ':
1071
+ stage: stop stage
1072
+ image: path/to/docker/gcloud:the-version
1073
+ variables:
1074
+ KUBERNETES_CPU_REQUEST: '0.22'
1075
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1076
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1077
+ GIT_STRATEGY: none
1078
+ script:
1079
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1080
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1081
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1082
+ - set +e
1083
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1084
+ - gcloud run services delete pan-test-app-stage-api --project=asdf --region=asia-east1
1085
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1086
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1087
+ - echo 'Disabling component in Dependency Track'
1088
+ - /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
1089
+ - set -e
1090
+ - 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
1091
+ environment:
1092
+ name: stage/api
1093
+ url: $CL_GITLAB_ENVIRONMENT_URL
1094
+ action: stop
1095
+ artifacts:
1096
+ reports:
1097
+ dotenv: gitlab_environment.env
1098
+ rules:
1099
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1100
+ when: on_success
1101
+ - when: manual
1102
+ if: $CI_COMMIT_TAG
1103
+ needs: []
1104
+ retry: *a1
1105
+ interruptible: true
1106
+ allow_failure: true
1107
+ 'api 🔨 app | prod ':
1108
+ stage: build
1109
+ image: path/to/docker/jobs-default:the-version
1110
+ variables:
1111
+ KUBERNETES_CPU_REQUEST: '0.45'
1112
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1113
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1114
+ script:
1115
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1116
+ - export ENV_SHORT="prod"
1117
+ - export APP_DIR="api"
1118
+ - export ENV_TYPE="prod"
1119
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1120
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1121
+ - 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")"
1122
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1123
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1124
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1125
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1126
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1127
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1128
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1129
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1130
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1131
+ - export foo="foo-value"
1132
+ - |-
1133
+ export multiline="line1
1134
+ line2
1135
+ line3
1136
+
1137
+ single quote: '
1138
+ doouble quote: \\"
1139
+ "
1140
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
1141
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1142
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1143
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1144
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1145
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1146
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1147
+ - cd api
1148
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1149
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1150
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1151
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1152
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1153
+ - yarn install --immutable
1154
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1155
+ - yarn build
1156
+ cache:
1157
+ - key: api-yarn
1158
+ policy: pull-push
1159
+ paths:
1160
+ - api/.yarn
1161
+ - key: api-node-modules
1162
+ policy: pull-push
1163
+ paths:
1164
+ - api/node_modules
1165
+ - key: api-next-cache
1166
+ policy: pull-push
1167
+ paths:
1168
+ - api/.next/cache
1169
+ artifacts:
1170
+ paths:
1171
+ - api/__build_info.json
1172
+ - api/.next
1173
+ - api/dist
1174
+ expire_in: 1 day
1175
+ when: always
1176
+ reports: {}
1177
+ rules:
1178
+ - if: $CI_COMMIT_TAG
1179
+ needs: []
1180
+ retry: *a1
1181
+ interruptible: true
1182
+ 'api 🔨 docker | prod ':
1183
+ stage: build
1184
+ image: path/to/docker/docker-build:the-version
1185
+ services:
1186
+ - name: docker:24.0.6-dind
1187
+ command:
1188
+ - --tls=false
1189
+ variables:
1190
+ DOCKER_HOST: tcp://0.0.0.0:2375
1191
+ DOCKER_TLS_CERTDIR: ''
1192
+ DOCKER_DRIVER: overlay2
1193
+ DOCKER_BUILDKIT: '1'
1194
+ KUBERNETES_CPU_REQUEST: '0.45'
1195
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1196
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1197
+ script:
1198
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1199
+ - export APP_DIR="api"
1200
+ - export DOCKER_BUILD_CONTEXT="."
1201
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1202
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api"
1203
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1204
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1205
+ - |-
1206
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1207
+ RUN yarn plugin import workspace-tools
1208
+ RUN yarn workspaces focus --production && yarn rebuild"
1209
+ - |-
1210
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1211
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1212
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1213
+ COPY --chown=node:node .yarn /app/.yarn"
1214
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1215
+ - ensureNodeDockerfile
1216
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1217
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1218
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
1219
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1220
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1221
+ - 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
1222
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1223
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1224
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1225
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1226
+ - docker push $DOCKER_CACHE_IMAGE
1227
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1228
+ cache:
1229
+ - key: api-yarn
1230
+ policy: pull
1231
+ paths:
1232
+ - api/.yarn
1233
+ rules:
1234
+ - if: $CI_COMMIT_TAG
1235
+ needs:
1236
+ - 'api 🔨 app | prod '
1237
+ retry: *a1
1238
+ interruptible: true
1239
+ 'api 🧾 sbom | prod ':
1240
+ stage: build
1241
+ image: aquasec/trivy:0.38.3
1242
+ variables: {}
1243
+ script:
1244
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1245
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1246
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1247
+ artifacts:
1248
+ paths:
1249
+ - __sbom.json
1250
+ rules:
1251
+ - if: $CI_COMMIT_TAG
1252
+ needs: []
1253
+ retry: *a1
1254
+ interruptible: true
1255
+ allow_failure: true
1256
+ 'api 🚀 Deploy | prod ':
1257
+ stage: deploy prod
1258
+ image: path/to/docker/gcloud:the-version
1259
+ variables:
1260
+ KUBERNETES_CPU_REQUEST: '0.22'
1261
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1262
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1263
+ script:
1264
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1265
+ - export ENV_SHORT="prod"
1266
+ - export APP_DIR="api"
1267
+ - export ENV_TYPE="prod"
1268
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1269
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1270
+ - 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")"
1271
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1272
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1273
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1274
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1275
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1276
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1277
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1278
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1279
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1280
+ - export foo="foo-value"
1281
+ - |-
1282
+ export multiline="line1
1283
+ line2
1284
+ line3
1285
+
1286
+ single quote: '
1287
+ doouble quote: \\"
1288
+ "
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\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\",\\"foo\\",\\"multiline\\"]"
1290
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1291
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api"
1292
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/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 asdf --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
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1327
+ asdf
1328
+ DEPLOY_CLOUD_RUN_REGION: |-
1329
+ asia-east1
1330
+ GCLOUD_RUN_canonicalHostSuffix: |-
1331
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1332
+ foo: |-
1333
+ foo-value
1334
+ multiline: |
1335
+ line1
1336
+ line2
1337
+ line3
1338
+
1339
+ single quote: '
1340
+ doouble quote: "
1341
+ _ALL_ENV_VAR_KEYS: |-
1342
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix","foo","multiline"]
1343
+
1344
+ EOF
1345
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1346
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1347
+ - gcloud run deploy pan-test-app-prod-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --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
1348
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1349
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1350
+ - gcloud run revisions list --project=asdf --region=asia-east1 --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=asdf --region=asia-east1 --quiet $revisionname ; done
1351
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api@$version --quiet --delete-tags; done
1352
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1353
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1354
+ - echo 'Uploading SBOM to Dependency Track'
1355
+ - /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
1356
+ - 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
1357
+ environment:
1358
+ name: prod/api
1359
+ url: $CL_GITLAB_ENVIRONMENT_URL
1360
+ on_stop: 'api 🛑 Stop ⚠️ | prod '
1361
+ artifacts:
1362
+ reports:
1363
+ dotenv: gitlab_environment.env
1364
+ rules:
1365
+ - when: manual
1366
+ if: $CI_COMMIT_TAG
1367
+ needs:
1368
+ - job: 'api 🔨 app | prod '
1369
+ artifacts: false
1370
+ - job: 'api 🔨 docker | prod '
1371
+ artifacts: false
1372
+ - job: 'api 🧾 sbom | prod '
1373
+ artifacts: true
1374
+ retry: *a1
1375
+ interruptible: true
1376
+ allow_failure: true
1377
+ 'api 🛑 Stop ⚠️ | prod ':
1378
+ stage: stop prod
1379
+ image: path/to/docker/gcloud:the-version
1380
+ variables:
1381
+ KUBERNETES_CPU_REQUEST: '0.22'
1382
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1383
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1384
+ GIT_STRATEGY: none
1385
+ script:
1386
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1387
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1388
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1389
+ - set +e
1390
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1391
+ - gcloud run services delete pan-test-app-prod-api --project=asdf --region=asia-east1
1392
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
1393
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/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 asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1394
+ - echo 'Disabling component in Dependency Track'
1395
+ - /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
1396
+ - set -e
1397
+ - 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
1398
+ environment:
1399
+ name: prod/api
1400
+ url: $CL_GITLAB_ENVIRONMENT_URL
1401
+ action: stop
1402
+ artifacts:
1403
+ reports:
1404
+ dotenv: gitlab_environment.env
1405
+ rules:
1406
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1407
+ when: on_success
1408
+ - when: manual
1409
+ if: $CI_COMMIT_TAG
1410
+ needs: []
1411
+ retry: *a1
1412
+ interruptible: true
1413
+ allow_failure: true
1414
+ api2 🛡 audit:
1415
+ stage: test
1416
+ image: path/to/docker/jobs-default:the-version
1417
+ variables:
1418
+ KUBERNETES_CPU_REQUEST: '0.45'
1419
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1420
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1421
+ script:
1422
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1423
+ - export APP_PATH="api"
1424
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1425
+ - cd api
1426
+ - yarn npm audit --environment production
1427
+ rules:
1428
+ - when: never
1429
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1430
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1431
+ - if: $CI_MERGE_REQUEST_ID
1432
+ needs: []
1433
+ retry: *a1
1434
+ interruptible: true
1435
+ allow_failure: true
1436
+ api2 👮 lint:
1437
+ stage: test
1438
+ image: path/to/docker/jobs-default:the-version
1439
+ variables:
1440
+ KUBERNETES_CPU_REQUEST: '0.45'
1441
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1442
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1443
+ script:
1444
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1445
+ - export APP_PATH="api"
1446
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1447
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1448
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1449
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1450
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1451
+ - cd api
1452
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1453
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1454
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1455
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1456
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1457
+ - yarn install --immutable
1458
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1459
+ - yarn lint
1460
+ cache:
1461
+ - key: api-yarn
1462
+ policy: pull-push
1463
+ paths:
1464
+ - api/.yarn
1465
+ - key: api-node-modules
1466
+ policy: pull-push
1467
+ paths:
1468
+ - api/node_modules
1469
+ rules:
1470
+ - when: never
1471
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1472
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1473
+ - if: $CI_MERGE_REQUEST_ID
1474
+ needs: []
1475
+ retry: *a1
1476
+ interruptible: true
1477
+ api2 🧪 test:
1478
+ stage: test
1479
+ image: path/to/docker/jobs-testing-chrome:the-version
1480
+ variables:
1481
+ KUBERNETES_CPU_REQUEST: '0.45'
1482
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1483
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1484
+ script:
1485
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1486
+ - export APP_PATH="api"
1487
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1488
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1489
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1490
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1491
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1492
+ - cd api
1493
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1494
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1495
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1496
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1497
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1498
+ - yarn install --immutable
1499
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1500
+ - yarn test
1501
+ cache:
1502
+ - key: api-yarn
1503
+ policy: pull-push
1504
+ paths:
1505
+ - api/.yarn
1506
+ - key: api-node-modules
1507
+ policy: pull-push
1508
+ paths:
1509
+ - api/node_modules
1510
+ rules:
1511
+ - when: never
1512
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1513
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1514
+ - if: $CI_MERGE_REQUEST_ID
1515
+ needs: []
1516
+ retry: *a1
1517
+ interruptible: true
1518
+ 'api2 🔨 app | dev ':
1519
+ stage: build
1520
+ image: path/to/docker/jobs-default:the-version
1521
+ variables:
1522
+ KUBERNETES_CPU_REQUEST: '0.45'
1523
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1524
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1525
+ script:
1526
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1527
+ - export ENV_SHORT="dev"
1528
+ - export APP_DIR="api"
1529
+ - export ENV_TYPE="dev"
1530
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1531
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1532
+ - 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")"
1533
+ - export HOST="api2.dev.test-app.pan.panter.cloud"
1534
+ - export ROOT_URL="https://api2.dev.test-app.pan.panter.cloud"
1535
+ - export HOST_INTERNAL="api2.dev.test-app.pan.panter.cloud"
1536
+ - export HOST_CANONICAL="api2.dev.test-app.pan.panter.cloud"
1537
+ - export ROOT_URL_INTERNAL="https://api2.dev.test-app.pan.panter.cloud"
1538
+ - export KUBE_NAMESPACE="pan-test-app-dev"
1539
+ - export KUBE_APP_NAME="api2"
1540
+ - export KUBE_APP_NAME_PREFIX=""
1541
+ - |-
1542
+ export multiline_from_api="line1
1543
+ line2
1544
+ line3
1545
+
1546
+ single quote: '
1547
+ doouble quote: \\"
1548
+ "
1549
+ - |-
1550
+ export multiline2="yeah
1551
+ yeah2
1552
+ yeah3
1553
+
1554
+ single quote: '
1555
+ doouble quote: \\"
1556
+ "
1557
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
1558
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1559
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1560
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1561
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1562
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1563
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1564
+ - cd api
1565
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1566
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1567
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1568
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1569
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1570
+ - yarn install --immutable
1571
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1572
+ - yarn build
1573
+ cache:
1574
+ - key: api-yarn
1575
+ policy: pull-push
1576
+ paths:
1577
+ - api/.yarn
1578
+ - key: api-node-modules
1579
+ policy: pull-push
1580
+ paths:
1581
+ - api/node_modules
1582
+ - key: api2-next-cache
1583
+ policy: pull-push
1584
+ paths:
1585
+ - api/.next/cache
1586
+ artifacts:
1587
+ paths:
1588
+ - api/__build_info.json
1589
+ - api/.next
1590
+ - api/dist
1591
+ expire_in: 1 day
1592
+ when: always
1593
+ reports: {}
1594
+ rules:
1595
+ - when: never
1596
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1597
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1598
+ needs: []
1599
+ retry: *a1
1600
+ interruptible: true
1601
+ 'api2 🔨 docker | dev ':
1602
+ stage: build
1603
+ image: path/to/docker/docker-build:the-version
1604
+ services:
1605
+ - name: docker:24.0.6-dind
1606
+ command:
1607
+ - --tls=false
1608
+ variables:
1609
+ DOCKER_HOST: tcp://0.0.0.0:2375
1610
+ DOCKER_TLS_CERTDIR: ''
1611
+ DOCKER_DRIVER: overlay2
1612
+ DOCKER_BUILDKIT: '1'
1613
+ KUBERNETES_CPU_REQUEST: '0.45'
1614
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1615
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1616
+ script:
1617
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1618
+ - export APP_DIR="api"
1619
+ - export DOCKER_BUILD_CONTEXT="."
1620
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
1621
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
1622
+ - export DOCKER_IMAGE_NAME="dev/api2"
1623
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
1624
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1625
+ - |-
1626
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1627
+ RUN yarn plugin import workspace-tools
1628
+ RUN yarn workspaces focus --production && yarn rebuild"
1629
+ - |-
1630
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1631
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1632
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1633
+ COPY --chown=node:node .yarn /app/.yarn"
1634
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1635
+ - ensureNodeDockerfile
1636
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1637
+ - docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY
1638
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1639
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1640
+ - 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
1641
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1642
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1643
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1644
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1645
+ - docker push $DOCKER_CACHE_IMAGE
1646
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1647
+ cache:
1648
+ - key: api-yarn
1649
+ policy: pull
1650
+ paths:
1651
+ - api/.yarn
1652
+ rules:
1653
+ - when: never
1654
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1655
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1656
+ needs:
1657
+ - 'api2 🔨 app | dev '
1658
+ retry: *a1
1659
+ interruptible: true
1660
+ 'api2 🧾 sbom | dev ':
1661
+ stage: build
1662
+ image: aquasec/trivy:0.38.3
1663
+ variables: {}
1664
+ script:
1665
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1666
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1667
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1668
+ artifacts:
1669
+ paths:
1670
+ - __sbom.json
1671
+ rules:
1672
+ - when: never
1673
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1674
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1675
+ needs: []
1676
+ retry: *a1
1677
+ interruptible: true
1678
+ allow_failure: true
1679
+ 'api2 🚀 Deploy | dev ':
1680
+ stage: deploy dev
1681
+ image: path/to/docker/kubernetes:the-version
1682
+ variables:
1683
+ KUBERNETES_CPU_REQUEST: '0.22'
1684
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1685
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1686
+ script:
1687
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1688
+ - export ENV_SHORT="dev"
1689
+ - export APP_DIR="api"
1690
+ - export ENV_TYPE="dev"
1691
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1692
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1693
+ - 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")"
1694
+ - export HOST="api2.dev.test-app.pan.panter.cloud"
1695
+ - export ROOT_URL="https://api2.dev.test-app.pan.panter.cloud"
1696
+ - export HOST_INTERNAL="api2.dev.test-app.pan.panter.cloud"
1697
+ - export HOST_CANONICAL="api2.dev.test-app.pan.panter.cloud"
1698
+ - export ROOT_URL_INTERNAL="https://api2.dev.test-app.pan.panter.cloud"
1699
+ - export KUBE_NAMESPACE="pan-test-app-dev"
1700
+ - export KUBE_APP_NAME="api2"
1701
+ - export KUBE_APP_NAME_PREFIX=""
1702
+ - |-
1703
+ export multiline_from_api="line1
1704
+ line2
1705
+ line3
1706
+
1707
+ single quote: '
1708
+ doouble quote: \\"
1709
+ "
1710
+ - |-
1711
+ export multiline2="yeah
1712
+ yeah2
1713
+ yeah3
1714
+
1715
+ single quote: '
1716
+ doouble quote: \\"
1717
+ "
1718
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
1719
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
1720
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
1721
+ - export DOCKER_IMAGE_NAME="dev/api2"
1722
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
1723
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1724
+ - export RELEASE_NAME="pan-test-app-dev-api2"
1725
+ - export HELM_EXPERIMENTAL_OCI="1"
1726
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
1727
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
1728
+ - export HELM_ARGS=""
1729
+ - export COMPONENT_NAME="api2"
1730
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1731
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1732
+ - kubectl config set-cluster "kube-pan-test-app-dev-api2" --server="$CL_dev_api2_KUBE_URL" --certificate-authority <(echo $CL_dev_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
1733
+ - kubectl config set-credentials "kube-pan-test-app-dev-api2" --token="$CL_dev_api2_KUBE_TOKEN"
1734
+ - kubectl config set-context "kube-pan-test-app-dev-api2" --cluster="kube-pan-test-app-dev-api2" --user="kube-pan-test-app-dev-api2" --namespace="pan-test-app-dev"
1735
+ - kubectl config use-context "kube-pan-test-app-dev-api2"
1736
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeallvalues[collapsed=true]\\r\\e[0KWrite __all_values.yml for helm deployment"
1737
+ - |
1738
+ cat > __all_values.yml <<EOF
1739
+ env:
1740
+ secret: {}
1741
+ public:
1742
+ ENV_SHORT: |-
1743
+ dev
1744
+ APP_DIR: |-
1745
+ api
1746
+ ENV_TYPE: |-
1747
+ dev
1748
+ BUILD_INFO_BUILD_ID: |-
1749
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1750
+ BUILD_INFO_BUILD_TIME: |-
1751
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1752
+ BUILD_INFO_CURRENT_VERSION: |-
1753
+ $(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/^/ /')
1754
+ HOST: |-
1755
+ api2.dev.test-app.pan.panter.cloud
1756
+ ROOT_URL: |-
1757
+ https://api2.dev.test-app.pan.panter.cloud
1758
+ HOST_INTERNAL: |-
1759
+ api2.dev.test-app.pan.panter.cloud
1760
+ HOST_CANONICAL: |-
1761
+ api2.dev.test-app.pan.panter.cloud
1762
+ ROOT_URL_INTERNAL: |-
1763
+ https://api2.dev.test-app.pan.panter.cloud
1764
+ KUBE_NAMESPACE: |-
1765
+ pan-test-app-dev
1766
+ KUBE_APP_NAME: |-
1767
+ api2
1768
+ KUBE_APP_NAME_PREFIX: ""
1769
+ multiline_from_api: |
1770
+ line1
1771
+ line2
1772
+ line3
1773
+
1774
+ single quote: '
1775
+ doouble quote: "
1776
+ multiline2: |
1777
+ yeah
1778
+ yeah2
1779
+ yeah3
1780
+
1781
+ single quote: '
1782
+ doouble quote: "
1783
+ _ALL_ENV_VAR_KEYS: |-
1784
+ ["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","KUBE_NAMESPACE","KUBE_APP_NAME","KUBE_APP_NAME_PREFIX","multiline_from_api","multiline2"]
1785
+ application:
1786
+ host: |-
1787
+ api2.dev.test-app.pan.panter.cloud
1788
+ command: |-
1789
+ yarn start
1790
+ livenessProbe:
1791
+ httpGet:
1792
+ path: |-
1793
+ __health
1794
+ readinessProbe:
1795
+ httpGet:
1796
+ path: |-
1797
+ __health
1798
+ startupProbe:
1799
+ httpGet:
1800
+ path: |-
1801
+ __health
1802
+
1803
+ EOF
1804
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeallvalues\\r\\e[0K"
1805
+ - kubernetesCreateSecret
1806
+ - kubernetesDeploy
1807
+ - echo 'Uploading SBOM to Dependency Track'
1808
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api2" "https://api2.dev.test-app.pan.panter.cloud" "__sbom.json" vex.json || true
1809
+ - echo deployment successful 😻
1810
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.dev.test-app.pan.panter.cloud" >> gitlab_environment.env
1811
+ environment:
1812
+ name: dev/api2
1813
+ url: $CL_GITLAB_ENVIRONMENT_URL
1814
+ on_stop: 'api2 🛑 Stop ⚠️ | dev '
1815
+ auto_stop_in: 4 weeks
1816
+ artifacts:
1817
+ reports:
1818
+ dotenv: gitlab_environment.env
1819
+ rules:
1820
+ - when: never
1821
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1822
+ - when: on_success
1823
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1824
+ needs:
1825
+ - job: api2 👮 lint
1826
+ artifacts: false
1827
+ - job: 'api2 🔨 app | dev '
1828
+ artifacts: false
1829
+ - job: 'api2 🔨 docker | dev '
1830
+ artifacts: false
1831
+ - job: api2 🧪 test
1832
+ artifacts: false
1833
+ - job: 'api2 🧾 sbom | dev '
1834
+ artifacts: true
1835
+ - job: api2 🛡 audit
1836
+ artifacts: false
1837
+ retry: *a1
1838
+ interruptible: true
1839
+ allow_failure: false
1840
+ 'api2 🛑 Stop ⚠️ | dev ':
1841
+ stage: stop dev
1842
+ image: path/to/docker/kubernetes:the-version
1843
+ variables:
1844
+ KUBERNETES_CPU_REQUEST: '0.22'
1845
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1846
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1847
+ GIT_STRATEGY: none
1848
+ script:
1849
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1850
+ - export ENV_SHORT="dev"
1851
+ - export APP_DIR="api"
1852
+ - export ENV_TYPE="dev"
1853
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1854
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1855
+ - 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")"
1856
+ - export HOST="api2.dev.test-app.pan.panter.cloud"
1857
+ - export ROOT_URL="https://api2.dev.test-app.pan.panter.cloud"
1858
+ - export HOST_INTERNAL="api2.dev.test-app.pan.panter.cloud"
1859
+ - export HOST_CANONICAL="api2.dev.test-app.pan.panter.cloud"
1860
+ - export ROOT_URL_INTERNAL="https://api2.dev.test-app.pan.panter.cloud"
1861
+ - export KUBE_NAMESPACE="pan-test-app-dev"
1862
+ - export KUBE_APP_NAME="api2"
1863
+ - export KUBE_APP_NAME_PREFIX=""
1864
+ - |-
1865
+ export multiline_from_api="line1
1866
+ line2
1867
+ line3
1868
+
1869
+ single quote: '
1870
+ doouble quote: \\"
1871
+ "
1872
+ - |-
1873
+ export multiline2="yeah
1874
+ yeah2
1875
+ yeah3
1876
+
1877
+ single quote: '
1878
+ doouble quote: \\"
1879
+ "
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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
1881
+ - export RELEASE_NAME="pan-test-app-dev-api2"
1882
+ - export HELM_EXPERIMENTAL_OCI="1"
1883
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
1884
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
1885
+ - export HELM_ARGS=""
1886
+ - export COMPONENT_NAME="api2"
1887
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1888
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1889
+ - kubectl config set-cluster "kube-pan-test-app-dev-api2" --server="$CL_dev_api2_KUBE_URL" --certificate-authority <(echo $CL_dev_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
1890
+ - kubectl config set-credentials "kube-pan-test-app-dev-api2" --token="$CL_dev_api2_KUBE_TOKEN"
1891
+ - kubectl config set-context "kube-pan-test-app-dev-api2" --cluster="kube-pan-test-app-dev-api2" --user="kube-pan-test-app-dev-api2" --namespace="pan-test-app-dev"
1892
+ - kubectl config use-context "kube-pan-test-app-dev-api2"
1893
+ - kubernetesDelete
1894
+ - echo 'Disabling component in Dependency Track'
1895
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api2" "https://api2.dev.test-app.pan.panter.cloud" || true
1896
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.dev.test-app.pan.panter.cloud" >> gitlab_environment.env
1897
+ environment:
1898
+ name: dev/api2
1899
+ url: $CL_GITLAB_ENVIRONMENT_URL
1900
+ action: stop
1901
+ artifacts:
1902
+ reports:
1903
+ dotenv: gitlab_environment.env
1904
+ rules:
1905
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1906
+ when: on_success
1907
+ - when: never
1908
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1909
+ - when: manual
1910
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1911
+ needs: []
1912
+ retry: *a1
1913
+ interruptible: true
1914
+ allow_failure: true
1915
+ 'api2 ↩️ Rollback ⚠️ | dev ':
1916
+ stage: rollback dev
1917
+ image: path/to/docker/kubernetes:the-version
1918
+ variables:
1919
+ KUBERNETES_CPU_REQUEST: '0.22'
1920
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1921
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1922
+ GIT_STRATEGY: none
1923
+ script:
1924
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1925
+ - export ENV_SHORT="dev"
1926
+ - export APP_DIR="api"
1927
+ - export ENV_TYPE="dev"
1928
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1929
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1930
+ - 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")"
1931
+ - export HOST="api2.dev.test-app.pan.panter.cloud"
1932
+ - export ROOT_URL="https://api2.dev.test-app.pan.panter.cloud"
1933
+ - export HOST_INTERNAL="api2.dev.test-app.pan.panter.cloud"
1934
+ - export HOST_CANONICAL="api2.dev.test-app.pan.panter.cloud"
1935
+ - export ROOT_URL_INTERNAL="https://api2.dev.test-app.pan.panter.cloud"
1936
+ - export KUBE_NAMESPACE="pan-test-app-dev"
1937
+ - export KUBE_APP_NAME="api2"
1938
+ - export KUBE_APP_NAME_PREFIX=""
1939
+ - |-
1940
+ export multiline_from_api="line1
1941
+ line2
1942
+ line3
1943
+
1944
+ single quote: '
1945
+ doouble quote: \\"
1946
+ "
1947
+ - |-
1948
+ export multiline2="yeah
1949
+ yeah2
1950
+ yeah3
1951
+
1952
+ single quote: '
1953
+ doouble quote: \\"
1954
+ "
1955
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
1956
+ - export RELEASE_NAME="pan-test-app-dev-api2"
1957
+ - export HELM_EXPERIMENTAL_OCI="1"
1958
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
1959
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
1960
+ - export HELM_ARGS=""
1961
+ - export COMPONENT_NAME="api2"
1962
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1963
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1964
+ - kubectl config set-cluster "kube-pan-test-app-dev-api2" --server="$CL_dev_api2_KUBE_URL" --certificate-authority <(echo $CL_dev_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
1965
+ - kubectl config set-credentials "kube-pan-test-app-dev-api2" --token="$CL_dev_api2_KUBE_TOKEN"
1966
+ - kubectl config set-context "kube-pan-test-app-dev-api2" --cluster="kube-pan-test-app-dev-api2" --user="kube-pan-test-app-dev-api2" --namespace="pan-test-app-dev"
1967
+ - kubectl config use-context "kube-pan-test-app-dev-api2"
1968
+ - kubernetesRollback
1969
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.dev.test-app.pan.panter.cloud" >> gitlab_environment.env
1970
+ environment:
1971
+ name: dev/api2
1972
+ url: $CL_GITLAB_ENVIRONMENT_URL
1973
+ action: access
1974
+ artifacts:
1975
+ reports:
1976
+ dotenv: gitlab_environment.env
1977
+ rules:
1978
+ - when: never
1979
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1980
+ - when: manual
1981
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1982
+ needs: []
1983
+ retry: *a1
1984
+ interruptible: true
1985
+ allow_failure: true
1986
+ 'api2 🔨 app | review ':
1987
+ stage: build
1988
+ image: path/to/docker/jobs-default:the-version
1989
+ variables:
1990
+ KUBERNETES_CPU_REQUEST: '0.45'
1991
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1992
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1993
+ script:
1994
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1995
+ - export ENV_SHORT="review"
1996
+ - export APP_DIR="api"
1997
+ - export ENV_TYPE="review"
1998
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1999
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2000
+ - 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")"
2001
+ - export HOST="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2002
+ - export ROOT_URL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2003
+ - export HOST_INTERNAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2004
+ - export HOST_CANONICAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2005
+ - export ROOT_URL_INTERNAL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2006
+ - export KUBE_NAMESPACE="pan-test-app-review"
2007
+ - export KUBE_APP_NAME="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api2"
2008
+ - export KUBE_APP_NAME_PREFIX="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-"
2009
+ - |-
2010
+ export multiline_from_api="line1
2011
+ line2
2012
+ line3
2013
+
2014
+ single quote: '
2015
+ doouble quote: \\"
2016
+ "
2017
+ - |-
2018
+ export multiline2="yeah
2019
+ yeah2
2020
+ yeah3
2021
+
2022
+ single quote: '
2023
+ doouble quote: \\"
2024
+ "
2025
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2026
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2027
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
2028
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2029
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2030
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2031
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2032
+ - cd api
2033
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2034
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2035
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2036
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2037
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
2038
+ - yarn install --immutable
2039
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
2040
+ - yarn build
2041
+ cache:
2042
+ - key: api-yarn
2043
+ policy: pull-push
2044
+ paths:
2045
+ - api/.yarn
2046
+ - key: api-node-modules
2047
+ policy: pull-push
2048
+ paths:
2049
+ - api/node_modules
2050
+ - key: api2-next-cache
2051
+ policy: pull-push
2052
+ paths:
2053
+ - api/.next/cache
2054
+ artifacts:
2055
+ paths:
2056
+ - api/__build_info.json
2057
+ - api/.next
2058
+ - api/dist
2059
+ expire_in: 1 day
2060
+ when: always
2061
+ reports: {}
2062
+ rules:
2063
+ - if: $CI_MERGE_REQUEST_ID
2064
+ needs: []
2065
+ retry: *a1
2066
+ interruptible: true
2067
+ 'api2 🔨 docker | review ':
2068
+ stage: build
2069
+ image: path/to/docker/docker-build:the-version
2070
+ services:
2071
+ - name: docker:24.0.6-dind
2072
+ command:
2073
+ - --tls=false
2074
+ variables:
2075
+ DOCKER_HOST: tcp://0.0.0.0:2375
2076
+ DOCKER_TLS_CERTDIR: ''
2077
+ DOCKER_DRIVER: overlay2
2078
+ DOCKER_BUILDKIT: '1'
2079
+ KUBERNETES_CPU_REQUEST: '0.45'
2080
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2081
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2082
+ script:
2083
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2084
+ - export APP_DIR="api"
2085
+ - export DOCKER_BUILD_CONTEXT="."
2086
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
2087
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
2088
+ - export DOCKER_IMAGE_NAME="review/api2"
2089
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
2090
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2091
+ - |-
2092
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2093
+ RUN yarn plugin import workspace-tools
2094
+ RUN yarn workspaces focus --production && yarn rebuild"
2095
+ - |-
2096
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
2097
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
2098
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2099
+ COPY --chown=node:node .yarn /app/.yarn"
2100
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2101
+ - ensureNodeDockerfile
2102
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
2103
+ - docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY
2104
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
2105
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
2106
+ - 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
2107
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
2108
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
2109
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2110
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2111
+ - docker push $DOCKER_CACHE_IMAGE
2112
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
2113
+ cache:
2114
+ - key: api-yarn
2115
+ policy: pull
2116
+ paths:
2117
+ - api/.yarn
2118
+ rules:
2119
+ - if: $CI_MERGE_REQUEST_ID
2120
+ needs:
2121
+ - 'api2 🔨 app | review '
2122
+ retry: *a1
2123
+ interruptible: true
2124
+ 'api2 🧾 sbom | review ':
2125
+ stage: build
2126
+ image: aquasec/trivy:0.38.3
2127
+ variables: {}
2128
+ script:
2129
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2130
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2131
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
2132
+ artifacts:
2133
+ paths:
2134
+ - __sbom.json
2135
+ rules:
2136
+ - if: $CI_MERGE_REQUEST_ID
2137
+ needs: []
2138
+ retry: *a1
2139
+ interruptible: true
2140
+ allow_failure: true
2141
+ 'api2 🚀 Deploy | review ':
2142
+ stage: deploy review
2143
+ image: path/to/docker/kubernetes:the-version
2144
+ variables:
2145
+ KUBERNETES_CPU_REQUEST: '0.22'
2146
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2147
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2148
+ script:
2149
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2150
+ - export ENV_SHORT="review"
2151
+ - export APP_DIR="api"
2152
+ - export ENV_TYPE="review"
2153
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2154
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2155
+ - 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")"
2156
+ - export HOST="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2157
+ - export ROOT_URL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2158
+ - export HOST_INTERNAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2159
+ - export HOST_CANONICAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2160
+ - export ROOT_URL_INTERNAL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2161
+ - export KUBE_NAMESPACE="pan-test-app-review"
2162
+ - export KUBE_APP_NAME="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api2"
2163
+ - export KUBE_APP_NAME_PREFIX="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-"
2164
+ - |-
2165
+ export multiline_from_api="line1
2166
+ line2
2167
+ line3
2168
+
2169
+ single quote: '
2170
+ doouble quote: \\"
2171
+ "
2172
+ - |-
2173
+ export multiline2="yeah
2174
+ yeah2
2175
+ yeah3
2176
+
2177
+ single quote: '
2178
+ doouble quote: \\"
2179
+ "
2180
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2181
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
2182
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
2183
+ - export DOCKER_IMAGE_NAME="review/api2"
2184
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
2185
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2186
+ - export RELEASE_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"; })-api2"
2187
+ - export HELM_EXPERIMENTAL_OCI="1"
2188
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2189
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2190
+ - export HELM_ARGS=""
2191
+ - export COMPONENT_NAME="api2"
2192
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2193
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2194
+ - kubectl config set-cluster "kube-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"; })-api2" --server="$CL_review_api2_KUBE_URL" --certificate-authority <(echo $CL_review_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2195
+ - kubectl config set-credentials "kube-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"; })-api2" --token="$CL_review_api2_KUBE_TOKEN"
2196
+ - kubectl config set-context "kube-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"; })-api2" --cluster="kube-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"; })-api2" --user="kube-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"; })-api2" --namespace="pan-test-app-review"
2197
+ - kubectl config use-context "kube-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"; })-api2"
2198
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeallvalues[collapsed=true]\\r\\e[0KWrite __all_values.yml for helm deployment"
2199
+ - |
2200
+ cat > __all_values.yml <<EOF
2201
+ env:
2202
+ secret: {}
2203
+ public:
2204
+ ENV_SHORT: |-
2205
+ review
2206
+ APP_DIR: |-
2207
+ api
2208
+ ENV_TYPE: |-
2209
+ review
2210
+ BUILD_INFO_BUILD_ID: |-
2211
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2212
+ BUILD_INFO_BUILD_TIME: |-
2213
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2214
+ BUILD_INFO_CURRENT_VERSION: |-
2215
+ $(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/^/ /')
2216
+ HOST: |-
2217
+ $(printf %s "api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2218
+ ROOT_URL: |-
2219
+ $(printf %s "https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2220
+ HOST_INTERNAL: |-
2221
+ $(printf %s "api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2222
+ HOST_CANONICAL: |-
2223
+ $(printf %s "api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2224
+ ROOT_URL_INTERNAL: |-
2225
+ $(printf %s "https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2226
+ KUBE_NAMESPACE: |-
2227
+ pan-test-app-review
2228
+ KUBE_APP_NAME: |-
2229
+ $(printf %s "$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api2" | sed 's/^/ /')
2230
+ KUBE_APP_NAME_PREFIX: |-
2231
+ $(printf %s "$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-" | sed 's/^/ /')
2232
+ multiline_from_api: |
2233
+ line1
2234
+ line2
2235
+ line3
2236
+
2237
+ single quote: '
2238
+ doouble quote: "
2239
+ multiline2: |
2240
+ yeah
2241
+ yeah2
2242
+ yeah3
2243
+
2244
+ single quote: '
2245
+ doouble quote: "
2246
+ _ALL_ENV_VAR_KEYS: |-
2247
+ ["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","KUBE_NAMESPACE","KUBE_APP_NAME","KUBE_APP_NAME_PREFIX","multiline_from_api","multiline2"]
2248
+ application:
2249
+ host: |-
2250
+ $(printf %s "api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" | sed 's/^/ /')
2251
+ command: |-
2252
+ yarn start
2253
+ livenessProbe:
2254
+ httpGet:
2255
+ path: |-
2256
+ __health
2257
+ readinessProbe:
2258
+ httpGet:
2259
+ path: |-
2260
+ __health
2261
+ startupProbe:
2262
+ httpGet:
2263
+ path: |-
2264
+ __health
2265
+
2266
+ EOF
2267
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeallvalues\\r\\e[0K"
2268
+ - kubernetesCreateSecret
2269
+ - kubernetesDeploy
2270
+ - echo 'Uploading SBOM to Dependency Track'
2271
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api2" "https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" "__sbom.json" vex.json || true
2272
+ - echo deployment successful 😻
2273
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" >> gitlab_environment.env
2274
+ environment:
2275
+ name: review/$CI_COMMIT_REF_NAME/api2
2276
+ url: $CL_GITLAB_ENVIRONMENT_URL
2277
+ on_stop: 'api2 🛑 Stop ⚠️ | review '
2278
+ auto_stop_in: 1 week
2279
+ artifacts:
2280
+ reports:
2281
+ dotenv: gitlab_environment.env
2282
+ rules:
2283
+ - when: on_success
2284
+ if: $CI_MERGE_REQUEST_ID
2285
+ needs:
2286
+ - job: api2 👮 lint
2287
+ artifacts: false
2288
+ - job: 'api2 🔨 app | review '
2289
+ artifacts: false
2290
+ - job: 'api2 🔨 docker | review '
2291
+ artifacts: false
2292
+ - job: api2 🧪 test
2293
+ artifacts: false
2294
+ - job: 'api2 🧾 sbom | review '
2295
+ artifacts: true
2296
+ - job: api2 🛡 audit
2297
+ artifacts: false
2298
+ retry: *a1
2299
+ interruptible: true
2300
+ allow_failure: false
2301
+ 'api2 🛑 Stop ⚠️ | review ':
2302
+ stage: stop review
2303
+ image: path/to/docker/kubernetes:the-version
2304
+ variables:
2305
+ KUBERNETES_CPU_REQUEST: '0.22'
2306
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2307
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2308
+ GIT_STRATEGY: none
2309
+ script:
2310
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2311
+ - export ENV_SHORT="review"
2312
+ - export APP_DIR="api"
2313
+ - export ENV_TYPE="review"
2314
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2315
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2316
+ - 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")"
2317
+ - export HOST="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2318
+ - export ROOT_URL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2319
+ - export HOST_INTERNAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2320
+ - export HOST_CANONICAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2321
+ - export ROOT_URL_INTERNAL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2322
+ - export KUBE_NAMESPACE="pan-test-app-review"
2323
+ - export KUBE_APP_NAME="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api2"
2324
+ - export KUBE_APP_NAME_PREFIX="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-"
2325
+ - |-
2326
+ export multiline_from_api="line1
2327
+ line2
2328
+ line3
2329
+
2330
+ single quote: '
2331
+ doouble quote: \\"
2332
+ "
2333
+ - |-
2334
+ export multiline2="yeah
2335
+ yeah2
2336
+ yeah3
2337
+
2338
+ single quote: '
2339
+ doouble quote: \\"
2340
+ "
2341
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2342
+ - export RELEASE_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"; })-api2"
2343
+ - export HELM_EXPERIMENTAL_OCI="1"
2344
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2345
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2346
+ - export HELM_ARGS=""
2347
+ - export COMPONENT_NAME="api2"
2348
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2349
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2350
+ - kubectl config set-cluster "kube-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"; })-api2" --server="$CL_review_api2_KUBE_URL" --certificate-authority <(echo $CL_review_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2351
+ - kubectl config set-credentials "kube-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"; })-api2" --token="$CL_review_api2_KUBE_TOKEN"
2352
+ - kubectl config set-context "kube-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"; })-api2" --cluster="kube-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"; })-api2" --user="kube-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"; })-api2" --namespace="pan-test-app-review"
2353
+ - kubectl config use-context "kube-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"; })-api2"
2354
+ - kubernetesDelete
2355
+ - echo 'Disabling component in Dependency Track'
2356
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api2" "https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" || true
2357
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" >> gitlab_environment.env
2358
+ environment:
2359
+ name: review/$CI_COMMIT_REF_NAME/api2
2360
+ url: $CL_GITLAB_ENVIRONMENT_URL
2361
+ action: stop
2362
+ artifacts:
2363
+ reports:
2364
+ dotenv: gitlab_environment.env
2365
+ rules:
2366
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2367
+ when: on_success
2368
+ - when: manual
2369
+ if: $CI_MERGE_REQUEST_ID
2370
+ needs: []
2371
+ retry: *a1
2372
+ interruptible: true
2373
+ allow_failure: true
2374
+ 'api2 ↩️ Rollback ⚠️ | review ':
2375
+ stage: rollback review
2376
+ image: path/to/docker/kubernetes:the-version
2377
+ variables:
2378
+ KUBERNETES_CPU_REQUEST: '0.22'
2379
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2380
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2381
+ GIT_STRATEGY: none
2382
+ script:
2383
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2384
+ - export ENV_SHORT="review"
2385
+ - export APP_DIR="api"
2386
+ - export ENV_TYPE="review"
2387
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2388
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2389
+ - 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")"
2390
+ - export HOST="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2391
+ - export ROOT_URL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2392
+ - export HOST_INTERNAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2393
+ - export HOST_CANONICAL="api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2394
+ - export ROOT_URL_INTERNAL="https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud"
2395
+ - export KUBE_NAMESPACE="pan-test-app-review"
2396
+ - export KUBE_APP_NAME="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api2"
2397
+ - export KUBE_APP_NAME_PREFIX="$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-"
2398
+ - |-
2399
+ export multiline_from_api="line1
2400
+ line2
2401
+ line3
2402
+
2403
+ single quote: '
2404
+ doouble quote: \\"
2405
+ "
2406
+ - |-
2407
+ export multiline2="yeah
2408
+ yeah2
2409
+ yeah3
2410
+
2411
+ single quote: '
2412
+ doouble quote: \\"
2413
+ "
2414
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2415
+ - export RELEASE_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"; })-api2"
2416
+ - export HELM_EXPERIMENTAL_OCI="1"
2417
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2418
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2419
+ - export HELM_ARGS=""
2420
+ - export COMPONENT_NAME="api2"
2421
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2422
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2423
+ - kubectl config set-cluster "kube-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"; })-api2" --server="$CL_review_api2_KUBE_URL" --certificate-authority <(echo $CL_review_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2424
+ - kubectl config set-credentials "kube-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"; })-api2" --token="$CL_review_api2_KUBE_TOKEN"
2425
+ - kubectl config set-context "kube-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"; })-api2" --cluster="kube-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"; })-api2" --user="kube-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"; })-api2" --namespace="pan-test-app-review"
2426
+ - kubectl config use-context "kube-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"; })-api2"
2427
+ - kubernetesRollback
2428
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }).review.test-app.pan.panter.cloud" >> gitlab_environment.env
2429
+ environment:
2430
+ name: review/$CI_COMMIT_REF_NAME/api2
2431
+ url: $CL_GITLAB_ENVIRONMENT_URL
2432
+ action: access
2433
+ artifacts:
2434
+ reports:
2435
+ dotenv: gitlab_environment.env
2436
+ rules:
2437
+ - when: manual
2438
+ if: $CI_MERGE_REQUEST_ID
2439
+ needs: []
2440
+ retry: *a1
2441
+ interruptible: true
2442
+ allow_failure: true
2443
+ 'api2 🔨 app | stage ':
2444
+ stage: build
2445
+ image: path/to/docker/jobs-default:the-version
2446
+ variables:
2447
+ KUBERNETES_CPU_REQUEST: '0.45'
2448
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2449
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2450
+ script:
2451
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2452
+ - export ENV_SHORT="stage"
2453
+ - export APP_DIR="api"
2454
+ - export ENV_TYPE="stage"
2455
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2456
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2457
+ - 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")"
2458
+ - export HOST="api2.stage.test-app.pan.panter.cloud"
2459
+ - export ROOT_URL="https://api2.stage.test-app.pan.panter.cloud"
2460
+ - export HOST_INTERNAL="api2.stage.test-app.pan.panter.cloud"
2461
+ - export HOST_CANONICAL="api2.stage.test-app.pan.panter.cloud"
2462
+ - export ROOT_URL_INTERNAL="https://api2.stage.test-app.pan.panter.cloud"
2463
+ - export KUBE_NAMESPACE="pan-test-app-stage"
2464
+ - export KUBE_APP_NAME="api2"
2465
+ - export KUBE_APP_NAME_PREFIX=""
2466
+ - |-
2467
+ export multiline_from_api="line1
2468
+ line2
2469
+ line3
2470
+
2471
+ single quote: '
2472
+ doouble quote: \\"
2473
+ "
2474
+ - |-
2475
+ export multiline2="yeah
2476
+ yeah2
2477
+ yeah3
2478
+
2479
+ single quote: '
2480
+ doouble quote: \\"
2481
+ "
2482
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2483
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2484
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
2485
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2486
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2487
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2488
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2489
+ - cd api
2490
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2491
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2492
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2493
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2494
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
2495
+ - yarn install --immutable
2496
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
2497
+ - yarn build
2498
+ cache:
2499
+ - key: api-yarn
2500
+ policy: pull-push
2501
+ paths:
2502
+ - api/.yarn
2503
+ - key: api-node-modules
2504
+ policy: pull-push
2505
+ paths:
2506
+ - api/node_modules
2507
+ - key: api2-next-cache
2508
+ policy: pull-push
2509
+ paths:
2510
+ - api/.next/cache
2511
+ artifacts:
2512
+ paths:
2513
+ - api/__build_info.json
2514
+ - api/.next
2515
+ - api/dist
2516
+ expire_in: 1 day
2517
+ when: always
2518
+ reports: {}
2519
+ rules:
2520
+ - if: $CI_COMMIT_TAG
2521
+ needs: []
2522
+ retry: *a1
2523
+ interruptible: true
2524
+ 'api2 🔨 docker | stage ':
2525
+ stage: build
2526
+ image: path/to/docker/docker-build:the-version
2527
+ services:
2528
+ - name: docker:24.0.6-dind
2529
+ command:
2530
+ - --tls=false
2531
+ variables:
2532
+ DOCKER_HOST: tcp://0.0.0.0:2375
2533
+ DOCKER_TLS_CERTDIR: ''
2534
+ DOCKER_DRIVER: overlay2
2535
+ DOCKER_BUILDKIT: '1'
2536
+ KUBERNETES_CPU_REQUEST: '0.45'
2537
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2538
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2539
+ script:
2540
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2541
+ - export APP_DIR="api"
2542
+ - export DOCKER_BUILD_CONTEXT="."
2543
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
2544
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
2545
+ - export DOCKER_IMAGE_NAME="stage/api2"
2546
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
2547
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2548
+ - |-
2549
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2550
+ RUN yarn plugin import workspace-tools
2551
+ RUN yarn workspaces focus --production && yarn rebuild"
2552
+ - |-
2553
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
2554
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
2555
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
2556
+ COPY --chown=node:node .yarn /app/.yarn"
2557
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2558
+ - ensureNodeDockerfile
2559
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
2560
+ - docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY
2561
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
2562
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
2563
+ - 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
2564
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
2565
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
2566
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
2567
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
2568
+ - docker push $DOCKER_CACHE_IMAGE
2569
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
2570
+ cache:
2571
+ - key: api-yarn
2572
+ policy: pull
2573
+ paths:
2574
+ - api/.yarn
2575
+ rules:
2576
+ - if: $CI_COMMIT_TAG
2577
+ needs:
2578
+ - 'api2 🔨 app | stage '
2579
+ retry: *a1
2580
+ interruptible: true
2581
+ 'api2 🧾 sbom | stage ':
2582
+ stage: build
2583
+ image: aquasec/trivy:0.38.3
2584
+ variables: {}
2585
+ script:
2586
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2587
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2588
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
2589
+ artifacts:
2590
+ paths:
2591
+ - __sbom.json
2592
+ rules:
2593
+ - if: $CI_COMMIT_TAG
2594
+ needs: []
2595
+ retry: *a1
2596
+ interruptible: true
2597
+ allow_failure: true
2598
+ 'api2 🚀 Deploy | stage ':
2599
+ stage: deploy stage
2600
+ image: path/to/docker/kubernetes:the-version
2601
+ variables:
2602
+ KUBERNETES_CPU_REQUEST: '0.22'
2603
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2604
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2605
+ script:
2606
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2607
+ - export ENV_SHORT="stage"
2608
+ - export APP_DIR="api"
2609
+ - export ENV_TYPE="stage"
2610
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2611
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2612
+ - 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")"
2613
+ - export HOST="api2.stage.test-app.pan.panter.cloud"
2614
+ - export ROOT_URL="https://api2.stage.test-app.pan.panter.cloud"
2615
+ - export HOST_INTERNAL="api2.stage.test-app.pan.panter.cloud"
2616
+ - export HOST_CANONICAL="api2.stage.test-app.pan.panter.cloud"
2617
+ - export ROOT_URL_INTERNAL="https://api2.stage.test-app.pan.panter.cloud"
2618
+ - export KUBE_NAMESPACE="pan-test-app-stage"
2619
+ - export KUBE_APP_NAME="api2"
2620
+ - export KUBE_APP_NAME_PREFIX=""
2621
+ - |-
2622
+ export multiline_from_api="line1
2623
+ line2
2624
+ line3
2625
+
2626
+ single quote: '
2627
+ doouble quote: \\"
2628
+ "
2629
+ - |-
2630
+ export multiline2="yeah
2631
+ yeah2
2632
+ yeah3
2633
+
2634
+ single quote: '
2635
+ doouble quote: \\"
2636
+ "
2637
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2638
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
2639
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
2640
+ - export DOCKER_IMAGE_NAME="stage/api2"
2641
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
2642
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2643
+ - export RELEASE_NAME="pan-test-app-stage-api2"
2644
+ - export HELM_EXPERIMENTAL_OCI="1"
2645
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2646
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2647
+ - export HELM_ARGS=""
2648
+ - export COMPONENT_NAME="api2"
2649
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2650
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2651
+ - kubectl config set-cluster "kube-pan-test-app-stage-api2" --server="$CL_stage_api2_KUBE_URL" --certificate-authority <(echo $CL_stage_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2652
+ - kubectl config set-credentials "kube-pan-test-app-stage-api2" --token="$CL_stage_api2_KUBE_TOKEN"
2653
+ - kubectl config set-context "kube-pan-test-app-stage-api2" --cluster="kube-pan-test-app-stage-api2" --user="kube-pan-test-app-stage-api2" --namespace="pan-test-app-stage"
2654
+ - kubectl config use-context "kube-pan-test-app-stage-api2"
2655
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeallvalues[collapsed=true]\\r\\e[0KWrite __all_values.yml for helm deployment"
2656
+ - |
2657
+ cat > __all_values.yml <<EOF
2658
+ env:
2659
+ secret: {}
2660
+ public:
2661
+ ENV_SHORT: |-
2662
+ stage
2663
+ APP_DIR: |-
2664
+ api
2665
+ ENV_TYPE: |-
2666
+ stage
2667
+ BUILD_INFO_BUILD_ID: |-
2668
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2669
+ BUILD_INFO_BUILD_TIME: |-
2670
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2671
+ BUILD_INFO_CURRENT_VERSION: |-
2672
+ $(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/^/ /')
2673
+ HOST: |-
2674
+ api2.stage.test-app.pan.panter.cloud
2675
+ ROOT_URL: |-
2676
+ https://api2.stage.test-app.pan.panter.cloud
2677
+ HOST_INTERNAL: |-
2678
+ api2.stage.test-app.pan.panter.cloud
2679
+ HOST_CANONICAL: |-
2680
+ api2.stage.test-app.pan.panter.cloud
2681
+ ROOT_URL_INTERNAL: |-
2682
+ https://api2.stage.test-app.pan.panter.cloud
2683
+ KUBE_NAMESPACE: |-
2684
+ pan-test-app-stage
2685
+ KUBE_APP_NAME: |-
2686
+ api2
2687
+ KUBE_APP_NAME_PREFIX: ""
2688
+ multiline_from_api: |
2689
+ line1
2690
+ line2
2691
+ line3
2692
+
2693
+ single quote: '
2694
+ doouble quote: "
2695
+ multiline2: |
2696
+ yeah
2697
+ yeah2
2698
+ yeah3
2699
+
2700
+ single quote: '
2701
+ doouble quote: "
2702
+ _ALL_ENV_VAR_KEYS: |-
2703
+ ["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","KUBE_NAMESPACE","KUBE_APP_NAME","KUBE_APP_NAME_PREFIX","multiline_from_api","multiline2"]
2704
+ application:
2705
+ host: |-
2706
+ api2.stage.test-app.pan.panter.cloud
2707
+ command: |-
2708
+ yarn start
2709
+ livenessProbe:
2710
+ httpGet:
2711
+ path: |-
2712
+ __health
2713
+ readinessProbe:
2714
+ httpGet:
2715
+ path: |-
2716
+ __health
2717
+ startupProbe:
2718
+ httpGet:
2719
+ path: |-
2720
+ __health
2721
+
2722
+ EOF
2723
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeallvalues\\r\\e[0K"
2724
+ - kubernetesCreateSecret
2725
+ - kubernetesDeploy
2726
+ - echo 'Uploading SBOM to Dependency Track'
2727
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api2" "https://api2.stage.test-app.pan.panter.cloud" "__sbom.json" vex.json || true
2728
+ - echo deployment successful 😻
2729
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.stage.test-app.pan.panter.cloud" >> gitlab_environment.env
2730
+ environment:
2731
+ name: stage/api2
2732
+ url: $CL_GITLAB_ENVIRONMENT_URL
2733
+ on_stop: 'api2 🛑 Stop ⚠️ | stage '
2734
+ artifacts:
2735
+ reports:
2736
+ dotenv: gitlab_environment.env
2737
+ rules:
2738
+ - when: on_success
2739
+ if: $CI_COMMIT_TAG
2740
+ needs:
2741
+ - job: 'api2 🔨 app | stage '
2742
+ artifacts: false
2743
+ - job: 'api2 🔨 docker | stage '
2744
+ artifacts: false
2745
+ - job: 'api2 🧾 sbom | stage '
2746
+ artifacts: true
2747
+ retry: *a1
2748
+ interruptible: true
2749
+ allow_failure: false
2750
+ 'api2 🛑 Stop ⚠️ | stage ':
2751
+ stage: stop stage
2752
+ image: path/to/docker/kubernetes:the-version
2753
+ variables:
2754
+ KUBERNETES_CPU_REQUEST: '0.22'
2755
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2756
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2757
+ GIT_STRATEGY: none
2758
+ script:
2759
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2760
+ - export ENV_SHORT="stage"
2761
+ - export APP_DIR="api"
2762
+ - export ENV_TYPE="stage"
2763
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2764
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2765
+ - 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")"
2766
+ - export HOST="api2.stage.test-app.pan.panter.cloud"
2767
+ - export ROOT_URL="https://api2.stage.test-app.pan.panter.cloud"
2768
+ - export HOST_INTERNAL="api2.stage.test-app.pan.panter.cloud"
2769
+ - export HOST_CANONICAL="api2.stage.test-app.pan.panter.cloud"
2770
+ - export ROOT_URL_INTERNAL="https://api2.stage.test-app.pan.panter.cloud"
2771
+ - export KUBE_NAMESPACE="pan-test-app-stage"
2772
+ - export KUBE_APP_NAME="api2"
2773
+ - export KUBE_APP_NAME_PREFIX=""
2774
+ - |-
2775
+ export multiline_from_api="line1
2776
+ line2
2777
+ line3
2778
+
2779
+ single quote: '
2780
+ doouble quote: \\"
2781
+ "
2782
+ - |-
2783
+ export multiline2="yeah
2784
+ yeah2
2785
+ yeah3
2786
+
2787
+ single quote: '
2788
+ doouble quote: \\"
2789
+ "
2790
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2791
+ - export RELEASE_NAME="pan-test-app-stage-api2"
2792
+ - export HELM_EXPERIMENTAL_OCI="1"
2793
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2794
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2795
+ - export HELM_ARGS=""
2796
+ - export COMPONENT_NAME="api2"
2797
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2798
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2799
+ - kubectl config set-cluster "kube-pan-test-app-stage-api2" --server="$CL_stage_api2_KUBE_URL" --certificate-authority <(echo $CL_stage_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2800
+ - kubectl config set-credentials "kube-pan-test-app-stage-api2" --token="$CL_stage_api2_KUBE_TOKEN"
2801
+ - kubectl config set-context "kube-pan-test-app-stage-api2" --cluster="kube-pan-test-app-stage-api2" --user="kube-pan-test-app-stage-api2" --namespace="pan-test-app-stage"
2802
+ - kubectl config use-context "kube-pan-test-app-stage-api2"
2803
+ - kubernetesDelete
2804
+ - echo 'Disabling component in Dependency Track'
2805
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api2" "https://api2.stage.test-app.pan.panter.cloud" || true
2806
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.stage.test-app.pan.panter.cloud" >> gitlab_environment.env
2807
+ environment:
2808
+ name: stage/api2
2809
+ url: $CL_GITLAB_ENVIRONMENT_URL
2810
+ action: stop
2811
+ artifacts:
2812
+ reports:
2813
+ dotenv: gitlab_environment.env
2814
+ rules:
2815
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2816
+ when: on_success
2817
+ - when: manual
2818
+ if: $CI_COMMIT_TAG
2819
+ needs: []
2820
+ retry: *a1
2821
+ interruptible: true
2822
+ allow_failure: true
2823
+ 'api2 ↩️ Rollback ⚠️ | stage ':
2824
+ stage: rollback stage
2825
+ image: path/to/docker/kubernetes:the-version
2826
+ variables:
2827
+ KUBERNETES_CPU_REQUEST: '0.22'
2828
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2829
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2830
+ GIT_STRATEGY: none
2831
+ script:
2832
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2833
+ - export ENV_SHORT="stage"
2834
+ - export APP_DIR="api"
2835
+ - export ENV_TYPE="stage"
2836
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2837
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2838
+ - 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")"
2839
+ - export HOST="api2.stage.test-app.pan.panter.cloud"
2840
+ - export ROOT_URL="https://api2.stage.test-app.pan.panter.cloud"
2841
+ - export HOST_INTERNAL="api2.stage.test-app.pan.panter.cloud"
2842
+ - export HOST_CANONICAL="api2.stage.test-app.pan.panter.cloud"
2843
+ - export ROOT_URL_INTERNAL="https://api2.stage.test-app.pan.panter.cloud"
2844
+ - export KUBE_NAMESPACE="pan-test-app-stage"
2845
+ - export KUBE_APP_NAME="api2"
2846
+ - export KUBE_APP_NAME_PREFIX=""
2847
+ - |-
2848
+ export multiline_from_api="line1
2849
+ line2
2850
+ line3
2851
+
2852
+ single quote: '
2853
+ doouble quote: \\"
2854
+ "
2855
+ - |-
2856
+ export multiline2="yeah
2857
+ yeah2
2858
+ yeah3
2859
+
2860
+ single quote: '
2861
+ doouble quote: \\"
2862
+ "
2863
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2864
+ - export RELEASE_NAME="pan-test-app-stage-api2"
2865
+ - export HELM_EXPERIMENTAL_OCI="1"
2866
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
2867
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
2868
+ - export HELM_ARGS=""
2869
+ - export COMPONENT_NAME="api2"
2870
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2871
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2872
+ - kubectl config set-cluster "kube-pan-test-app-stage-api2" --server="$CL_stage_api2_KUBE_URL" --certificate-authority <(echo $CL_stage_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
2873
+ - kubectl config set-credentials "kube-pan-test-app-stage-api2" --token="$CL_stage_api2_KUBE_TOKEN"
2874
+ - kubectl config set-context "kube-pan-test-app-stage-api2" --cluster="kube-pan-test-app-stage-api2" --user="kube-pan-test-app-stage-api2" --namespace="pan-test-app-stage"
2875
+ - kubectl config use-context "kube-pan-test-app-stage-api2"
2876
+ - kubernetesRollback
2877
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.stage.test-app.pan.panter.cloud" >> gitlab_environment.env
2878
+ environment:
2879
+ name: stage/api2
2880
+ url: $CL_GITLAB_ENVIRONMENT_URL
2881
+ action: access
2882
+ artifacts:
2883
+ reports:
2884
+ dotenv: gitlab_environment.env
2885
+ rules:
2886
+ - when: manual
2887
+ if: $CI_COMMIT_TAG
2888
+ needs: []
2889
+ retry: *a1
2890
+ interruptible: true
2891
+ allow_failure: true
2892
+ 'api2 🔨 app | prod ':
2893
+ stage: build
2894
+ image: path/to/docker/jobs-default:the-version
2895
+ variables:
2896
+ KUBERNETES_CPU_REQUEST: '0.45'
2897
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2898
+ KUBERNETES_MEMORY_LIMIT: 4Gi
2899
+ script:
2900
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2901
+ - export ENV_SHORT="prod"
2902
+ - export APP_DIR="api"
2903
+ - export ENV_TYPE="prod"
2904
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
2905
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
2906
+ - 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")"
2907
+ - export HOST="api2.prod.test-app.pan.panter.cloud"
2908
+ - export ROOT_URL="https://api2.prod.test-app.pan.panter.cloud"
2909
+ - export HOST_INTERNAL="api2.prod.test-app.pan.panter.cloud"
2910
+ - export HOST_CANONICAL="api2.prod.test-app.pan.panter.cloud"
2911
+ - export ROOT_URL_INTERNAL="https://api2.prod.test-app.pan.panter.cloud"
2912
+ - export KUBE_NAMESPACE="pan-test-app-prod"
2913
+ - export KUBE_APP_NAME="api2"
2914
+ - export KUBE_APP_NAME_PREFIX=""
2915
+ - |-
2916
+ export multiline_from_api="line1
2917
+ line2
2918
+ line3
2919
+
2920
+ single quote: '
2921
+ doouble quote: \\"
2922
+ "
2923
+ - |-
2924
+ export multiline2="yeah
2925
+ yeah2
2926
+ yeah3
2927
+
2928
+ single quote: '
2929
+ doouble quote: \\"
2930
+ "
2931
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
2932
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2933
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
2934
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2935
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2936
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2937
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2938
+ - cd api
2939
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
2940
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
2941
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
2942
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
2943
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
2944
+ - yarn install --immutable
2945
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
2946
+ - yarn build
2947
+ cache:
2948
+ - key: api-yarn
2949
+ policy: pull-push
2950
+ paths:
2951
+ - api/.yarn
2952
+ - key: api-node-modules
2953
+ policy: pull-push
2954
+ paths:
2955
+ - api/node_modules
2956
+ - key: api2-next-cache
2957
+ policy: pull-push
2958
+ paths:
2959
+ - api/.next/cache
2960
+ artifacts:
2961
+ paths:
2962
+ - api/__build_info.json
2963
+ - api/.next
2964
+ - api/dist
2965
+ expire_in: 1 day
2966
+ when: always
2967
+ reports: {}
2968
+ rules:
2969
+ - if: $CI_COMMIT_TAG
2970
+ needs: []
2971
+ retry: *a1
2972
+ interruptible: true
2973
+ 'api2 🔨 docker | prod ':
2974
+ stage: build
2975
+ image: path/to/docker/docker-build:the-version
2976
+ services:
2977
+ - name: docker:24.0.6-dind
2978
+ command:
2979
+ - --tls=false
2980
+ variables:
2981
+ DOCKER_HOST: tcp://0.0.0.0:2375
2982
+ DOCKER_TLS_CERTDIR: ''
2983
+ DOCKER_DRIVER: overlay2
2984
+ DOCKER_BUILDKIT: '1'
2985
+ KUBERNETES_CPU_REQUEST: '0.45'
2986
+ KUBERNETES_MEMORY_REQUEST: 1Gi
2987
+ KUBERNETES_MEMORY_LIMIT: 2Gi
2988
+ script:
2989
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2990
+ - export APP_DIR="api"
2991
+ - export DOCKER_BUILD_CONTEXT="."
2992
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
2993
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
2994
+ - export DOCKER_IMAGE_NAME="prod/api2"
2995
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
2996
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2997
+ - |-
2998
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
2999
+ RUN yarn plugin import workspace-tools
3000
+ RUN yarn workspaces focus --production && yarn rebuild"
3001
+ - |-
3002
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
3003
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
3004
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
3005
+ COPY --chown=node:node .yarn /app/.yarn"
3006
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
3007
+ - ensureNodeDockerfile
3008
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
3009
+ - docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY
3010
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
3011
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
3012
+ - 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
3013
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
3014
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
3015
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
3016
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
3017
+ - docker push $DOCKER_CACHE_IMAGE
3018
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
3019
+ cache:
3020
+ - key: api-yarn
3021
+ policy: pull
3022
+ paths:
3023
+ - api/.yarn
3024
+ rules:
3025
+ - if: $CI_COMMIT_TAG
3026
+ needs:
3027
+ - 'api2 🔨 app | prod '
3028
+ retry: *a1
3029
+ interruptible: true
3030
+ 'api2 🧾 sbom | prod ':
3031
+ stage: build
3032
+ image: aquasec/trivy:0.38.3
3033
+ variables: {}
3034
+ script:
3035
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
3036
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
3037
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
3038
+ artifacts:
3039
+ paths:
3040
+ - __sbom.json
3041
+ rules:
3042
+ - if: $CI_COMMIT_TAG
3043
+ needs: []
3044
+ retry: *a1
3045
+ interruptible: true
3046
+ allow_failure: true
3047
+ 'api2 🚀 Deploy | prod ':
3048
+ stage: deploy prod
3049
+ image: path/to/docker/kubernetes:the-version
3050
+ variables:
3051
+ KUBERNETES_CPU_REQUEST: '0.22'
3052
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3053
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3054
+ script:
3055
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
3056
+ - export ENV_SHORT="prod"
3057
+ - export APP_DIR="api"
3058
+ - export ENV_TYPE="prod"
3059
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3060
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3061
+ - 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")"
3062
+ - export HOST="api2.prod.test-app.pan.panter.cloud"
3063
+ - export ROOT_URL="https://api2.prod.test-app.pan.panter.cloud"
3064
+ - export HOST_INTERNAL="api2.prod.test-app.pan.panter.cloud"
3065
+ - export HOST_CANONICAL="api2.prod.test-app.pan.panter.cloud"
3066
+ - export ROOT_URL_INTERNAL="https://api2.prod.test-app.pan.panter.cloud"
3067
+ - export KUBE_NAMESPACE="pan-test-app-prod"
3068
+ - export KUBE_APP_NAME="api2"
3069
+ - export KUBE_APP_NAME_PREFIX=""
3070
+ - |-
3071
+ export multiline_from_api="line1
3072
+ line2
3073
+ line3
3074
+
3075
+ single quote: '
3076
+ doouble quote: \\"
3077
+ "
3078
+ - |-
3079
+ export multiline2="yeah
3080
+ yeah2
3081
+ yeah3
3082
+
3083
+ single quote: '
3084
+ doouble quote: \\"
3085
+ "
3086
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
3087
+ - export DOCKER_REGISTRY="$CI_REGISTRY"
3088
+ - export DOCKER_CACHE_IMAGE="$CI_REGISTRY_IMAGE/caches/api2"
3089
+ - export DOCKER_IMAGE_NAME="prod/api2"
3090
+ - export DOCKER_IMAGE="$CI_REGISTRY_IMAGE/$DOCKER_IMAGE_NAME"
3091
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
3092
+ - export RELEASE_NAME="pan-test-app-prod-api2"
3093
+ - export HELM_EXPERIMENTAL_OCI="1"
3094
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
3095
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
3096
+ - export HELM_ARGS=""
3097
+ - export COMPONENT_NAME="api2"
3098
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3099
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
3100
+ - kubectl config set-cluster "kube-pan-test-app-prod-api2" --server="$CL_prod_api2_KUBE_URL" --certificate-authority <(echo $CL_prod_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
3101
+ - kubectl config set-credentials "kube-pan-test-app-prod-api2" --token="$CL_prod_api2_KUBE_TOKEN"
3102
+ - kubectl config set-context "kube-pan-test-app-prod-api2" --cluster="kube-pan-test-app-prod-api2" --user="kube-pan-test-app-prod-api2" --namespace="pan-test-app-prod"
3103
+ - kubectl config use-context "kube-pan-test-app-prod-api2"
3104
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeallvalues[collapsed=true]\\r\\e[0KWrite __all_values.yml for helm deployment"
3105
+ - |
3106
+ cat > __all_values.yml <<EOF
3107
+ env:
3108
+ secret: {}
3109
+ public:
3110
+ ENV_SHORT: |-
3111
+ prod
3112
+ APP_DIR: |-
3113
+ api
3114
+ ENV_TYPE: |-
3115
+ prod
3116
+ BUILD_INFO_BUILD_ID: |-
3117
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
3118
+ BUILD_INFO_BUILD_TIME: |-
3119
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
3120
+ BUILD_INFO_CURRENT_VERSION: |-
3121
+ $(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/^/ /')
3122
+ HOST: |-
3123
+ api2.prod.test-app.pan.panter.cloud
3124
+ ROOT_URL: |-
3125
+ https://api2.prod.test-app.pan.panter.cloud
3126
+ HOST_INTERNAL: |-
3127
+ api2.prod.test-app.pan.panter.cloud
3128
+ HOST_CANONICAL: |-
3129
+ api2.prod.test-app.pan.panter.cloud
3130
+ ROOT_URL_INTERNAL: |-
3131
+ https://api2.prod.test-app.pan.panter.cloud
3132
+ KUBE_NAMESPACE: |-
3133
+ pan-test-app-prod
3134
+ KUBE_APP_NAME: |-
3135
+ api2
3136
+ KUBE_APP_NAME_PREFIX: ""
3137
+ multiline_from_api: |
3138
+ line1
3139
+ line2
3140
+ line3
3141
+
3142
+ single quote: '
3143
+ doouble quote: "
3144
+ multiline2: |
3145
+ yeah
3146
+ yeah2
3147
+ yeah3
3148
+
3149
+ single quote: '
3150
+ doouble quote: "
3151
+ _ALL_ENV_VAR_KEYS: |-
3152
+ ["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","KUBE_NAMESPACE","KUBE_APP_NAME","KUBE_APP_NAME_PREFIX","multiline_from_api","multiline2"]
3153
+ application:
3154
+ host: |-
3155
+ api2.prod.test-app.pan.panter.cloud
3156
+ command: |-
3157
+ yarn start
3158
+ livenessProbe:
3159
+ httpGet:
3160
+ path: |-
3161
+ __health
3162
+ readinessProbe:
3163
+ httpGet:
3164
+ path: |-
3165
+ __health
3166
+ startupProbe:
3167
+ httpGet:
3168
+ path: |-
3169
+ __health
3170
+
3171
+ EOF
3172
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeallvalues\\r\\e[0K"
3173
+ - kubernetesCreateSecret
3174
+ - kubernetesDeploy
3175
+ - echo 'Uploading SBOM to Dependency Track'
3176
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api2" "https://api2.prod.test-app.pan.panter.cloud" "__sbom.json" vex.json || true
3177
+ - echo deployment successful 😻
3178
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.prod.test-app.pan.panter.cloud" >> gitlab_environment.env
3179
+ environment:
3180
+ name: prod/api2
3181
+ url: $CL_GITLAB_ENVIRONMENT_URL
3182
+ on_stop: 'api2 🛑 Stop ⚠️ | prod '
3183
+ artifacts:
3184
+ reports:
3185
+ dotenv: gitlab_environment.env
3186
+ rules:
3187
+ - when: manual
3188
+ if: $CI_COMMIT_TAG
3189
+ needs:
3190
+ - job: 'api2 🔨 app | prod '
3191
+ artifacts: false
3192
+ - job: 'api2 🔨 docker | prod '
3193
+ artifacts: false
3194
+ - job: 'api2 🧾 sbom | prod '
3195
+ artifacts: true
3196
+ retry: *a1
3197
+ interruptible: true
3198
+ allow_failure: true
3199
+ 'api2 🛑 Stop ⚠️ | prod ':
3200
+ stage: stop prod
3201
+ image: path/to/docker/kubernetes:the-version
3202
+ variables:
3203
+ KUBERNETES_CPU_REQUEST: '0.22'
3204
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3205
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3206
+ GIT_STRATEGY: none
3207
+ script:
3208
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
3209
+ - export ENV_SHORT="prod"
3210
+ - export APP_DIR="api"
3211
+ - export ENV_TYPE="prod"
3212
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3213
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3214
+ - 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")"
3215
+ - export HOST="api2.prod.test-app.pan.panter.cloud"
3216
+ - export ROOT_URL="https://api2.prod.test-app.pan.panter.cloud"
3217
+ - export HOST_INTERNAL="api2.prod.test-app.pan.panter.cloud"
3218
+ - export HOST_CANONICAL="api2.prod.test-app.pan.panter.cloud"
3219
+ - export ROOT_URL_INTERNAL="https://api2.prod.test-app.pan.panter.cloud"
3220
+ - export KUBE_NAMESPACE="pan-test-app-prod"
3221
+ - export KUBE_APP_NAME="api2"
3222
+ - export KUBE_APP_NAME_PREFIX=""
3223
+ - |-
3224
+ export multiline_from_api="line1
3225
+ line2
3226
+ line3
3227
+
3228
+ single quote: '
3229
+ doouble quote: \\"
3230
+ "
3231
+ - |-
3232
+ export multiline2="yeah
3233
+ yeah2
3234
+ yeah3
3235
+
3236
+ single quote: '
3237
+ doouble quote: \\"
3238
+ "
3239
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
3240
+ - export RELEASE_NAME="pan-test-app-prod-api2"
3241
+ - export HELM_EXPERIMENTAL_OCI="1"
3242
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
3243
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
3244
+ - export HELM_ARGS=""
3245
+ - export COMPONENT_NAME="api2"
3246
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3247
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
3248
+ - kubectl config set-cluster "kube-pan-test-app-prod-api2" --server="$CL_prod_api2_KUBE_URL" --certificate-authority <(echo $CL_prod_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
3249
+ - kubectl config set-credentials "kube-pan-test-app-prod-api2" --token="$CL_prod_api2_KUBE_TOKEN"
3250
+ - kubectl config set-context "kube-pan-test-app-prod-api2" --cluster="kube-pan-test-app-prod-api2" --user="kube-pan-test-app-prod-api2" --namespace="pan-test-app-prod"
3251
+ - kubectl config use-context "kube-pan-test-app-prod-api2"
3252
+ - kubernetesDelete
3253
+ - echo 'Disabling component in Dependency Track'
3254
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api2" "https://api2.prod.test-app.pan.panter.cloud" || true
3255
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.prod.test-app.pan.panter.cloud" >> gitlab_environment.env
3256
+ environment:
3257
+ name: prod/api2
3258
+ url: $CL_GITLAB_ENVIRONMENT_URL
3259
+ action: stop
3260
+ artifacts:
3261
+ reports:
3262
+ dotenv: gitlab_environment.env
3263
+ rules:
3264
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
3265
+ when: on_success
3266
+ - when: manual
3267
+ if: $CI_COMMIT_TAG
3268
+ needs: []
3269
+ retry: *a1
3270
+ interruptible: true
3271
+ allow_failure: true
3272
+ 'api2 ↩️ Rollback ⚠️ | prod ':
3273
+ stage: rollback prod
3274
+ image: path/to/docker/kubernetes:the-version
3275
+ variables:
3276
+ KUBERNETES_CPU_REQUEST: '0.22'
3277
+ KUBERNETES_MEMORY_REQUEST: 200Mi
3278
+ KUBERNETES_MEMORY_LIMIT: 400Mi
3279
+ GIT_STRATEGY: none
3280
+ script:
3281
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
3282
+ - export ENV_SHORT="prod"
3283
+ - export APP_DIR="api"
3284
+ - export ENV_TYPE="prod"
3285
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3286
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
3287
+ - 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")"
3288
+ - export HOST="api2.prod.test-app.pan.panter.cloud"
3289
+ - export ROOT_URL="https://api2.prod.test-app.pan.panter.cloud"
3290
+ - export HOST_INTERNAL="api2.prod.test-app.pan.panter.cloud"
3291
+ - export HOST_CANONICAL="api2.prod.test-app.pan.panter.cloud"
3292
+ - export ROOT_URL_INTERNAL="https://api2.prod.test-app.pan.panter.cloud"
3293
+ - export KUBE_NAMESPACE="pan-test-app-prod"
3294
+ - export KUBE_APP_NAME="api2"
3295
+ - export KUBE_APP_NAME_PREFIX=""
3296
+ - |-
3297
+ export multiline_from_api="line1
3298
+ line2
3299
+ line3
3300
+
3301
+ single quote: '
3302
+ doouble quote: \\"
3303
+ "
3304
+ - |-
3305
+ export multiline2="yeah
3306
+ yeah2
3307
+ yeah3
3308
+
3309
+ single quote: '
3310
+ doouble quote: \\"
3311
+ "
3312
+ - 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\\",\\"KUBE_NAMESPACE\\",\\"KUBE_APP_NAME\\",\\"KUBE_APP_NAME_PREFIX\\",\\"multiline_from_api\\",\\"multiline2\\"]"
3313
+ - export RELEASE_NAME="pan-test-app-prod-api2"
3314
+ - export HELM_EXPERIMENTAL_OCI="1"
3315
+ - export KUBE_DOCKER_IMAGE_PULL_SECRET="gitlab-registry-api2"
3316
+ - export HELM_GITLAB_CHART_NAME="/helm-charts/the-panter-chart"
3317
+ - export HELM_ARGS=""
3318
+ - export COMPONENT_NAME="api2"
3319
+ - export BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
3320
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
3321
+ - kubectl config set-cluster "kube-pan-test-app-prod-api2" --server="$CL_prod_api2_KUBE_URL" --certificate-authority <(echo $CL_prod_api2_KUBE_CA_PEM | base64 -d) --embed-certs=true
3322
+ - kubectl config set-credentials "kube-pan-test-app-prod-api2" --token="$CL_prod_api2_KUBE_TOKEN"
3323
+ - kubectl config set-context "kube-pan-test-app-prod-api2" --cluster="kube-pan-test-app-prod-api2" --user="kube-pan-test-app-prod-api2" --namespace="pan-test-app-prod"
3324
+ - kubectl config use-context "kube-pan-test-app-prod-api2"
3325
+ - kubernetesRollback
3326
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://api2.prod.test-app.pan.panter.cloud" >> gitlab_environment.env
3327
+ environment:
3328
+ name: prod/api2
3329
+ url: $CL_GITLAB_ENVIRONMENT_URL
3330
+ action: access
3331
+ artifacts:
3332
+ reports:
3333
+ dotenv: gitlab_environment.env
3334
+ rules:
3335
+ - when: manual
3336
+ if: $CI_COMMIT_TAG
3337
+ needs: []
3338
+ retry: *a1
3339
+ interruptible: true
3340
+ allow_failure: true
3341
+ create release:
3342
+ stage: release
3343
+ image: path/to/docker/semantic-release:the-version
3344
+ script:
3345
+ - semanticRelease
3346
+ after_script:
3347
+ - echo '👉 The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
3348
+ rules:
3349
+ - &a2
3350
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
3351
+ when: never
3352
+ - &a3
3353
+ if: $CI_PIPELINE_SOURCE == "schedule"
3354
+ when: never
3355
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $AUTO_RELEASE == "true"
3356
+ when: on_success
3357
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
3358
+ when: manual
3359
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
3360
+ when: manual
3361
+ ⚠️ force create release:
3362
+ stage: release
3363
+ image: path/to/docker/semantic-release:the-version
3364
+ script:
3365
+ - semanticRelease
3366
+ after_script:
3367
+ - echo '👉 The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
3368
+ rules:
3369
+ - *a2
3370
+ - *a3
3371
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
3372
+ when: manual
3373
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
3374
+ when: manual
3375
+ needs: []
3376
+ "
3377
+ `;
3378
+
3
3379
  exports[`matches snapshot for multiline-var 1`] = `
4
3380
  {
5
3381
  "mainBranch": {