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