@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,2154 @@
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
+ app ๐Ÿ›ก 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="app"
58
+ - export LC_A="L=en_US.UTF-8"
59
+ - export LANG="en_US.UTF-8"
60
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
61
+ - cd app
62
+ - yarn npm audit --environment production
63
+ rules:
64
+ - when: never
65
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
66
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
67
+ - if: $CI_MERGE_REQUEST_ID
68
+ needs: []
69
+ retry: &a1
70
+ max: 2
71
+ when:
72
+ - runner_system_failure
73
+ - stuck_or_timeout_failure
74
+ interruptible: true
75
+ allow_failure: true
76
+ app ๐Ÿ‘ฎ lint:
77
+ stage: test
78
+ image: path/to/docker/jobs-default:the-version
79
+ variables:
80
+ KUBERNETES_CPU_REQUEST: '0.45'
81
+ KUBERNETES_MEMORY_REQUEST: 1Gi
82
+ KUBERNETES_MEMORY_LIMIT: 4Gi
83
+ script:
84
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
85
+ - export APP_PATH="app"
86
+ - export LC_A="L=en_US.UTF-8"
87
+ - export LANG="en_US.UTF-8"
88
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
89
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
90
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
91
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
92
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
93
+ - cd app
94
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
95
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
96
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
97
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
98
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
99
+ - yarn install --immutable
100
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
101
+ - yarn lint
102
+ cache:
103
+ - key: app-yarn
104
+ policy: pull-push
105
+ paths:
106
+ - app/.yarn
107
+ - key: app-node-modules
108
+ policy: pull-push
109
+ paths:
110
+ - app/node_modules
111
+ rules:
112
+ - when: never
113
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
114
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
115
+ - if: $CI_MERGE_REQUEST_ID
116
+ needs: []
117
+ retry: *a1
118
+ interruptible: true
119
+ app ๐Ÿงช test:
120
+ stage: test
121
+ image: path/to/docker/jobs-testing-chrome:the-version
122
+ variables:
123
+ KUBERNETES_CPU_REQUEST: '0.45'
124
+ KUBERNETES_MEMORY_REQUEST: 1Gi
125
+ KUBERNETES_MEMORY_LIMIT: 4Gi
126
+ script:
127
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
128
+ - export APP_PATH="app"
129
+ - export LC_A="L=en_US.UTF-8"
130
+ - export LANG="en_US.UTF-8"
131
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
132
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
133
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
134
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
135
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
136
+ - cd app
137
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
138
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
139
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
140
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
141
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
142
+ - yarn install --immutable
143
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
144
+ - yarn test
145
+ cache:
146
+ - key: app-yarn
147
+ policy: pull-push
148
+ paths:
149
+ - app/.yarn
150
+ - key: app-node-modules
151
+ policy: pull-push
152
+ paths:
153
+ - app/node_modules
154
+ rules:
155
+ - when: never
156
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
157
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
158
+ - if: $CI_MERGE_REQUEST_ID
159
+ needs: []
160
+ retry: *a1
161
+ interruptible: true
162
+ 'app ๐Ÿ”จ app | dev ':
163
+ stage: build
164
+ tags:
165
+ - mac-runner
166
+ image: path/to/docker/jobs-default:the-version
167
+ variables:
168
+ KUBERNETES_CPU_REQUEST: '0.45'
169
+ KUBERNETES_MEMORY_REQUEST: 1Gi
170
+ KUBERNETES_MEMORY_LIMIT: 4Gi
171
+ script:
172
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
173
+ - export ENV_SHORT="dev"
174
+ - export APP_DIR="app"
175
+ - export ENV_TYPE="dev"
176
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
177
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
178
+ - 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")"
179
+ - export HOST="unknown-host.example.com"
180
+ - export ROOT_URL="https://unknown-host.example.com"
181
+ - export HOST_INTERNAL="unknown-host.example.com"
182
+ - export HOST_CANONICAL="unknown-host.example.com"
183
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
184
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_dev_app_APP_STORE_CONNECT_API_KEY_CONTENT"
185
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_dev_app_APP_STORE_CONNECT_ISSUER_ID"
186
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_dev_app_APP_STORE_CONNECT_API_KEY_ID"
187
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
188
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
189
+ - export LC_A="L=en_US.UTF-8"
190
+ - export LANG="en_US.UTF-8"
191
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
192
+ - echo -e "\\e[0Ksection_start:$(date +%s):write-dotenv-app[collapsed=true]\\r\\e[0Kwrite dot env"
193
+ - |-
194
+ cat <<EOF > app/.env
195
+ ENV_SHORT=dev
196
+ APP_DIR=app
197
+ ENV_TYPE=dev
198
+ HOST=unknown-host.example.com
199
+ ROOT_URL=https://unknown-host.example.com
200
+ HOST_INTERNAL=unknown-host.example.com
201
+ HOST_CANONICAL=unknown-host.example.com
202
+ ROOT_URL_INTERNAL=https://unknown-host.example.com
203
+ APP_STORE_CONNECT_API_KEY_CONTENT=$CL_dev_app_APP_STORE_CONNECT_API_KEY_CONTENT
204
+ APP_STORE_CONNECT_ISSUER_ID=$CL_dev_app_APP_STORE_CONNECT_ISSUER_ID
205
+ APP_STORE_CONNECT_API_KEY_ID=$CL_dev_app_APP_STORE_CONNECT_API_KEY_ID
206
+ GRAPHQL_URL=https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql
207
+ _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","APP_STORE_CONNECT_API_KEY_CONTENT","APP_STORE_CONNECT_ISSUER_ID","APP_STORE_CONNECT_API_KEY_ID","GRAPHQL_URL"]
208
+ EOF
209
+ - echo -e "\\e[0Ksection_end:$(date +%s):write-dotenv-app\\r\\e[0K"
210
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > app/__build_info.json
211
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
212
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
213
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
214
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
215
+ - cd app
216
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
217
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
218
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
219
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
220
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
221
+ - yarn install --immutable
222
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
223
+ - bundle config set --local path 'vendor/ruby'
224
+ - gem install bundler
225
+ - bundle install
226
+ - bundle exec pod install --project-directory=ios
227
+ - bundle exec fastlane build
228
+ cache:
229
+ - key:
230
+ files:
231
+ - app/Gemfile.lock
232
+ paths:
233
+ - app/vendor
234
+ - key: app-yarn
235
+ policy: pull-push
236
+ paths:
237
+ - app/.yarn
238
+ - key: app-node-modules
239
+ policy: pull-push
240
+ paths:
241
+ - app/node_modules
242
+ - key: app-next-cache
243
+ policy: pull-push
244
+ paths:
245
+ - app/.next/cache
246
+ artifacts:
247
+ paths:
248
+ - app/__build_info.json
249
+ - app/.next
250
+ - app/dist
251
+ exclude:
252
+ - app/.env
253
+ expire_in: 1 day
254
+ when: always
255
+ reports: {}
256
+ rules:
257
+ - when: never
258
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
259
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
260
+ needs: []
261
+ retry: *a1
262
+ interruptible: true
263
+ 'app ๐Ÿงพ sbom | dev ':
264
+ stage: build
265
+ image: aquasec/trivy:0.38.3
266
+ variables: {}
267
+ script:
268
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
269
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
270
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" app
271
+ artifacts:
272
+ paths:
273
+ - __sbom.json
274
+ rules:
275
+ - when: never
276
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
277
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
278
+ needs: []
279
+ retry: *a1
280
+ interruptible: true
281
+ allow_failure: true
282
+ 'app ๐Ÿš€ Deploy | dev ':
283
+ stage: deploy dev
284
+ tags:
285
+ - mac-runner
286
+ image: path/to/docker/jobs-default:the-version
287
+ variables:
288
+ KUBERNETES_CPU_REQUEST: '0.22'
289
+ KUBERNETES_MEMORY_REQUEST: 200Mi
290
+ KUBERNETES_MEMORY_LIMIT: 400Mi
291
+ script:
292
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
293
+ - export ENV_SHORT="dev"
294
+ - export APP_DIR="app"
295
+ - export ENV_TYPE="dev"
296
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
297
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
298
+ - 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")"
299
+ - export HOST="unknown-host.example.com"
300
+ - export ROOT_URL="https://unknown-host.example.com"
301
+ - export HOST_INTERNAL="unknown-host.example.com"
302
+ - export HOST_CANONICAL="unknown-host.example.com"
303
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
304
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_dev_app_APP_STORE_CONNECT_API_KEY_CONTENT"
305
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_dev_app_APP_STORE_CONNECT_ISSUER_ID"
306
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_dev_app_APP_STORE_CONNECT_API_KEY_ID"
307
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
308
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
309
+ - export LC_A="L=en_US.UTF-8"
310
+ - export LANG="en_US.UTF-8"
311
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
312
+ - cd app
313
+ - bundle config set --local path 'vendor/ruby'
314
+ - gem install bundler
315
+ - bundle install
316
+ - bundle exec fastlane deploy_test
317
+ - echo 'Uploading SBOM to Dependency Track'
318
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/app" "https://unknown-host.example.com" "__sbom.json" vex.json || true
319
+ cache:
320
+ - key:
321
+ files:
322
+ - app/Gemfile.lock
323
+ paths:
324
+ - app/vendor
325
+ rules:
326
+ - when: never
327
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
328
+ - when: on_success
329
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
330
+ needs:
331
+ - job: app ๐Ÿ‘ฎ lint
332
+ artifacts: false
333
+ - job: 'app ๐Ÿ”จ app | dev '
334
+ artifacts: true
335
+ - job: app ๐Ÿงช test
336
+ artifacts: false
337
+ - job: 'app ๐Ÿงพ sbom | dev '
338
+ artifacts: true
339
+ - job: app ๐Ÿ›ก audit
340
+ artifacts: false
341
+ retry: *a1
342
+ interruptible: true
343
+ allow_failure: false
344
+ 'app ๐Ÿ”จ app | review ':
345
+ stage: build
346
+ tags:
347
+ - mac-runner
348
+ image: path/to/docker/jobs-default:the-version
349
+ variables:
350
+ KUBERNETES_CPU_REQUEST: '0.45'
351
+ KUBERNETES_MEMORY_REQUEST: 1Gi
352
+ KUBERNETES_MEMORY_LIMIT: 4Gi
353
+ script:
354
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
355
+ - export ENV_SHORT="review"
356
+ - export APP_DIR="app"
357
+ - export ENV_TYPE="review"
358
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
359
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
360
+ - 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")"
361
+ - export HOST="unknown-host.example.com"
362
+ - export ROOT_URL="https://unknown-host.example.com"
363
+ - export HOST_INTERNAL="unknown-host.example.com"
364
+ - export HOST_CANONICAL="unknown-host.example.com"
365
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
366
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_review_app_APP_STORE_CONNECT_API_KEY_CONTENT"
367
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_review_app_APP_STORE_CONNECT_ISSUER_ID"
368
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_review_app_APP_STORE_CONNECT_API_KEY_ID"
369
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
370
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
371
+ - export LC_A="L=en_US.UTF-8"
372
+ - export LANG="en_US.UTF-8"
373
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
374
+ - echo -e "\\e[0Ksection_start:$(date +%s):write-dotenv-app[collapsed=true]\\r\\e[0Kwrite dot env"
375
+ - |-
376
+ cat <<EOF > app/.env
377
+ ENV_SHORT=review
378
+ APP_DIR=app
379
+ ENV_TYPE=review
380
+ HOST=unknown-host.example.com
381
+ ROOT_URL=https://unknown-host.example.com
382
+ HOST_INTERNAL=unknown-host.example.com
383
+ HOST_CANONICAL=unknown-host.example.com
384
+ ROOT_URL_INTERNAL=https://unknown-host.example.com
385
+ APP_STORE_CONNECT_API_KEY_CONTENT=$CL_review_app_APP_STORE_CONNECT_API_KEY_CONTENT
386
+ APP_STORE_CONNECT_ISSUER_ID=$CL_review_app_APP_STORE_CONNECT_ISSUER_ID
387
+ APP_STORE_CONNECT_API_KEY_ID=$CL_review_app_APP_STORE_CONNECT_API_KEY_ID
388
+ GRAPHQL_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql
389
+ _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","APP_STORE_CONNECT_API_KEY_CONTENT","APP_STORE_CONNECT_ISSUER_ID","APP_STORE_CONNECT_API_KEY_ID","GRAPHQL_URL"]
390
+ EOF
391
+ - echo -e "\\e[0Ksection_end:$(date +%s):write-dotenv-app\\r\\e[0K"
392
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > app/__build_info.json
393
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
394
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
395
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
396
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
397
+ - cd app
398
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
399
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
400
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
401
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
402
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
403
+ - yarn install --immutable
404
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
405
+ - bundle config set --local path 'vendor/ruby'
406
+ - gem install bundler
407
+ - bundle install
408
+ - bundle exec pod install --project-directory=ios
409
+ - bundle exec fastlane build
410
+ cache:
411
+ - key:
412
+ files:
413
+ - app/Gemfile.lock
414
+ paths:
415
+ - app/vendor
416
+ - key: app-yarn
417
+ policy: pull-push
418
+ paths:
419
+ - app/.yarn
420
+ - key: app-node-modules
421
+ policy: pull-push
422
+ paths:
423
+ - app/node_modules
424
+ - key: app-next-cache
425
+ policy: pull-push
426
+ paths:
427
+ - app/.next/cache
428
+ artifacts:
429
+ paths:
430
+ - app/__build_info.json
431
+ - app/.next
432
+ - app/dist
433
+ exclude:
434
+ - app/.env
435
+ expire_in: 1 day
436
+ when: always
437
+ reports: {}
438
+ rules:
439
+ - if: $CI_MERGE_REQUEST_ID
440
+ needs: []
441
+ retry: *a1
442
+ interruptible: true
443
+ 'app ๐Ÿงพ sbom | review ':
444
+ stage: build
445
+ image: aquasec/trivy:0.38.3
446
+ variables: {}
447
+ script:
448
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
449
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
450
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" app
451
+ artifacts:
452
+ paths:
453
+ - __sbom.json
454
+ rules:
455
+ - if: $CI_MERGE_REQUEST_ID
456
+ needs: []
457
+ retry: *a1
458
+ interruptible: true
459
+ allow_failure: true
460
+ 'app ๐Ÿš€ Deploy | review ':
461
+ stage: deploy review
462
+ tags:
463
+ - mac-runner
464
+ image: path/to/docker/jobs-default:the-version
465
+ variables:
466
+ KUBERNETES_CPU_REQUEST: '0.22'
467
+ KUBERNETES_MEMORY_REQUEST: 200Mi
468
+ KUBERNETES_MEMORY_LIMIT: 400Mi
469
+ script:
470
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
471
+ - export ENV_SHORT="review"
472
+ - export APP_DIR="app"
473
+ - export ENV_TYPE="review"
474
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
475
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
476
+ - 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")"
477
+ - export HOST="unknown-host.example.com"
478
+ - export ROOT_URL="https://unknown-host.example.com"
479
+ - export HOST_INTERNAL="unknown-host.example.com"
480
+ - export HOST_CANONICAL="unknown-host.example.com"
481
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
482
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_review_app_APP_STORE_CONNECT_API_KEY_CONTENT"
483
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_review_app_APP_STORE_CONNECT_ISSUER_ID"
484
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_review_app_APP_STORE_CONNECT_API_KEY_ID"
485
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
486
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
487
+ - export LC_A="L=en_US.UTF-8"
488
+ - export LANG="en_US.UTF-8"
489
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
490
+ - cd app
491
+ - bundle config set --local path 'vendor/ruby'
492
+ - gem install bundler
493
+ - bundle install
494
+ - bundle exec fastlane deploy_test
495
+ - echo 'Uploading SBOM to Dependency Track'
496
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/app" "https://unknown-host.example.com" "__sbom.json" vex.json || true
497
+ cache:
498
+ - key:
499
+ files:
500
+ - app/Gemfile.lock
501
+ paths:
502
+ - app/vendor
503
+ rules:
504
+ - when: on_success
505
+ if: $CI_MERGE_REQUEST_ID
506
+ needs:
507
+ - job: app ๐Ÿ‘ฎ lint
508
+ artifacts: false
509
+ - job: 'app ๐Ÿ”จ app | review '
510
+ artifacts: true
511
+ - job: app ๐Ÿงช test
512
+ artifacts: false
513
+ - job: 'app ๐Ÿงพ sbom | review '
514
+ artifacts: true
515
+ - job: app ๐Ÿ›ก audit
516
+ artifacts: false
517
+ retry: *a1
518
+ interruptible: true
519
+ allow_failure: false
520
+ 'app ๐Ÿ”จ app | stage ':
521
+ stage: build
522
+ tags:
523
+ - mac-runner
524
+ image: path/to/docker/jobs-default:the-version
525
+ variables:
526
+ KUBERNETES_CPU_REQUEST: '0.45'
527
+ KUBERNETES_MEMORY_REQUEST: 1Gi
528
+ KUBERNETES_MEMORY_LIMIT: 4Gi
529
+ script:
530
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
531
+ - export ENV_SHORT="stage"
532
+ - export APP_DIR="app"
533
+ - export ENV_TYPE="stage"
534
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
535
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
536
+ - 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")"
537
+ - export HOST="unknown-host.example.com"
538
+ - export ROOT_URL="https://unknown-host.example.com"
539
+ - export HOST_INTERNAL="unknown-host.example.com"
540
+ - export HOST_CANONICAL="unknown-host.example.com"
541
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
542
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_stage_app_APP_STORE_CONNECT_API_KEY_CONTENT"
543
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_stage_app_APP_STORE_CONNECT_ISSUER_ID"
544
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_stage_app_APP_STORE_CONNECT_API_KEY_ID"
545
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
546
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
547
+ - export LC_A="L=en_US.UTF-8"
548
+ - export LANG="en_US.UTF-8"
549
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
550
+ - echo -e "\\e[0Ksection_start:$(date +%s):write-dotenv-app[collapsed=true]\\r\\e[0Kwrite dot env"
551
+ - |-
552
+ cat <<EOF > app/.env
553
+ ENV_SHORT=stage
554
+ APP_DIR=app
555
+ ENV_TYPE=stage
556
+ HOST=unknown-host.example.com
557
+ ROOT_URL=https://unknown-host.example.com
558
+ HOST_INTERNAL=unknown-host.example.com
559
+ HOST_CANONICAL=unknown-host.example.com
560
+ ROOT_URL_INTERNAL=https://unknown-host.example.com
561
+ APP_STORE_CONNECT_API_KEY_CONTENT=$CL_stage_app_APP_STORE_CONNECT_API_KEY_CONTENT
562
+ APP_STORE_CONNECT_ISSUER_ID=$CL_stage_app_APP_STORE_CONNECT_ISSUER_ID
563
+ APP_STORE_CONNECT_API_KEY_ID=$CL_stage_app_APP_STORE_CONNECT_API_KEY_ID
564
+ GRAPHQL_URL=https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql
565
+ _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","APP_STORE_CONNECT_API_KEY_CONTENT","APP_STORE_CONNECT_ISSUER_ID","APP_STORE_CONNECT_API_KEY_ID","GRAPHQL_URL"]
566
+ EOF
567
+ - echo -e "\\e[0Ksection_end:$(date +%s):write-dotenv-app\\r\\e[0K"
568
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > app/__build_info.json
569
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
570
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
571
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
572
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
573
+ - cd app
574
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
575
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
576
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
577
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
578
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
579
+ - yarn install --immutable
580
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
581
+ - bundle config set --local path 'vendor/ruby'
582
+ - gem install bundler
583
+ - bundle install
584
+ - bundle exec pod install --project-directory=ios
585
+ - bundle exec fastlane build
586
+ cache:
587
+ - key:
588
+ files:
589
+ - app/Gemfile.lock
590
+ paths:
591
+ - app/vendor
592
+ - key: app-yarn
593
+ policy: pull-push
594
+ paths:
595
+ - app/.yarn
596
+ - key: app-node-modules
597
+ policy: pull-push
598
+ paths:
599
+ - app/node_modules
600
+ - key: app-next-cache
601
+ policy: pull-push
602
+ paths:
603
+ - app/.next/cache
604
+ artifacts:
605
+ paths:
606
+ - app/__build_info.json
607
+ - app/.next
608
+ - app/dist
609
+ exclude:
610
+ - app/.env
611
+ expire_in: 1 day
612
+ when: always
613
+ reports: {}
614
+ rules:
615
+ - if: $CI_COMMIT_TAG
616
+ needs: []
617
+ retry: *a1
618
+ interruptible: true
619
+ 'app ๐Ÿงพ sbom | stage ':
620
+ stage: build
621
+ image: aquasec/trivy:0.38.3
622
+ variables: {}
623
+ script:
624
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
625
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
626
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" app
627
+ artifacts:
628
+ paths:
629
+ - __sbom.json
630
+ rules:
631
+ - if: $CI_COMMIT_TAG
632
+ needs: []
633
+ retry: *a1
634
+ interruptible: true
635
+ allow_failure: true
636
+ 'app ๐Ÿš€ Deploy | stage ':
637
+ stage: deploy stage
638
+ tags:
639
+ - mac-runner
640
+ image: path/to/docker/jobs-default:the-version
641
+ variables:
642
+ KUBERNETES_CPU_REQUEST: '0.22'
643
+ KUBERNETES_MEMORY_REQUEST: 200Mi
644
+ KUBERNETES_MEMORY_LIMIT: 400Mi
645
+ script:
646
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
647
+ - export ENV_SHORT="stage"
648
+ - export APP_DIR="app"
649
+ - export ENV_TYPE="stage"
650
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
651
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
652
+ - 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")"
653
+ - export HOST="unknown-host.example.com"
654
+ - export ROOT_URL="https://unknown-host.example.com"
655
+ - export HOST_INTERNAL="unknown-host.example.com"
656
+ - export HOST_CANONICAL="unknown-host.example.com"
657
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
658
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_stage_app_APP_STORE_CONNECT_API_KEY_CONTENT"
659
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_stage_app_APP_STORE_CONNECT_ISSUER_ID"
660
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_stage_app_APP_STORE_CONNECT_API_KEY_ID"
661
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
662
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
663
+ - export LC_A="L=en_US.UTF-8"
664
+ - export LANG="en_US.UTF-8"
665
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
666
+ - cd app
667
+ - bundle config set --local path 'vendor/ruby'
668
+ - gem install bundler
669
+ - bundle install
670
+ - bundle exec fastlane deploy_test
671
+ - echo 'Uploading SBOM to Dependency Track'
672
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/app" "https://unknown-host.example.com" "__sbom.json" vex.json || true
673
+ cache:
674
+ - key:
675
+ files:
676
+ - app/Gemfile.lock
677
+ paths:
678
+ - app/vendor
679
+ rules:
680
+ - when: on_success
681
+ if: $CI_COMMIT_TAG
682
+ needs:
683
+ - job: 'app ๐Ÿ”จ app | stage '
684
+ artifacts: true
685
+ - job: 'app ๐Ÿงพ sbom | stage '
686
+ artifacts: true
687
+ retry: *a1
688
+ interruptible: true
689
+ allow_failure: false
690
+ 'app ๐Ÿ”จ app | prod ':
691
+ stage: build
692
+ tags:
693
+ - mac-runner
694
+ image: path/to/docker/jobs-default:the-version
695
+ variables:
696
+ KUBERNETES_CPU_REQUEST: '0.45'
697
+ KUBERNETES_MEMORY_REQUEST: 1Gi
698
+ KUBERNETES_MEMORY_LIMIT: 4Gi
699
+ script:
700
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
701
+ - export ENV_SHORT="prod"
702
+ - export APP_DIR="app"
703
+ - export ENV_TYPE="prod"
704
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
705
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
706
+ - 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")"
707
+ - export HOST="unknown-host.example.com"
708
+ - export ROOT_URL="https://unknown-host.example.com"
709
+ - export HOST_INTERNAL="unknown-host.example.com"
710
+ - export HOST_CANONICAL="unknown-host.example.com"
711
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
712
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_prod_app_APP_STORE_CONNECT_API_KEY_CONTENT"
713
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_prod_app_APP_STORE_CONNECT_ISSUER_ID"
714
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_prod_app_APP_STORE_CONNECT_API_KEY_ID"
715
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
716
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
717
+ - export LC_A="L=en_US.UTF-8"
718
+ - export LANG="en_US.UTF-8"
719
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
720
+ - echo -e "\\e[0Ksection_start:$(date +%s):write-dotenv-app[collapsed=true]\\r\\e[0Kwrite dot env"
721
+ - |-
722
+ cat <<EOF > app/.env
723
+ ENV_SHORT=prod
724
+ APP_DIR=app
725
+ ENV_TYPE=prod
726
+ HOST=unknown-host.example.com
727
+ ROOT_URL=https://unknown-host.example.com
728
+ HOST_INTERNAL=unknown-host.example.com
729
+ HOST_CANONICAL=unknown-host.example.com
730
+ ROOT_URL_INTERNAL=https://unknown-host.example.com
731
+ APP_STORE_CONNECT_API_KEY_CONTENT=$CL_prod_app_APP_STORE_CONNECT_API_KEY_CONTENT
732
+ APP_STORE_CONNECT_ISSUER_ID=$CL_prod_app_APP_STORE_CONNECT_ISSUER_ID
733
+ APP_STORE_CONNECT_API_KEY_ID=$CL_prod_app_APP_STORE_CONNECT_API_KEY_ID
734
+ GRAPHQL_URL=https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql
735
+ _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","APP_STORE_CONNECT_API_KEY_CONTENT","APP_STORE_CONNECT_ISSUER_ID","APP_STORE_CONNECT_API_KEY_ID","GRAPHQL_URL"]
736
+ EOF
737
+ - echo -e "\\e[0Ksection_end:$(date +%s):write-dotenv-app\\r\\e[0K"
738
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > app/__build_info.json
739
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
740
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
741
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
742
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
743
+ - cd app
744
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
745
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
746
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
747
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
748
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
749
+ - yarn install --immutable
750
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
751
+ - bundle config set --local path 'vendor/ruby'
752
+ - gem install bundler
753
+ - bundle install
754
+ - bundle exec pod install --project-directory=ios
755
+ - bundle exec fastlane build
756
+ cache:
757
+ - key:
758
+ files:
759
+ - app/Gemfile.lock
760
+ paths:
761
+ - app/vendor
762
+ - key: app-yarn
763
+ policy: pull-push
764
+ paths:
765
+ - app/.yarn
766
+ - key: app-node-modules
767
+ policy: pull-push
768
+ paths:
769
+ - app/node_modules
770
+ - key: app-next-cache
771
+ policy: pull-push
772
+ paths:
773
+ - app/.next/cache
774
+ artifacts:
775
+ paths:
776
+ - app/__build_info.json
777
+ - app/.next
778
+ - app/dist
779
+ exclude:
780
+ - app/.env
781
+ expire_in: 1 day
782
+ when: always
783
+ reports: {}
784
+ rules:
785
+ - if: $CI_COMMIT_TAG
786
+ needs: []
787
+ retry: *a1
788
+ interruptible: true
789
+ 'app ๐Ÿงพ sbom | prod ':
790
+ stage: build
791
+ image: aquasec/trivy:0.38.3
792
+ variables: {}
793
+ script:
794
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
795
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
796
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" app
797
+ artifacts:
798
+ paths:
799
+ - __sbom.json
800
+ rules:
801
+ - if: $CI_COMMIT_TAG
802
+ needs: []
803
+ retry: *a1
804
+ interruptible: true
805
+ allow_failure: true
806
+ 'app ๐Ÿš€ Deploy | prod ':
807
+ stage: deploy prod
808
+ tags:
809
+ - mac-runner
810
+ image: path/to/docker/jobs-default:the-version
811
+ variables:
812
+ KUBERNETES_CPU_REQUEST: '0.22'
813
+ KUBERNETES_MEMORY_REQUEST: 200Mi
814
+ KUBERNETES_MEMORY_LIMIT: 400Mi
815
+ script:
816
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
817
+ - export ENV_SHORT="prod"
818
+ - export APP_DIR="app"
819
+ - export ENV_TYPE="prod"
820
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
821
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
822
+ - 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")"
823
+ - export HOST="unknown-host.example.com"
824
+ - export ROOT_URL="https://unknown-host.example.com"
825
+ - export HOST_INTERNAL="unknown-host.example.com"
826
+ - export HOST_CANONICAL="unknown-host.example.com"
827
+ - export ROOT_URL_INTERNAL="https://unknown-host.example.com"
828
+ - export APP_STORE_CONNECT_API_KEY_CONTENT="$CL_prod_app_APP_STORE_CONNECT_API_KEY_CONTENT"
829
+ - export APP_STORE_CONNECT_ISSUER_ID="$CL_prod_app_APP_STORE_CONNECT_ISSUER_ID"
830
+ - export APP_STORE_CONNECT_API_KEY_ID="$CL_prod_app_APP_STORE_CONNECT_API_KEY_ID"
831
+ - export GRAPHQL_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')/graphql"
832
+ - 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\\",\\"APP_STORE_CONNECT_API_KEY_CONTENT\\",\\"APP_STORE_CONNECT_ISSUER_ID\\",\\"APP_STORE_CONNECT_API_KEY_ID\\",\\"GRAPHQL_URL\\"]"
833
+ - export LC_A="L=en_US.UTF-8"
834
+ - export LANG="en_US.UTF-8"
835
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
836
+ - cd app
837
+ - bundle config set --local path 'vendor/ruby'
838
+ - gem install bundler
839
+ - bundle install
840
+ - bundle exec fastlane deploy_test
841
+ - echo 'Uploading SBOM to Dependency Track'
842
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/app" "https://unknown-host.example.com" "__sbom.json" vex.json || true
843
+ cache:
844
+ - key:
845
+ files:
846
+ - app/Gemfile.lock
847
+ paths:
848
+ - app/vendor
849
+ rules:
850
+ - when: manual
851
+ if: $CI_COMMIT_TAG
852
+ needs:
853
+ - job: 'app ๐Ÿ”จ app | prod '
854
+ artifacts: true
855
+ - job: 'app ๐Ÿงพ sbom | prod '
856
+ artifacts: true
857
+ retry: *a1
858
+ interruptible: true
859
+ allow_failure: true
860
+ api ๐Ÿ›ก audit:
861
+ stage: test
862
+ image: path/to/docker/jobs-default:the-version
863
+ variables:
864
+ KUBERNETES_CPU_REQUEST: '0.45'
865
+ KUBERNETES_MEMORY_REQUEST: 1Gi
866
+ KUBERNETES_MEMORY_LIMIT: 4Gi
867
+ script:
868
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
869
+ - export APP_PATH="api"
870
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
871
+ - cd api
872
+ - yarn npm audit --environment production
873
+ rules:
874
+ - when: never
875
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
876
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
877
+ - if: $CI_MERGE_REQUEST_ID
878
+ needs: []
879
+ retry: *a1
880
+ interruptible: true
881
+ allow_failure: true
882
+ api ๐Ÿ‘ฎ lint:
883
+ stage: test
884
+ image: path/to/docker/jobs-default:the-version
885
+ variables:
886
+ KUBERNETES_CPU_REQUEST: '0.45'
887
+ KUBERNETES_MEMORY_REQUEST: 1Gi
888
+ KUBERNETES_MEMORY_LIMIT: 4Gi
889
+ script:
890
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
891
+ - export APP_PATH="api"
892
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
893
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
894
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
895
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
896
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
897
+ - cd api
898
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
899
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
900
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
901
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
902
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
903
+ - yarn install --immutable
904
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
905
+ - yarn lint
906
+ cache:
907
+ - key: api-yarn
908
+ policy: pull-push
909
+ paths:
910
+ - api/.yarn
911
+ - key: api-node-modules
912
+ policy: pull-push
913
+ paths:
914
+ - api/node_modules
915
+ rules:
916
+ - when: never
917
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
918
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
919
+ - if: $CI_MERGE_REQUEST_ID
920
+ needs: []
921
+ retry: *a1
922
+ interruptible: true
923
+ api ๐Ÿงช test:
924
+ stage: test
925
+ image: path/to/docker/jobs-testing-chrome:the-version
926
+ variables:
927
+ KUBERNETES_CPU_REQUEST: '0.45'
928
+ KUBERNETES_MEMORY_REQUEST: 1Gi
929
+ KUBERNETES_MEMORY_LIMIT: 4Gi
930
+ script:
931
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
932
+ - export APP_PATH="api"
933
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
934
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
935
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
936
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
937
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
938
+ - cd api
939
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
940
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
941
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
942
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
943
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
944
+ - yarn install --immutable
945
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
946
+ - yarn test
947
+ cache:
948
+ - key: api-yarn
949
+ policy: pull-push
950
+ paths:
951
+ - api/.yarn
952
+ - key: api-node-modules
953
+ policy: pull-push
954
+ paths:
955
+ - api/node_modules
956
+ rules:
957
+ - when: never
958
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
959
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
960
+ - if: $CI_MERGE_REQUEST_ID
961
+ needs: []
962
+ retry: *a1
963
+ interruptible: true
964
+ 'api ๐Ÿ”จ app | dev ':
965
+ stage: build
966
+ image: path/to/docker/jobs-default:the-version
967
+ variables:
968
+ KUBERNETES_CPU_REQUEST: '0.45'
969
+ KUBERNETES_MEMORY_REQUEST: 1Gi
970
+ KUBERNETES_MEMORY_LIMIT: 4Gi
971
+ script:
972
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
973
+ - export ENV_SHORT="dev"
974
+ - export APP_DIR="api"
975
+ - export ENV_TYPE="dev"
976
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
977
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
978
+ - 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")"
979
+ - export HOST="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
980
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
981
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
982
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
983
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
984
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
985
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
986
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
987
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
988
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
989
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
990
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
991
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
992
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
993
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
994
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
995
+ - cd api
996
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
997
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
998
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
999
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1000
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1001
+ - yarn install --immutable
1002
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1003
+ - yarn build
1004
+ cache:
1005
+ - key: api-yarn
1006
+ policy: pull-push
1007
+ paths:
1008
+ - api/.yarn
1009
+ - key: api-node-modules
1010
+ policy: pull-push
1011
+ paths:
1012
+ - api/node_modules
1013
+ - key: api-next-cache
1014
+ policy: pull-push
1015
+ paths:
1016
+ - api/.next/cache
1017
+ artifacts:
1018
+ paths:
1019
+ - api/__build_info.json
1020
+ - api/.next
1021
+ - api/dist
1022
+ expire_in: 1 day
1023
+ when: always
1024
+ reports: {}
1025
+ rules:
1026
+ - when: never
1027
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1028
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1029
+ needs: []
1030
+ retry: *a1
1031
+ interruptible: true
1032
+ 'api ๐Ÿ”จ docker | dev ':
1033
+ stage: build
1034
+ image: path/to/docker/docker-build:the-version
1035
+ services:
1036
+ - name: docker:24.0.6-dind
1037
+ command:
1038
+ - --tls=false
1039
+ variables:
1040
+ DOCKER_HOST: tcp://0.0.0.0:2375
1041
+ DOCKER_TLS_CERTDIR: ''
1042
+ DOCKER_DRIVER: overlay2
1043
+ DOCKER_BUILDKIT: '1'
1044
+ KUBERNETES_CPU_REQUEST: '0.45'
1045
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1046
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1047
+ script:
1048
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1049
+ - export APP_DIR="api"
1050
+ - export DOCKER_BUILD_CONTEXT="."
1051
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1052
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api"
1053
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1054
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1055
+ - |-
1056
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1057
+ RUN yarn plugin import workspace-tools
1058
+ RUN yarn workspaces focus --production && yarn rebuild"
1059
+ - |-
1060
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1061
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1062
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1063
+ COPY --chown=node:node .yarn /app/.yarn"
1064
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1065
+ - ensureNodeDockerfile
1066
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1067
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
1068
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
1069
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1070
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1071
+ - 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
1072
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1073
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1074
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1075
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1076
+ - docker push $DOCKER_CACHE_IMAGE
1077
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1078
+ cache:
1079
+ - key: api-yarn
1080
+ policy: pull
1081
+ paths:
1082
+ - api/.yarn
1083
+ rules:
1084
+ - when: never
1085
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1086
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1087
+ needs:
1088
+ - 'api ๐Ÿ”จ app | dev '
1089
+ retry: *a1
1090
+ interruptible: true
1091
+ 'api ๐Ÿงพ sbom | dev ':
1092
+ stage: build
1093
+ image: aquasec/trivy:0.38.3
1094
+ variables: {}
1095
+ script:
1096
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1097
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1098
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1099
+ artifacts:
1100
+ paths:
1101
+ - __sbom.json
1102
+ rules:
1103
+ - when: never
1104
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1105
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1106
+ needs: []
1107
+ retry: *a1
1108
+ interruptible: true
1109
+ allow_failure: true
1110
+ 'api ๐Ÿš€ Deploy | dev ':
1111
+ stage: deploy dev
1112
+ image: path/to/docker/gcloud:the-version
1113
+ variables:
1114
+ KUBERNETES_CPU_REQUEST: '0.22'
1115
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1116
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1117
+ script:
1118
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1119
+ - export ENV_SHORT="dev"
1120
+ - export APP_DIR="api"
1121
+ - export ENV_TYPE="dev"
1122
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1123
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1124
+ - 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")"
1125
+ - export HOST="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1126
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1127
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1128
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1129
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1130
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1131
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1132
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
1133
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
1134
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1135
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1136
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api"
1137
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1138
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1139
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1140
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1141
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
1142
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
1143
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
1144
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1145
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
1146
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
1147
+ - |
1148
+ cat > ____envvars.yaml <<EOF
1149
+ ENV_SHORT: |-
1150
+ dev
1151
+ APP_DIR: |-
1152
+ api
1153
+ ENV_TYPE: |-
1154
+ dev
1155
+ BUILD_INFO_BUILD_ID: |-
1156
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1157
+ BUILD_INFO_BUILD_TIME: |-
1158
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1159
+ BUILD_INFO_CURRENT_VERSION: |-
1160
+ $(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/^/ /')
1161
+ HOST: |-
1162
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1163
+ ROOT_URL: |-
1164
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1165
+ HOST_INTERNAL: |-
1166
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1167
+ HOST_CANONICAL: |-
1168
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1169
+ ROOT_URL_INTERNAL: |-
1170
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1171
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1172
+ asdf
1173
+ DEPLOY_CLOUD_RUN_REGION: |-
1174
+ asia-east1
1175
+ GCLOUD_RUN_canonicalHostSuffix: |-
1176
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1177
+ _ALL_ENV_VAR_KEYS: |-
1178
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1179
+
1180
+ EOF
1181
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1182
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1183
+ - gcloud run deploy pan-test-app-dev-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-service-name=pan-test-app-dev-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1184
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1185
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1186
+ - gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-dev-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done
1187
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api@$version --quiet --delete-tags; done
1188
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1189
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1190
+ - echo 'Uploading SBOM to Dependency Track'
1191
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1192
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1193
+ environment:
1194
+ name: dev/api
1195
+ url: $CL_GITLAB_ENVIRONMENT_URL
1196
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | dev '
1197
+ auto_stop_in: 4 weeks
1198
+ artifacts:
1199
+ reports:
1200
+ dotenv: gitlab_environment.env
1201
+ rules:
1202
+ - when: never
1203
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1204
+ - when: on_success
1205
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1206
+ needs:
1207
+ - job: api ๐Ÿ‘ฎ lint
1208
+ artifacts: false
1209
+ - job: 'api ๐Ÿ”จ app | dev '
1210
+ artifacts: false
1211
+ - job: 'api ๐Ÿ”จ docker | dev '
1212
+ artifacts: false
1213
+ - job: api ๐Ÿงช test
1214
+ artifacts: false
1215
+ - job: 'api ๐Ÿงพ sbom | dev '
1216
+ artifacts: true
1217
+ - job: api ๐Ÿ›ก audit
1218
+ artifacts: false
1219
+ retry: *a1
1220
+ interruptible: true
1221
+ allow_failure: false
1222
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | dev ':
1223
+ stage: stop dev
1224
+ image: path/to/docker/gcloud:the-version
1225
+ variables:
1226
+ KUBERNETES_CPU_REQUEST: '0.22'
1227
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1228
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1229
+ GIT_STRATEGY: none
1230
+ script:
1231
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1232
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1233
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1234
+ - set +e
1235
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
1236
+ - gcloud run services delete pan-test-app-dev-api --project=asdf --region=asia-east1
1237
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
1238
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1239
+ - echo 'Disabling component in Dependency Track'
1240
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1241
+ - set -e
1242
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1243
+ environment:
1244
+ name: dev/api
1245
+ url: $CL_GITLAB_ENVIRONMENT_URL
1246
+ action: stop
1247
+ artifacts:
1248
+ reports:
1249
+ dotenv: gitlab_environment.env
1250
+ rules:
1251
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1252
+ when: on_success
1253
+ - when: never
1254
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1255
+ - when: manual
1256
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1257
+ needs: []
1258
+ retry: *a1
1259
+ interruptible: true
1260
+ allow_failure: true
1261
+ 'api ๐Ÿ”จ app | review ':
1262
+ stage: build
1263
+ image: path/to/docker/jobs-default:the-version
1264
+ variables:
1265
+ KUBERNETES_CPU_REQUEST: '0.45'
1266
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1267
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1268
+ script:
1269
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1270
+ - export ENV_SHORT="review"
1271
+ - export APP_DIR="api"
1272
+ - export ENV_TYPE="review"
1273
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1274
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1275
+ - 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")"
1276
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1277
+ - export ROOT_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1278
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1279
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1280
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1281
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1282
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1283
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
1284
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
1285
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1286
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1287
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1288
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1289
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1290
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1291
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1292
+ - cd api
1293
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1294
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1295
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1296
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1297
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1298
+ - yarn install --immutable
1299
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1300
+ - yarn build
1301
+ cache:
1302
+ - key: api-yarn
1303
+ policy: pull-push
1304
+ paths:
1305
+ - api/.yarn
1306
+ - key: api-node-modules
1307
+ policy: pull-push
1308
+ paths:
1309
+ - api/node_modules
1310
+ - key: api-next-cache
1311
+ policy: pull-push
1312
+ paths:
1313
+ - api/.next/cache
1314
+ artifacts:
1315
+ paths:
1316
+ - api/__build_info.json
1317
+ - api/.next
1318
+ - api/dist
1319
+ expire_in: 1 day
1320
+ when: always
1321
+ reports: {}
1322
+ rules:
1323
+ - if: $CI_MERGE_REQUEST_ID
1324
+ needs: []
1325
+ retry: *a1
1326
+ interruptible: true
1327
+ 'api ๐Ÿ”จ docker | review ':
1328
+ stage: build
1329
+ image: path/to/docker/docker-build:the-version
1330
+ services:
1331
+ - name: docker:24.0.6-dind
1332
+ command:
1333
+ - --tls=false
1334
+ variables:
1335
+ DOCKER_HOST: tcp://0.0.0.0:2375
1336
+ DOCKER_TLS_CERTDIR: ''
1337
+ DOCKER_DRIVER: overlay2
1338
+ DOCKER_BUILDKIT: '1'
1339
+ KUBERNETES_CPU_REQUEST: '0.45'
1340
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1341
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1342
+ script:
1343
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1344
+ - export APP_DIR="api"
1345
+ - export DOCKER_BUILD_CONTEXT="."
1346
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1347
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
1348
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1349
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1350
+ - |-
1351
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1352
+ RUN yarn plugin import workspace-tools
1353
+ RUN yarn workspaces focus --production && yarn rebuild"
1354
+ - |-
1355
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1356
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1357
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1358
+ COPY --chown=node:node .yarn /app/.yarn"
1359
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1360
+ - ensureNodeDockerfile
1361
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1362
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
1363
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
1364
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1365
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1366
+ - 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
1367
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1368
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1369
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1370
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1371
+ - docker push $DOCKER_CACHE_IMAGE
1372
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1373
+ cache:
1374
+ - key: api-yarn
1375
+ policy: pull
1376
+ paths:
1377
+ - api/.yarn
1378
+ rules:
1379
+ - if: $CI_MERGE_REQUEST_ID
1380
+ needs:
1381
+ - 'api ๐Ÿ”จ app | review '
1382
+ retry: *a1
1383
+ interruptible: true
1384
+ 'api ๐Ÿงพ sbom | review ':
1385
+ stage: build
1386
+ image: aquasec/trivy:0.38.3
1387
+ variables: {}
1388
+ script:
1389
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1390
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1391
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1392
+ artifacts:
1393
+ paths:
1394
+ - __sbom.json
1395
+ rules:
1396
+ - if: $CI_MERGE_REQUEST_ID
1397
+ needs: []
1398
+ retry: *a1
1399
+ interruptible: true
1400
+ allow_failure: true
1401
+ 'api ๐Ÿš€ Deploy | review ':
1402
+ stage: deploy review
1403
+ image: path/to/docker/gcloud:the-version
1404
+ variables:
1405
+ KUBERNETES_CPU_REQUEST: '0.22'
1406
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1407
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1408
+ script:
1409
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1410
+ - export ENV_SHORT="review"
1411
+ - export APP_DIR="api"
1412
+ - export ENV_TYPE="review"
1413
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1414
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1415
+ - 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")"
1416
+ - export HOST="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1417
+ - export ROOT_URL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1418
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1419
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1420
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1421
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1422
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1423
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
1424
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
1425
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1426
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1427
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })"
1428
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1429
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1430
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1431
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1432
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
1433
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
1434
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
1435
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1436
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
1437
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
1438
+ - |
1439
+ cat > ____envvars.yaml <<EOF
1440
+ ENV_SHORT: |-
1441
+ review
1442
+ APP_DIR: |-
1443
+ api
1444
+ ENV_TYPE: |-
1445
+ review
1446
+ BUILD_INFO_BUILD_ID: |-
1447
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1448
+ BUILD_INFO_BUILD_TIME: |-
1449
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1450
+ BUILD_INFO_CURRENT_VERSION: |-
1451
+ $(printf %s "$(tag=$(git ls-remote origin "refs/tags/v*[0-9]" 2>/dev/null | cut -f 2- | sort -V | tail -1 | sed 's/refs\\/tags\\/v//'); [ -z "$tag" ] && echo "0.0.0" || echo "$tag")" | sed 's/^/ /')
1452
+ HOST: |-
1453
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1454
+ ROOT_URL: |-
1455
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1456
+ HOST_INTERNAL: |-
1457
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1458
+ HOST_CANONICAL: |-
1459
+ $(printf %s "$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1460
+ ROOT_URL_INTERNAL: |-
1461
+ $(printf %s "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1462
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1463
+ asdf
1464
+ DEPLOY_CLOUD_RUN_REGION: |-
1465
+ asia-east1
1466
+ GCLOUD_RUN_canonicalHostSuffix: |-
1467
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1468
+ _ALL_ENV_VAR_KEYS: |-
1469
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1470
+
1471
+ EOF
1472
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1473
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1474
+ - gcloud run deploy $(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }):$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-service-name=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1475
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1476
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1477
+ - gcloud run revisions list --project=asdf --region=asia-east1 --service=$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done
1478
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }) --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })@$version --quiet --delete-tags; done
1479
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1480
+ - set +e
1481
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
1482
+ - set -e
1483
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1484
+ - echo 'Uploading SBOM to Dependency Track'
1485
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1486
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1487
+ environment:
1488
+ name: review/$CI_COMMIT_REF_NAME/api
1489
+ url: $CL_GITLAB_ENVIRONMENT_URL
1490
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | review '
1491
+ auto_stop_in: 1 week
1492
+ artifacts:
1493
+ reports:
1494
+ dotenv: gitlab_environment.env
1495
+ rules:
1496
+ - when: on_success
1497
+ if: $CI_MERGE_REQUEST_ID
1498
+ needs:
1499
+ - job: api ๐Ÿ‘ฎ lint
1500
+ artifacts: false
1501
+ - job: 'api ๐Ÿ”จ app | review '
1502
+ artifacts: false
1503
+ - job: 'api ๐Ÿ”จ docker | review '
1504
+ artifacts: false
1505
+ - job: api ๐Ÿงช test
1506
+ artifacts: false
1507
+ - job: 'api ๐Ÿงพ sbom | review '
1508
+ artifacts: true
1509
+ - job: api ๐Ÿ›ก audit
1510
+ artifacts: false
1511
+ retry: *a1
1512
+ interruptible: true
1513
+ allow_failure: false
1514
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | review ':
1515
+ stage: stop review
1516
+ image: path/to/docker/gcloud:the-version
1517
+ variables:
1518
+ KUBERNETES_CPU_REQUEST: '0.22'
1519
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1520
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1521
+ GIT_STRATEGY: none
1522
+ script:
1523
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1524
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1525
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1526
+ - set +e
1527
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
1528
+ - gcloud run services delete $(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api" | awk '{print tolower($0)}') --project=asdf --region=asia-east1
1529
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api/$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; }) --quiet --delete-tags
1530
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1531
+ - set +e
1532
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
1533
+ - set -e
1534
+ - echo 'Disabling component in Dependency Track'
1535
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1536
+ - set -e
1537
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-review-$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })-api-$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1538
+ environment:
1539
+ name: review/$CI_COMMIT_REF_NAME/api
1540
+ url: $CL_GITLAB_ENVIRONMENT_URL
1541
+ action: stop
1542
+ artifacts:
1543
+ reports:
1544
+ dotenv: gitlab_environment.env
1545
+ rules:
1546
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1547
+ when: on_success
1548
+ - when: manual
1549
+ if: $CI_MERGE_REQUEST_ID
1550
+ needs: []
1551
+ retry: *a1
1552
+ interruptible: true
1553
+ allow_failure: true
1554
+ 'api ๐Ÿ”จ app | stage ':
1555
+ stage: build
1556
+ image: path/to/docker/jobs-default:the-version
1557
+ variables:
1558
+ KUBERNETES_CPU_REQUEST: '0.45'
1559
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1560
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1561
+ script:
1562
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1563
+ - export ENV_SHORT="stage"
1564
+ - export APP_DIR="api"
1565
+ - export ENV_TYPE="stage"
1566
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1567
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1568
+ - 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")"
1569
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1570
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1571
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1572
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1573
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1574
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1575
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1576
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
1577
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
1578
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1579
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1580
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1581
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1582
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1583
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1584
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1585
+ - cd api
1586
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1587
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1588
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1589
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1590
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1591
+ - yarn install --immutable
1592
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1593
+ - yarn build
1594
+ cache:
1595
+ - key: api-yarn
1596
+ policy: pull-push
1597
+ paths:
1598
+ - api/.yarn
1599
+ - key: api-node-modules
1600
+ policy: pull-push
1601
+ paths:
1602
+ - api/node_modules
1603
+ - key: api-next-cache
1604
+ policy: pull-push
1605
+ paths:
1606
+ - api/.next/cache
1607
+ artifacts:
1608
+ paths:
1609
+ - api/__build_info.json
1610
+ - api/.next
1611
+ - api/dist
1612
+ expire_in: 1 day
1613
+ when: always
1614
+ reports: {}
1615
+ rules:
1616
+ - if: $CI_COMMIT_TAG
1617
+ needs: []
1618
+ retry: *a1
1619
+ interruptible: true
1620
+ 'api ๐Ÿ”จ docker | stage ':
1621
+ stage: build
1622
+ image: path/to/docker/docker-build:the-version
1623
+ services:
1624
+ - name: docker:24.0.6-dind
1625
+ command:
1626
+ - --tls=false
1627
+ variables:
1628
+ DOCKER_HOST: tcp://0.0.0.0:2375
1629
+ DOCKER_TLS_CERTDIR: ''
1630
+ DOCKER_DRIVER: overlay2
1631
+ DOCKER_BUILDKIT: '1'
1632
+ KUBERNETES_CPU_REQUEST: '0.45'
1633
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1634
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1635
+ script:
1636
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1637
+ - export APP_DIR="api"
1638
+ - export DOCKER_BUILD_CONTEXT="."
1639
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1640
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api"
1641
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1642
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1643
+ - |-
1644
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1645
+ RUN yarn plugin import workspace-tools
1646
+ RUN yarn workspaces focus --production && yarn rebuild"
1647
+ - |-
1648
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1649
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1650
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1651
+ COPY --chown=node:node .yarn /app/.yarn"
1652
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1653
+ - ensureNodeDockerfile
1654
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1655
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1656
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
1657
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1658
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1659
+ - 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
1660
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1661
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1662
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1663
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1664
+ - docker push $DOCKER_CACHE_IMAGE
1665
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1666
+ cache:
1667
+ - key: api-yarn
1668
+ policy: pull
1669
+ paths:
1670
+ - api/.yarn
1671
+ rules:
1672
+ - if: $CI_COMMIT_TAG
1673
+ needs:
1674
+ - 'api ๐Ÿ”จ app | stage '
1675
+ retry: *a1
1676
+ interruptible: true
1677
+ 'api ๐Ÿงพ sbom | stage ':
1678
+ stage: build
1679
+ image: aquasec/trivy:0.38.3
1680
+ variables: {}
1681
+ script:
1682
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1683
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1684
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1685
+ artifacts:
1686
+ paths:
1687
+ - __sbom.json
1688
+ rules:
1689
+ - if: $CI_COMMIT_TAG
1690
+ needs: []
1691
+ retry: *a1
1692
+ interruptible: true
1693
+ allow_failure: true
1694
+ 'api ๐Ÿš€ Deploy | stage ':
1695
+ stage: deploy stage
1696
+ image: path/to/docker/gcloud:the-version
1697
+ variables:
1698
+ KUBERNETES_CPU_REQUEST: '0.22'
1699
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1700
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1701
+ script:
1702
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1703
+ - export ENV_SHORT="stage"
1704
+ - export APP_DIR="api"
1705
+ - export ENV_TYPE="stage"
1706
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1707
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1708
+ - 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")"
1709
+ - export HOST="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1710
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1711
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1712
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1713
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1714
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1715
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1716
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
1717
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
1718
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1719
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1720
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api"
1721
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1722
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1723
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1724
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1725
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
1726
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1727
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
1728
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1729
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
1730
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
1731
+ - |
1732
+ cat > ____envvars.yaml <<EOF
1733
+ ENV_SHORT: |-
1734
+ stage
1735
+ APP_DIR: |-
1736
+ api
1737
+ ENV_TYPE: |-
1738
+ stage
1739
+ BUILD_INFO_BUILD_ID: |-
1740
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
1741
+ BUILD_INFO_BUILD_TIME: |-
1742
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
1743
+ BUILD_INFO_CURRENT_VERSION: |-
1744
+ $(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/^/ /')
1745
+ HOST: |-
1746
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1747
+ ROOT_URL: |-
1748
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1749
+ HOST_INTERNAL: |-
1750
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1751
+ HOST_CANONICAL: |-
1752
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1753
+ ROOT_URL_INTERNAL: |-
1754
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
1755
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1756
+ asdf
1757
+ DEPLOY_CLOUD_RUN_REGION: |-
1758
+ asia-east1
1759
+ GCLOUD_RUN_canonicalHostSuffix: |-
1760
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
1761
+ _ALL_ENV_VAR_KEYS: |-
1762
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1763
+
1764
+ EOF
1765
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
1766
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
1767
+ - gcloud run deploy pan-test-app-stage-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-service-name=pan-test-app-stage-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1768
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
1769
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
1770
+ - gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-stage-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done
1771
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api@$version --quiet --delete-tags; done
1772
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1773
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
1774
+ - echo 'Uploading SBOM to Dependency Track'
1775
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
1776
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1777
+ environment:
1778
+ name: stage/api
1779
+ url: $CL_GITLAB_ENVIRONMENT_URL
1780
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | stage '
1781
+ artifacts:
1782
+ reports:
1783
+ dotenv: gitlab_environment.env
1784
+ rules:
1785
+ - when: on_success
1786
+ if: $CI_COMMIT_TAG
1787
+ needs:
1788
+ - job: 'api ๐Ÿ”จ app | stage '
1789
+ artifacts: false
1790
+ - job: 'api ๐Ÿ”จ docker | stage '
1791
+ artifacts: false
1792
+ - job: 'api ๐Ÿงพ sbom | stage '
1793
+ artifacts: true
1794
+ retry: *a1
1795
+ interruptible: true
1796
+ allow_failure: false
1797
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | stage ':
1798
+ stage: stop stage
1799
+ image: path/to/docker/gcloud:the-version
1800
+ variables:
1801
+ KUBERNETES_CPU_REQUEST: '0.22'
1802
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1803
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1804
+ GIT_STRATEGY: none
1805
+ script:
1806
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1807
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1808
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1809
+ - set +e
1810
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1811
+ - gcloud run services delete pan-test-app-stage-api --project=asdf --region=asia-east1
1812
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1813
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
1814
+ - echo 'Disabling component in Dependency Track'
1815
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
1816
+ - set -e
1817
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
1818
+ environment:
1819
+ name: stage/api
1820
+ url: $CL_GITLAB_ENVIRONMENT_URL
1821
+ action: stop
1822
+ artifacts:
1823
+ reports:
1824
+ dotenv: gitlab_environment.env
1825
+ rules:
1826
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1827
+ when: on_success
1828
+ - when: manual
1829
+ if: $CI_COMMIT_TAG
1830
+ needs: []
1831
+ retry: *a1
1832
+ interruptible: true
1833
+ allow_failure: true
1834
+ 'api ๐Ÿ”จ app | prod ':
1835
+ stage: build
1836
+ image: path/to/docker/jobs-default:the-version
1837
+ variables:
1838
+ KUBERNETES_CPU_REQUEST: '0.45'
1839
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1840
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1841
+ script:
1842
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1843
+ - export ENV_SHORT="prod"
1844
+ - export APP_DIR="api"
1845
+ - export ENV_TYPE="prod"
1846
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1847
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1848
+ - 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")"
1849
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1850
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1851
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1852
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1853
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1854
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1855
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1856
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1857
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1858
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1859
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1860
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1861
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1862
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1863
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1864
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1865
+ - cd api
1866
+ - echo -e "\\e[0Ksection_start:$(date +%s):nodeinstall[collapsed=true]\\r\\e[0KEnsure node version"
1867
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1868
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1869
+ - echo -e "\\e[0Ksection_end:$(date +%s):nodeinstall\\r\\e[0K"
1870
+ - echo -e "\\e[0Ksection_start:$(date +%s):yarninstall[collapsed=true]\\r\\e[0KYarn install"
1871
+ - yarn install --immutable
1872
+ - echo -e "\\e[0Ksection_end:$(date +%s):yarninstall\\r\\e[0K"
1873
+ - yarn build
1874
+ cache:
1875
+ - key: api-yarn
1876
+ policy: pull-push
1877
+ paths:
1878
+ - api/.yarn
1879
+ - key: api-node-modules
1880
+ policy: pull-push
1881
+ paths:
1882
+ - api/node_modules
1883
+ - key: api-next-cache
1884
+ policy: pull-push
1885
+ paths:
1886
+ - api/.next/cache
1887
+ artifacts:
1888
+ paths:
1889
+ - api/__build_info.json
1890
+ - api/.next
1891
+ - api/dist
1892
+ expire_in: 1 day
1893
+ when: always
1894
+ reports: {}
1895
+ rules:
1896
+ - if: $CI_COMMIT_TAG
1897
+ needs: []
1898
+ retry: *a1
1899
+ interruptible: true
1900
+ 'api ๐Ÿ”จ docker | prod ':
1901
+ stage: build
1902
+ image: path/to/docker/docker-build:the-version
1903
+ services:
1904
+ - name: docker:24.0.6-dind
1905
+ command:
1906
+ - --tls=false
1907
+ variables:
1908
+ DOCKER_HOST: tcp://0.0.0.0:2375
1909
+ DOCKER_TLS_CERTDIR: ''
1910
+ DOCKER_DRIVER: overlay2
1911
+ DOCKER_BUILDKIT: '1'
1912
+ KUBERNETES_CPU_REQUEST: '0.45'
1913
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1914
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1915
+ script:
1916
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1917
+ - export APP_DIR="api"
1918
+ - export DOCKER_BUILD_CONTEXT="."
1919
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
1920
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api"
1921
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
1922
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1923
+ - |-
1924
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1925
+ RUN yarn plugin import workspace-tools
1926
+ RUN yarn workspaces focus --production && yarn rebuild"
1927
+ - |-
1928
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1929
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1930
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1931
+ COPY --chown=node:node .yarn /app/.yarn"
1932
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1933
+ - ensureNodeDockerfile
1934
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-login[collapsed=true]\\r\\e[0KDocker Login"
1935
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1936
+ - gcloud auth configure-docker asia-east1-docker.pkg.dev
1937
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-login\\r\\e[0K"
1938
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-build[collapsed=true]\\r\\e[0KDocker build"
1939
+ - 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
1940
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-build\\r\\e[0K"
1941
+ - echo -e "\\e[0Ksection_start:$(date +%s):docker-push[collapsed=true]\\r\\e[0KDocker push and tag"
1942
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1943
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1944
+ - docker push $DOCKER_CACHE_IMAGE
1945
+ - echo -e "\\e[0Ksection_end:$(date +%s):docker-push\\r\\e[0K"
1946
+ cache:
1947
+ - key: api-yarn
1948
+ policy: pull
1949
+ paths:
1950
+ - api/.yarn
1951
+ rules:
1952
+ - if: $CI_COMMIT_TAG
1953
+ needs:
1954
+ - 'api ๐Ÿ”จ app | prod '
1955
+ retry: *a1
1956
+ interruptible: true
1957
+ 'api ๐Ÿงพ sbom | prod ':
1958
+ stage: build
1959
+ image: aquasec/trivy:0.38.3
1960
+ variables: {}
1961
+ script:
1962
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1963
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
1964
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1965
+ artifacts:
1966
+ paths:
1967
+ - __sbom.json
1968
+ rules:
1969
+ - if: $CI_COMMIT_TAG
1970
+ needs: []
1971
+ retry: *a1
1972
+ interruptible: true
1973
+ allow_failure: true
1974
+ 'api ๐Ÿš€ Deploy | prod ':
1975
+ stage: deploy prod
1976
+ image: path/to/docker/gcloud:the-version
1977
+ variables:
1978
+ KUBERNETES_CPU_REQUEST: '0.22'
1979
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1980
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1981
+ script:
1982
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
1983
+ - export ENV_SHORT="prod"
1984
+ - export APP_DIR="api"
1985
+ - export ENV_TYPE="prod"
1986
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1987
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1988
+ - 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")"
1989
+ - export HOST="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1990
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1991
+ - export HOST_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1992
+ - export HOST_CANONICAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1993
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1994
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="asdf"
1995
+ - export DEPLOY_CLOUD_RUN_REGION="asia-east1"
1996
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1997
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1998
+ - export _ALL_ENV_VAR_KEYS="[\\"ENV_SHORT\\",\\"APP_DIR\\",\\"ENV_TYPE\\",\\"BUILD_INFO_BUILD_ID\\",\\"BUILD_INFO_BUILD_TIME\\",\\"BUILD_INFO_CURRENT_VERSION\\",\\"HOST\\",\\"ROOT_URL\\",\\"HOST_INTERNAL\\",\\"HOST_CANONICAL\\",\\"ROOT_URL_INTERNAL\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1999
+ - export DOCKER_REGISTRY="asia-east1-docker.pkg.dev"
2000
+ - export DOCKER_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api"
2001
+ - export DOCKER_CACHE_IMAGE="asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api"
2002
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
2003
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2004
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2005
+ - echo -e "\\e[0Ksection_start:$(date +%s):prepare[collapsed=true]\\r\\e[0KPrepare..."
2006
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
2007
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe asdf --format="value(projectNumber)")
2008
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
2009
+ - echo -e "\\e[0Ksection_end:$(date +%s):prepare\\r\\e[0K"
2010
+ - echo -e "\\e[0Ksection_start:$(date +%s):writeenvvars[collapsed=true]\\r\\e[0KWrite env vars to file"
2011
+ - |
2012
+ cat > ____envvars.yaml <<EOF
2013
+ ENV_SHORT: |-
2014
+ prod
2015
+ APP_DIR: |-
2016
+ api
2017
+ ENV_TYPE: |-
2018
+ prod
2019
+ BUILD_INFO_BUILD_ID: |-
2020
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed 's/^/ /')
2021
+ BUILD_INFO_BUILD_TIME: |-
2022
+ $(printf %s "$CI_JOB_STARTED_AT" | sed 's/^/ /')
2023
+ BUILD_INFO_CURRENT_VERSION: |-
2024
+ $(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/^/ /')
2025
+ HOST: |-
2026
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2027
+ ROOT_URL: |-
2028
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2029
+ HOST_INTERNAL: |-
2030
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2031
+ HOST_CANONICAL: |-
2032
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2033
+ ROOT_URL_INTERNAL: |-
2034
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed 's/^/ /')
2035
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
2036
+ asdf
2037
+ DEPLOY_CLOUD_RUN_REGION: |-
2038
+ asia-east1
2039
+ GCLOUD_RUN_canonicalHostSuffix: |-
2040
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed 's/^/ /')
2041
+ _ALL_ENV_VAR_KEYS: |-
2042
+ ["ENV_SHORT","APP_DIR","ENV_TYPE","BUILD_INFO_BUILD_ID","BUILD_INFO_BUILD_TIME","BUILD_INFO_CURRENT_VERSION","HOST","ROOT_URL","HOST_INTERNAL","HOST_CANONICAL","ROOT_URL_INTERNAL","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
2043
+
2044
+ EOF
2045
+ - echo -e "\\e[0Ksection_end:$(date +%s):writeenvvars\\r\\e[0K"
2046
+ - echo -e "\\e[0Ksection_start:$(date +%s):deploy[collapsed=true]\\r\\e[0KDeploy to cloud run"
2047
+ - gcloud run deploy pan-test-app-prod-api --command="yarn,start" --image=asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api:$DOCKER_IMAGE_TAG --project=asdf --region=asia-east1 --labels=customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-service-name=pan-test-app-prod-api --env-vars-file=____envvars.yaml --min-instances=0 --max-instances=100 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
2048
+ - echo -e "\\e[0Ksection_end:$(date +%s):deploy\\r\\e[0K"
2049
+ - echo -e "\\e[0Ksection_start:$(date +%s):cleanup[collapsed=true]\\r\\e[0KCleanup"
2050
+ - gcloud run revisions list --project=asdf --region=asia-east1 --service=pan-test-app-prod-api --limit=unlimited --sort-by=metadata.creationTimestamp --format="value(name)" --filter='(status.conditions.status=False OR status.conditions.status=Unknown)' | tail -n +6 | while read -r revisionname; do gcloud run revisions delete --project=asdf --region=asia-east1 --quiet $revisionname ; done
2051
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +7 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api@$version --quiet --delete-tags; done
2052
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
2053
+ - echo -e "\\e[0Ksection_end:$(date +%s):cleanup\\r\\e[0K"
2054
+ - echo 'Uploading SBOM to Dependency Track'
2055
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" "__sbom.json" vex.json || true
2056
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2057
+ environment:
2058
+ name: prod/api
2059
+ url: $CL_GITLAB_ENVIRONMENT_URL
2060
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | prod '
2061
+ artifacts:
2062
+ reports:
2063
+ dotenv: gitlab_environment.env
2064
+ rules:
2065
+ - when: manual
2066
+ if: $CI_COMMIT_TAG
2067
+ needs:
2068
+ - job: 'api ๐Ÿ”จ app | prod '
2069
+ artifacts: false
2070
+ - job: 'api ๐Ÿ”จ docker | prod '
2071
+ artifacts: false
2072
+ - job: 'api ๐Ÿงพ sbom | prod '
2073
+ artifacts: true
2074
+ retry: *a1
2075
+ interruptible: true
2076
+ allow_failure: true
2077
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | prod ':
2078
+ stage: stop prod
2079
+ image: path/to/docker/gcloud:the-version
2080
+ variables:
2081
+ KUBERNETES_CPU_REQUEST: '0.22'
2082
+ KUBERNETES_MEMORY_REQUEST: 200Mi
2083
+ KUBERNETES_MEMORY_LIMIT: 400Mi
2084
+ GIT_STRATEGY: none
2085
+ script:
2086
+ - echo -e "\\e[0Ksection_start:$(date +%s):injectvars[collapsed=true]\\r\\e[0KInjecting variables"
2087
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
2088
+ - echo -e "\\e[0Ksection_end:$(date +%s):injectvars\\r\\e[0K"
2089
+ - set +e
2090
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
2091
+ - gcloud run services delete pan-test-app-prod-api --project=asdf --region=asia-east1
2092
+ - gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
2093
+ - gcloud artifacts docker images list asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api --sort-by=~CREATE_TIME --format="value(version)" | tail -n +2 | while read -r version; do gcloud artifacts docker images delete asia-east1-docker.pkg.dev/asdf/catladder-deploy/pan-test-app/caches/api@$version --quiet --delete-tags; done
2094
+ - echo 'Disabling component in Dependency Track'
2095
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" || true
2096
+ - set -e
2097
+ - echo "CL_GITLAB_ENVIRONMENT_URL=https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" >> gitlab_environment.env
2098
+ environment:
2099
+ name: prod/api
2100
+ url: $CL_GITLAB_ENVIRONMENT_URL
2101
+ action: stop
2102
+ artifacts:
2103
+ reports:
2104
+ dotenv: gitlab_environment.env
2105
+ rules:
2106
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
2107
+ when: on_success
2108
+ - when: manual
2109
+ if: $CI_COMMIT_TAG
2110
+ needs: []
2111
+ retry: *a1
2112
+ interruptible: true
2113
+ allow_failure: true
2114
+ create release:
2115
+ stage: release
2116
+ image: path/to/docker/semantic-release:the-version
2117
+ script:
2118
+ - semanticRelease
2119
+ after_script:
2120
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
2121
+ rules:
2122
+ - &a2
2123
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
2124
+ when: never
2125
+ - &a3
2126
+ if: $CI_PIPELINE_SOURCE == "schedule"
2127
+ when: never
2128
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $AUTO_RELEASE == "true"
2129
+ when: on_success
2130
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
2131
+ when: manual
2132
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
2133
+ when: manual
2134
+ โš ๏ธ force create release:
2135
+ stage: release
2136
+ image: path/to/docker/semantic-release:the-version
2137
+ script:
2138
+ - semanticRelease
2139
+ after_script:
2140
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
2141
+ rules:
2142
+ - *a2
2143
+ - *a3
2144
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
2145
+ when: manual
2146
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
2147
+ when: manual
2148
+ needs: []
2149
+ "
2150
+ `;
2151
+
3
2152
  exports[`matches snapshot for native-app 1`] = `
4
2153
  {
5
2154
  "mainBranch": {