@catladder/pipeline 1.144.0 → 1.145.0

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