@catladder/pipeline 0.0.0-refactore-catenv-command-validates-argument-78d05852 โ†’ 0.0.0-reference-database-url-1befbbee

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