@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,1709 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`matches snapshot for cloud-run-with-sql-legacy-jobs 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 CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-migration:run"
206
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-send-reminders:run"
207
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
208
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
209
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
210
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
211
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
212
+ - collapseable_section_end "injectvars"
213
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
214
+ - |-
215
+ cat <<EOF > api/.env
216
+ ENV_SHORT=dev
217
+ APP_DIR=api
218
+ ENV_TYPE=dev
219
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
220
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
221
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
222
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
223
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
224
+ DB_NAME=pan-test-app-dev-api
225
+ DB_USER=my-user
226
+ DB_PASSWORD=$(printf %s "$CL_dev_api_DB_PASSWORD" | escapeForDotEnv)
227
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
228
+ 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
229
+ CLOUD_RUN_JOB_TRIGGER_URL_migration=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-migration:run
230
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-send-reminders:run
231
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
232
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
233
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
234
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
235
+ _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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
236
+ EOF
237
+ - collapseable_section_end "write-dotenv-api"
238
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
239
+ - collapseable_section_start "nodeinstall" "Ensure node version"
240
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
241
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
242
+ - collapseable_section_end "nodeinstall"
243
+ - cd api
244
+ - collapseable_section_start "nodeinstall" "Ensure node version"
245
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
246
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
247
+ - collapseable_section_end "nodeinstall"
248
+ - collapseable_section_start "yarninstall" "Yarn install"
249
+ - yarn install --immutable
250
+ - collapseable_section_end "yarninstall"
251
+ - yarn build
252
+ cache:
253
+ - key: api-yarn
254
+ policy: pull-push
255
+ paths:
256
+ - api/.yarn
257
+ - key: api-node-modules
258
+ policy: pull-push
259
+ paths:
260
+ - api/node_modules
261
+ artifacts:
262
+ paths:
263
+ - api/__build_info.json
264
+ - api/.next
265
+ - api/dist
266
+ exclude:
267
+ - api/.env
268
+ expire_in: 1 day
269
+ when: always
270
+ reports: {}
271
+ rules:
272
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
273
+ needs: []
274
+ retry: *a1
275
+ interruptible: true
276
+ 'api ๐Ÿ”จ docker | dev ':
277
+ stage: build
278
+ image: path/to/docker/docker-build:the-version
279
+ services:
280
+ - name: docker:24.0.6-dind
281
+ command:
282
+ - --tls=false
283
+ - --registry-mirror=https://mirror.gcr.io
284
+ variables:
285
+ DOCKER_HOST: tcp://docker:2375
286
+ DOCKER_TLS_CERTDIR: ''
287
+ DOCKER_DRIVER: overlay2
288
+ DOCKER_BUILDKIT: '1'
289
+ KUBERNETES_CPU_REQUEST: '0.45'
290
+ KUBERNETES_MEMORY_REQUEST: 1Gi
291
+ KUBERNETES_MEMORY_LIMIT: 2Gi
292
+ script:
293
+ - collapseable_section_start "injectvars" "Injecting variables"
294
+ - export APP_DIR="api"
295
+ - export DOCKER_BUILD_CONTEXT="."
296
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
297
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
298
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
299
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
300
+ - |-
301
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
302
+ RUN yarn plugin import workspace-tools
303
+ RUN yarn workspaces focus --production && yarn rebuild"
304
+ - |-
305
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
306
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
307
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
308
+ COPY --chown=node:node .yarn /app/.yarn"
309
+ - collapseable_section_end "injectvars"
310
+ - ensureNodeDockerfile
311
+ - collapseable_section_start "docker-login" "Docker Login"
312
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
313
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
314
+ - collapseable_section_end "docker-login"
315
+ - collapseable_section_start "docker-build" "Docker build"
316
+ - 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
317
+ - collapseable_section_end "docker-build"
318
+ - collapseable_section_start "docker-push" "Docker push and tag"
319
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
320
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
321
+ - docker push $DOCKER_CACHE_IMAGE
322
+ - collapseable_section_end "docker-push"
323
+ cache:
324
+ - key: api-yarn
325
+ policy: pull
326
+ paths:
327
+ - api/.yarn
328
+ rules:
329
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
330
+ needs:
331
+ - 'api ๐Ÿ”จ app | dev '
332
+ retry: *a1
333
+ interruptible: true
334
+ 'api ๐Ÿงพ sbom | dev ':
335
+ stage: build
336
+ image:
337
+ name: aquasec/trivy:0.58.2
338
+ entrypoint:
339
+ - ''
340
+ variables: {}
341
+ script:
342
+ - collapseable_section_start "injectvars" "Injecting variables"
343
+ - collapseable_section_end "injectvars"
344
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
345
+ artifacts:
346
+ paths:
347
+ - __sbom.json
348
+ rules:
349
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
350
+ needs: []
351
+ retry: *a1
352
+ interruptible: true
353
+ allow_failure: true
354
+ 'api ๐Ÿš€ Deploy | dev ':
355
+ stage: deploy dev
356
+ image: path/to/docker/gcloud:the-version
357
+ variables:
358
+ KUBERNETES_CPU_REQUEST: '0.22'
359
+ KUBERNETES_MEMORY_REQUEST: 200Mi
360
+ KUBERNETES_MEMORY_LIMIT: 400Mi
361
+ script:
362
+ - collapseable_section_start "injectvars" "Injecting variables"
363
+ - export ENV_SHORT="dev"
364
+ - export APP_DIR="api"
365
+ - export ENV_TYPE="dev"
366
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
367
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
368
+ - 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")"
369
+ - export HOSTNAME="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
370
+ - export ROOT_URL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
371
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
372
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
373
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
374
+ - export DB_NAME="pan-test-app-dev-api"
375
+ - export DB_USER="my-user"
376
+ - export DB_PASSWORD="$CL_dev_api_DB_PASSWORD"
377
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
378
+ - 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"
379
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-migration:run"
380
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-send-reminders:run"
381
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
382
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
383
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_dev_api_GCLOUD_DEPLOY_credentialsKey"
384
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix"
385
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
386
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
387
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api"
388
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
389
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
390
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
391
+ - collapseable_section_end "injectvars"
392
+ - collapseable_section_start "prepare" "Prepare..."
393
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
394
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
395
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
396
+ - collapseable_section_end "prepare"
397
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
398
+ - |
399
+ cat > ____envvars.yaml <<EOF
400
+ ENV_SHORT: |-
401
+ dev
402
+ APP_DIR: |-
403
+ api
404
+ ENV_TYPE: |-
405
+ dev
406
+ BUILD_INFO_BUILD_ID: |-
407
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
408
+ BUILD_INFO_BUILD_TIME: |-
409
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
410
+ BUILD_INFO_CURRENT_VERSION: |-
411
+ $(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/^/ /')
412
+ HOSTNAME: |-
413
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
414
+ ROOT_URL: |-
415
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
416
+ HOSTNAME_INTERNAL: |-
417
+ $(printf %s "$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
418
+ ROOT_URL_INTERNAL: |-
419
+ $(printf %s "https://$(printf %s "pan-test-app-dev-api-$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
420
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
421
+ projectId:region:instancename
422
+ DB_NAME: |-
423
+ pan-test-app-dev-api
424
+ DB_USER: |-
425
+ my-user
426
+ DB_PASSWORD: |-
427
+ $(printf %s "$CL_dev_api_DB_PASSWORD" | sed '1!s/^/ /')
428
+ DATABASE_URL: |-
429
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
430
+ DATABASE_JDBC_URL: |-
431
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
432
+ CLOUD_RUN_JOB_TRIGGER_URL_migration: |-
433
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-migration:run
434
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders: |-
435
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-send-reminders:run
436
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
437
+ google-project-id
438
+ DEPLOY_CLOUD_RUN_REGION: |-
439
+ europe-west6
440
+ GCLOUD_RUN_canonicalHostSuffix: |-
441
+ $(printf %s "$CL_dev_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
442
+ _ALL_ENV_VAR_KEYS: |-
443
+ ["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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
444
+
445
+ EOF
446
+ - collapseable_section_end "writeenvvars"
447
+ - collapseable_section_start "deploy" "Deploy to cloud run"
448
+ - set +e
449
+ - echo "ensuring Database..."
450
+ - gcloud sql databases create pan-test-app-dev-api --instance=instancename --project projectId
451
+ - set -e
452
+ - |-
453
+ exist_scheduler_names="$(
454
+ gcloud scheduler jobs list --filter='httpTarget.uri ~ dev.*api' --format='value(name)' --limit=999 --location='europe-west6' --project='google-project-id'
455
+ )"
456
+ current_job_uri="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-dev-api-send-reminders:run"
457
+ current_scheduler_name="pan-test-app-dev-api-send-reminders-scheduler"
458
+ if grep "$current_scheduler_name" <<<"$exist_scheduler_names" >/dev/null; then
459
+ gcloud scheduler jobs update http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
460
+ else
461
+ gcloud scheduler jobs create http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
462
+ fi
463
+ - |-
464
+ exist_job_names="$(
465
+ gcloud run jobs list --filter='metadata.name ~ dev.*api' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
466
+ )"
467
+ current_job_name="pan-test-app-dev-api-migration"
468
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
469
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
470
+ else
471
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
472
+ fi
473
+ - |-
474
+ current_job_name="pan-test-app-dev-api-send-reminders"
475
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
476
+ gcloud run jobs update "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
477
+ else
478
+ gcloud run jobs create "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=dev,env-name=dev,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
479
+ fi
480
+ - gcloud run jobs execute pan-test-app-dev-api-migration --project=google-project-id --region=europe-west6 --wait
481
+ - 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=5 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
482
+ - collapseable_section_end "deploy"
483
+ - collapseable_section_start "cleanup" "Cleanup"
484
+ - 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
485
+ - 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
486
+ - 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
487
+ - collapseable_section_end "cleanup"
488
+ - echo 'Uploading SBOM to Dependency Track'
489
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
490
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
491
+ environment:
492
+ name: dev/api
493
+ url: $CL_GITLAB_ENVIRONMENT_URL
494
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | dev '
495
+ auto_stop_in: 4 weeks
496
+ artifacts:
497
+ reports:
498
+ dotenv: gitlab_environment.env
499
+ rules:
500
+ - when: on_success
501
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
502
+ needs:
503
+ - job: api ๐Ÿ‘ฎ lint
504
+ artifacts: false
505
+ - job: 'api ๐Ÿ”จ app | dev '
506
+ artifacts: false
507
+ - job: 'api ๐Ÿ”จ docker | dev '
508
+ artifacts: false
509
+ - job: api ๐Ÿงช test
510
+ artifacts: false
511
+ - job: 'api ๐Ÿงพ sbom | dev '
512
+ artifacts: true
513
+ - job: api ๐Ÿ›ก audit
514
+ artifacts: false
515
+ retry: *a1
516
+ interruptible: true
517
+ allow_failure: false
518
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | dev ':
519
+ stage: stop dev
520
+ image: path/to/docker/gcloud:the-version
521
+ variables:
522
+ KUBERNETES_CPU_REQUEST: '0.22'
523
+ KUBERNETES_MEMORY_REQUEST: 200Mi
524
+ KUBERNETES_MEMORY_LIMIT: 400Mi
525
+ GIT_STRATEGY: none
526
+ script:
527
+ - collapseable_section_start "injectvars" "Injecting variables"
528
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
529
+ - collapseable_section_end "injectvars"
530
+ - set +e
531
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_dev_api_GCLOUD_DEPLOY_credentialsKey")
532
+ - gcloud run services delete pan-test-app-dev-api --project=google-project-id --region=europe-west6
533
+ - gcloud scheduler jobs delete pan-test-app-dev-api-send-reminders-scheduler --project=google-project-id --location=europe-west6
534
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-dev-api-migration --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
535
+ - gcloud run jobs delete pan-test-app-dev-api-migration --project=google-project-id --region=europe-west6
536
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-dev-api-send-reminders --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
537
+ - gcloud run jobs delete pan-test-app-dev-api-send-reminders --project=google-project-id --region=europe-west6
538
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/dev/api --quiet --delete-tags
539
+ - 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
540
+ - echo 'Disabling component in Dependency Track'
541
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
542
+ - set -e
543
+ environment:
544
+ name: dev/api
545
+ action: stop
546
+ rules:
547
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
548
+ when: on_success
549
+ - when: manual
550
+ if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE !~ /^chore\\(release\\).*/
551
+ needs: []
552
+ retry: *a1
553
+ interruptible: true
554
+ allow_failure: true
555
+ 'api ๐Ÿ”จ app | review ':
556
+ stage: build
557
+ image: path/to/docker/jobs-default:the-version
558
+ variables:
559
+ KUBERNETES_CPU_REQUEST: '0.45'
560
+ KUBERNETES_MEMORY_REQUEST: 1Gi
561
+ KUBERNETES_MEMORY_LIMIT: 4Gi
562
+ script:
563
+ - collapseable_section_start "injectvars" "Injecting variables"
564
+ - export ENV_SHORT="review"
565
+ - export APP_DIR="api"
566
+ - export ENV_TYPE="review"
567
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
568
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
569
+ - 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")"
570
+ - 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)}')"
571
+ - 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)}')"
572
+ - 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)}')"
573
+ - 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)}')"
574
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
575
+ - 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"
576
+ - export DB_USER="my-user"
577
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
578
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
579
+ - 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"
580
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-migration:run"
581
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-send-reminders:run"
582
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
583
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
584
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
585
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
586
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
587
+ - collapseable_section_end "injectvars"
588
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
589
+ - |-
590
+ cat <<EOF > api/.env
591
+ ENV_SHORT=review
592
+ APP_DIR=api
593
+ ENV_TYPE=review
594
+ 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)
595
+ 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)
596
+ 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)
597
+ 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)
598
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
599
+ 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)
600
+ DB_USER=my-user
601
+ DB_PASSWORD=$(printf %s "$CL_review_api_DB_PASSWORD" | escapeForDotEnv)
602
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
603
+ 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
604
+ CLOUD_RUN_JOB_TRIGGER_URL_migration=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-migration:run
605
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-send-reminders:run
606
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
607
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
608
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_review_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
609
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
610
+ _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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
611
+ EOF
612
+ - collapseable_section_end "write-dotenv-api"
613
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
614
+ - collapseable_section_start "nodeinstall" "Ensure node version"
615
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
616
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
617
+ - collapseable_section_end "nodeinstall"
618
+ - cd api
619
+ - collapseable_section_start "nodeinstall" "Ensure node version"
620
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
621
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
622
+ - collapseable_section_end "nodeinstall"
623
+ - collapseable_section_start "yarninstall" "Yarn install"
624
+ - yarn install --immutable
625
+ - collapseable_section_end "yarninstall"
626
+ - yarn build
627
+ cache:
628
+ - key: api-yarn
629
+ policy: pull-push
630
+ paths:
631
+ - api/.yarn
632
+ - key: api-node-modules
633
+ policy: pull-push
634
+ paths:
635
+ - api/node_modules
636
+ artifacts:
637
+ paths:
638
+ - api/__build_info.json
639
+ - api/.next
640
+ - api/dist
641
+ exclude:
642
+ - api/.env
643
+ expire_in: 1 day
644
+ when: always
645
+ reports: {}
646
+ rules:
647
+ - if: $CI_MERGE_REQUEST_ID
648
+ needs: []
649
+ retry: *a1
650
+ interruptible: true
651
+ 'api ๐Ÿ”จ docker | review ':
652
+ stage: build
653
+ image: path/to/docker/docker-build:the-version
654
+ services:
655
+ - name: docker:24.0.6-dind
656
+ command:
657
+ - --tls=false
658
+ - --registry-mirror=https://mirror.gcr.io
659
+ variables:
660
+ DOCKER_HOST: tcp://docker:2375
661
+ DOCKER_TLS_CERTDIR: ''
662
+ DOCKER_DRIVER: overlay2
663
+ DOCKER_BUILDKIT: '1'
664
+ KUBERNETES_CPU_REQUEST: '0.45'
665
+ KUBERNETES_MEMORY_REQUEST: 1Gi
666
+ KUBERNETES_MEMORY_LIMIT: 2Gi
667
+ script:
668
+ - collapseable_section_start "injectvars" "Injecting variables"
669
+ - export APP_DIR="api"
670
+ - export DOCKER_BUILD_CONTEXT="."
671
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
672
+ - 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"; })"
673
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
674
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
675
+ - |-
676
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
677
+ RUN yarn plugin import workspace-tools
678
+ RUN yarn workspaces focus --production && yarn rebuild"
679
+ - |-
680
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
681
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
682
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
683
+ COPY --chown=node:node .yarn /app/.yarn"
684
+ - collapseable_section_end "injectvars"
685
+ - ensureNodeDockerfile
686
+ - collapseable_section_start "docker-login" "Docker Login"
687
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
688
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
689
+ - collapseable_section_end "docker-login"
690
+ - collapseable_section_start "docker-build" "Docker build"
691
+ - 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
692
+ - collapseable_section_end "docker-build"
693
+ - collapseable_section_start "docker-push" "Docker push and tag"
694
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
695
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
696
+ - docker push $DOCKER_CACHE_IMAGE
697
+ - collapseable_section_end "docker-push"
698
+ cache:
699
+ - key: api-yarn
700
+ policy: pull
701
+ paths:
702
+ - api/.yarn
703
+ rules:
704
+ - if: $CI_MERGE_REQUEST_ID
705
+ needs:
706
+ - 'api ๐Ÿ”จ app | review '
707
+ retry: *a1
708
+ interruptible: true
709
+ 'api ๐Ÿงพ sbom | review ':
710
+ stage: build
711
+ image:
712
+ name: aquasec/trivy:0.58.2
713
+ entrypoint:
714
+ - ''
715
+ variables: {}
716
+ script:
717
+ - collapseable_section_start "injectvars" "Injecting variables"
718
+ - collapseable_section_end "injectvars"
719
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
720
+ artifacts:
721
+ paths:
722
+ - __sbom.json
723
+ rules:
724
+ - if: $CI_MERGE_REQUEST_ID
725
+ needs: []
726
+ retry: *a1
727
+ interruptible: true
728
+ allow_failure: true
729
+ 'api ๐Ÿš€ Deploy | review ':
730
+ stage: deploy review
731
+ image: path/to/docker/gcloud:the-version
732
+ variables:
733
+ KUBERNETES_CPU_REQUEST: '0.22'
734
+ KUBERNETES_MEMORY_REQUEST: 200Mi
735
+ KUBERNETES_MEMORY_LIMIT: 400Mi
736
+ script:
737
+ - collapseable_section_start "injectvars" "Injecting variables"
738
+ - export ENV_SHORT="review"
739
+ - export APP_DIR="api"
740
+ - export ENV_TYPE="review"
741
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
742
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
743
+ - 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")"
744
+ - 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)}')"
745
+ - 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)}')"
746
+ - 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)}')"
747
+ - 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)}')"
748
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
749
+ - 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"
750
+ - export DB_USER="my-user"
751
+ - export DB_PASSWORD="$CL_review_api_DB_PASSWORD"
752
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
753
+ - 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"
754
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-migration:run"
755
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-send-reminders:run"
756
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
757
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
758
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_review_api_GCLOUD_DEPLOY_credentialsKey"
759
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_review_api_GCLOUD_RUN_canonicalHostSuffix"
760
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
761
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
762
+ - 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"; })"
763
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
764
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
765
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
766
+ - collapseable_section_end "injectvars"
767
+ - collapseable_section_start "prepare" "Prepare..."
768
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
769
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
770
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
771
+ - collapseable_section_end "prepare"
772
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
773
+ - |
774
+ cat > ____envvars.yaml <<EOF
775
+ ENV_SHORT: |-
776
+ review
777
+ APP_DIR: |-
778
+ api
779
+ ENV_TYPE: |-
780
+ review
781
+ BUILD_INFO_BUILD_ID: |-
782
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
783
+ BUILD_INFO_BUILD_TIME: |-
784
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
785
+ BUILD_INFO_CURRENT_VERSION: |-
786
+ $(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/^/ /')
787
+ HOSTNAME: |-
788
+ $(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/^/ /')
789
+ ROOT_URL: |-
790
+ $(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/^/ /')
791
+ HOSTNAME_INTERNAL: |-
792
+ $(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/^/ /')
793
+ ROOT_URL_INTERNAL: |-
794
+ $(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/^/ /')
795
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
796
+ projectId:region:instancename
797
+ DB_NAME: |-
798
+ $(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/^/ /')
799
+ DB_USER: |-
800
+ my-user
801
+ DB_PASSWORD: |-
802
+ $(printf %s "$CL_review_api_DB_PASSWORD" | sed '1!s/^/ /')
803
+ DATABASE_URL: |-
804
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
805
+ DATABASE_JDBC_URL: |-
806
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
807
+ CLOUD_RUN_JOB_TRIGGER_URL_migration: |-
808
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-migration:run
809
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders: |-
810
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-send-reminders:run
811
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
812
+ google-project-id
813
+ DEPLOY_CLOUD_RUN_REGION: |-
814
+ europe-west6
815
+ GCLOUD_RUN_canonicalHostSuffix: |-
816
+ $(printf %s "$CL_review_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
817
+ _ALL_ENV_VAR_KEYS: |-
818
+ ["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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
819
+
820
+ EOF
821
+ - collapseable_section_end "writeenvvars"
822
+ - collapseable_section_start "deploy" "Deploy to cloud run"
823
+ - set +e
824
+ - echo "ensuring Database..."
825
+ - 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
826
+ - set -e
827
+ - |-
828
+ exist_scheduler_names="$(
829
+ gcloud scheduler jobs list --filter='httpTarget.uri ~ review.*api' --format='value(name)' --limit=999 --location='europe-west6' --project='google-project-id'
830
+ )"
831
+ current_job_uri="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/$(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)}')-send-reminders:run"
832
+ current_scheduler_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)}')-send-reminders-scheduler"
833
+ if grep "$current_scheduler_name" <<<"$exist_scheduler_names" >/dev/null; then
834
+ gcloud scheduler jobs update http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
835
+ else
836
+ gcloud scheduler jobs create http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
837
+ fi
838
+ - |-
839
+ exist_job_names="$(
840
+ gcloud run jobs list --filter='metadata.name ~ review.*api' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
841
+ )"
842
+ current_job_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)}')-migration"
843
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
844
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
845
+ else
846
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
847
+ fi
848
+ - |-
849
+ current_job_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)}')-send-reminders"
850
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
851
+ gcloud run jobs update "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
852
+ else
853
+ gcloud run jobs create "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=review,env-name=review,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
854
+ fi
855
+ - gcloud run jobs execute $(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)}')-migration --project=google-project-id --region=europe-west6 --wait
856
+ - 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=5 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
857
+ - collapseable_section_end "deploy"
858
+ - collapseable_section_start "cleanup" "Cleanup"
859
+ - 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
860
+ - 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
861
+ - 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
862
+ - set +e
863
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
864
+ - set -e
865
+ - collapseable_section_end "cleanup"
866
+ - echo 'Uploading SBOM to Dependency Track'
867
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
868
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
869
+ environment:
870
+ name: review/$CI_COMMIT_REF_NAME/api
871
+ url: $CL_GITLAB_ENVIRONMENT_URL
872
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | review '
873
+ auto_stop_in: 1 week
874
+ artifacts:
875
+ reports:
876
+ dotenv: gitlab_environment.env
877
+ rules:
878
+ - when: on_success
879
+ if: $CI_MERGE_REQUEST_ID
880
+ needs:
881
+ - job: api ๐Ÿ‘ฎ lint
882
+ artifacts: false
883
+ - job: 'api ๐Ÿ”จ app | review '
884
+ artifacts: false
885
+ - job: 'api ๐Ÿ”จ docker | review '
886
+ artifacts: false
887
+ - job: api ๐Ÿงช test
888
+ artifacts: false
889
+ - job: 'api ๐Ÿงพ sbom | review '
890
+ artifacts: true
891
+ - job: api ๐Ÿ›ก audit
892
+ artifacts: false
893
+ retry: *a1
894
+ interruptible: true
895
+ allow_failure: false
896
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | review ':
897
+ stage: stop review
898
+ image: path/to/docker/gcloud:the-version
899
+ variables:
900
+ KUBERNETES_CPU_REQUEST: '0.22'
901
+ KUBERNETES_MEMORY_REQUEST: 200Mi
902
+ KUBERNETES_MEMORY_LIMIT: 400Mi
903
+ GIT_STRATEGY: none
904
+ script:
905
+ - collapseable_section_start "injectvars" "Injecting variables"
906
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
907
+ - collapseable_section_end "injectvars"
908
+ - set +e
909
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_review_api_GCLOUD_DEPLOY_credentialsKey")
910
+ - 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
911
+ - gcloud scheduler jobs 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)}')-send-reminders-scheduler --project=google-project-id --location=europe-west6
912
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job $(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)}')-migration --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
913
+ - gcloud run jobs 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)}')-migration --project=google-project-id --region=europe-west6
914
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job $(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)}')-send-reminders --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
915
+ - gcloud run jobs 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)}')-send-reminders --project=google-project-id --region=europe-west6
916
+ - 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..."
917
+ - 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"
918
+ - "\\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 "
919
+ - 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
920
+ - 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
921
+ - set +e
922
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/review/api --quiet --delete-tags
923
+ - set -e
924
+ - echo 'Disabling component in Dependency Track'
925
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
926
+ - set -e
927
+ environment:
928
+ name: review/$CI_COMMIT_REF_NAME/api
929
+ action: stop
930
+ rules:
931
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
932
+ when: on_success
933
+ - when: manual
934
+ if: $CI_MERGE_REQUEST_ID
935
+ needs: []
936
+ retry: *a1
937
+ interruptible: true
938
+ allow_failure: true
939
+ 'api ๐Ÿ”จ app | stage ':
940
+ stage: build
941
+ image: path/to/docker/jobs-default:the-version
942
+ variables:
943
+ KUBERNETES_CPU_REQUEST: '0.45'
944
+ KUBERNETES_MEMORY_REQUEST: 1Gi
945
+ KUBERNETES_MEMORY_LIMIT: 4Gi
946
+ script:
947
+ - collapseable_section_start "injectvars" "Injecting variables"
948
+ - export ENV_SHORT="stage"
949
+ - export APP_DIR="api"
950
+ - export ENV_TYPE="stage"
951
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
952
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
953
+ - 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")"
954
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
955
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
956
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
957
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
958
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
959
+ - export DB_NAME="pan-test-app-stage-api"
960
+ - export DB_USER="my-user"
961
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
962
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
963
+ - 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"
964
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-migration:run"
965
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-send-reminders:run"
966
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
967
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
968
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
969
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
970
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
971
+ - collapseable_section_end "injectvars"
972
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
973
+ - |-
974
+ cat <<EOF > api/.env
975
+ ENV_SHORT=stage
976
+ APP_DIR=api
977
+ ENV_TYPE=stage
978
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
979
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
980
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
981
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
982
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
983
+ DB_NAME=pan-test-app-stage-api
984
+ DB_USER=my-user
985
+ DB_PASSWORD=$(printf %s "$CL_stage_api_DB_PASSWORD" | escapeForDotEnv)
986
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
987
+ 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
988
+ CLOUD_RUN_JOB_TRIGGER_URL_migration=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-migration:run
989
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-send-reminders:run
990
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
991
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
992
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
993
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
994
+ _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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
995
+ EOF
996
+ - collapseable_section_end "write-dotenv-api"
997
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
998
+ - collapseable_section_start "nodeinstall" "Ensure node version"
999
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1000
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1001
+ - collapseable_section_end "nodeinstall"
1002
+ - cd api
1003
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1004
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1005
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1006
+ - collapseable_section_end "nodeinstall"
1007
+ - collapseable_section_start "yarninstall" "Yarn install"
1008
+ - yarn install --immutable
1009
+ - collapseable_section_end "yarninstall"
1010
+ - yarn build
1011
+ cache:
1012
+ - key: api-yarn
1013
+ policy: pull-push
1014
+ paths:
1015
+ - api/.yarn
1016
+ - key: api-node-modules
1017
+ policy: pull-push
1018
+ paths:
1019
+ - api/node_modules
1020
+ artifacts:
1021
+ paths:
1022
+ - api/__build_info.json
1023
+ - api/.next
1024
+ - api/dist
1025
+ exclude:
1026
+ - api/.env
1027
+ expire_in: 1 day
1028
+ when: always
1029
+ reports: {}
1030
+ rules:
1031
+ - if: $CI_COMMIT_TAG
1032
+ needs: []
1033
+ retry: *a1
1034
+ interruptible: true
1035
+ 'api ๐Ÿ”จ docker | stage ':
1036
+ stage: build
1037
+ image: path/to/docker/docker-build:the-version
1038
+ services:
1039
+ - name: docker:24.0.6-dind
1040
+ command:
1041
+ - --tls=false
1042
+ - --registry-mirror=https://mirror.gcr.io
1043
+ variables:
1044
+ DOCKER_HOST: tcp://docker:2375
1045
+ DOCKER_TLS_CERTDIR: ''
1046
+ DOCKER_DRIVER: overlay2
1047
+ DOCKER_BUILDKIT: '1'
1048
+ KUBERNETES_CPU_REQUEST: '0.45'
1049
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1050
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1051
+ script:
1052
+ - collapseable_section_start "injectvars" "Injecting variables"
1053
+ - export APP_DIR="api"
1054
+ - export DOCKER_BUILD_CONTEXT="."
1055
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1056
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1057
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1058
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1059
+ - |-
1060
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1061
+ RUN yarn plugin import workspace-tools
1062
+ RUN yarn workspaces focus --production && yarn rebuild"
1063
+ - |-
1064
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1065
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1066
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1067
+ COPY --chown=node:node .yarn /app/.yarn"
1068
+ - collapseable_section_end "injectvars"
1069
+ - ensureNodeDockerfile
1070
+ - collapseable_section_start "docker-login" "Docker Login"
1071
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1072
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1073
+ - collapseable_section_end "docker-login"
1074
+ - collapseable_section_start "docker-build" "Docker build"
1075
+ - 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
1076
+ - collapseable_section_end "docker-build"
1077
+ - collapseable_section_start "docker-push" "Docker push and tag"
1078
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1079
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1080
+ - docker push $DOCKER_CACHE_IMAGE
1081
+ - collapseable_section_end "docker-push"
1082
+ cache:
1083
+ - key: api-yarn
1084
+ policy: pull
1085
+ paths:
1086
+ - api/.yarn
1087
+ rules:
1088
+ - if: $CI_COMMIT_TAG
1089
+ needs:
1090
+ - 'api ๐Ÿ”จ app | stage '
1091
+ retry: *a1
1092
+ interruptible: true
1093
+ 'api ๐Ÿงพ sbom | stage ':
1094
+ stage: build
1095
+ image:
1096
+ name: aquasec/trivy:0.58.2
1097
+ entrypoint:
1098
+ - ''
1099
+ variables: {}
1100
+ script:
1101
+ - collapseable_section_start "injectvars" "Injecting variables"
1102
+ - collapseable_section_end "injectvars"
1103
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1104
+ artifacts:
1105
+ paths:
1106
+ - __sbom.json
1107
+ rules:
1108
+ - if: $CI_COMMIT_TAG
1109
+ needs: []
1110
+ retry: *a1
1111
+ interruptible: true
1112
+ allow_failure: true
1113
+ 'api ๐Ÿš€ Deploy | stage ':
1114
+ stage: deploy stage
1115
+ image: path/to/docker/gcloud:the-version
1116
+ variables:
1117
+ KUBERNETES_CPU_REQUEST: '0.22'
1118
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1119
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1120
+ script:
1121
+ - collapseable_section_start "injectvars" "Injecting variables"
1122
+ - export ENV_SHORT="stage"
1123
+ - export APP_DIR="api"
1124
+ - export ENV_TYPE="stage"
1125
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1126
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1127
+ - 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")"
1128
+ - export HOSTNAME="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1129
+ - export ROOT_URL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1130
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1131
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1132
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1133
+ - export DB_NAME="pan-test-app-stage-api"
1134
+ - export DB_USER="my-user"
1135
+ - export DB_PASSWORD="$CL_stage_api_DB_PASSWORD"
1136
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1137
+ - 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"
1138
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-migration:run"
1139
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-send-reminders:run"
1140
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1141
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1142
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_stage_api_GCLOUD_DEPLOY_credentialsKey"
1143
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix"
1144
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1145
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1146
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api"
1147
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1148
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1149
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1150
+ - collapseable_section_end "injectvars"
1151
+ - collapseable_section_start "prepare" "Prepare..."
1152
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1153
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1154
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1155
+ - collapseable_section_end "prepare"
1156
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1157
+ - |
1158
+ cat > ____envvars.yaml <<EOF
1159
+ ENV_SHORT: |-
1160
+ stage
1161
+ APP_DIR: |-
1162
+ api
1163
+ ENV_TYPE: |-
1164
+ stage
1165
+ BUILD_INFO_BUILD_ID: |-
1166
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1167
+ BUILD_INFO_BUILD_TIME: |-
1168
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1169
+ BUILD_INFO_CURRENT_VERSION: |-
1170
+ $(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/^/ /')
1171
+ HOSTNAME: |-
1172
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1173
+ ROOT_URL: |-
1174
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1175
+ HOSTNAME_INTERNAL: |-
1176
+ $(printf %s "$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1177
+ ROOT_URL_INTERNAL: |-
1178
+ $(printf %s "https://$(printf %s "pan-test-app-stage-api-$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1179
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1180
+ projectId:region:instancename
1181
+ DB_NAME: |-
1182
+ pan-test-app-stage-api
1183
+ DB_USER: |-
1184
+ my-user
1185
+ DB_PASSWORD: |-
1186
+ $(printf %s "$CL_stage_api_DB_PASSWORD" | sed '1!s/^/ /')
1187
+ DATABASE_URL: |-
1188
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1189
+ DATABASE_JDBC_URL: |-
1190
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
1191
+ CLOUD_RUN_JOB_TRIGGER_URL_migration: |-
1192
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-migration:run
1193
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders: |-
1194
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-send-reminders:run
1195
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1196
+ google-project-id
1197
+ DEPLOY_CLOUD_RUN_REGION: |-
1198
+ europe-west6
1199
+ GCLOUD_RUN_canonicalHostSuffix: |-
1200
+ $(printf %s "$CL_stage_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1201
+ _ALL_ENV_VAR_KEYS: |-
1202
+ ["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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1203
+
1204
+ EOF
1205
+ - collapseable_section_end "writeenvvars"
1206
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1207
+ - set +e
1208
+ - echo "ensuring Database..."
1209
+ - gcloud sql databases create pan-test-app-stage-api --instance=instancename --project projectId
1210
+ - set -e
1211
+ - |-
1212
+ exist_scheduler_names="$(
1213
+ gcloud scheduler jobs list --filter='httpTarget.uri ~ stage.*api' --format='value(name)' --limit=999 --location='europe-west6' --project='google-project-id'
1214
+ )"
1215
+ current_job_uri="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-stage-api-send-reminders:run"
1216
+ current_scheduler_name="pan-test-app-stage-api-send-reminders-scheduler"
1217
+ if grep "$current_scheduler_name" <<<"$exist_scheduler_names" >/dev/null; then
1218
+ gcloud scheduler jobs update http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
1219
+ else
1220
+ gcloud scheduler jobs create http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
1221
+ fi
1222
+ - |-
1223
+ exist_job_names="$(
1224
+ gcloud run jobs list --filter='metadata.name ~ stage.*api' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
1225
+ )"
1226
+ current_job_name="pan-test-app-stage-api-migration"
1227
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1228
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1229
+ else
1230
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1231
+ fi
1232
+ - |-
1233
+ current_job_name="pan-test-app-stage-api-send-reminders"
1234
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1235
+ gcloud run jobs update "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1236
+ else
1237
+ gcloud run jobs create "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=stage,env-name=stage,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1238
+ fi
1239
+ - gcloud run jobs execute pan-test-app-stage-api-migration --project=google-project-id --region=europe-west6 --wait
1240
+ - 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=5 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1241
+ - collapseable_section_end "deploy"
1242
+ - collapseable_section_start "cleanup" "Cleanup"
1243
+ - 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
1244
+ - 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
1245
+ - 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
1246
+ - collapseable_section_end "cleanup"
1247
+ - echo 'Uploading SBOM to Dependency Track'
1248
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
1249
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1250
+ environment:
1251
+ name: stage/api
1252
+ url: $CL_GITLAB_ENVIRONMENT_URL
1253
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | stage '
1254
+ artifacts:
1255
+ reports:
1256
+ dotenv: gitlab_environment.env
1257
+ rules:
1258
+ - when: on_success
1259
+ if: $CI_COMMIT_TAG
1260
+ needs:
1261
+ - job: 'api ๐Ÿ”จ app | stage '
1262
+ artifacts: false
1263
+ - job: 'api ๐Ÿ”จ docker | stage '
1264
+ artifacts: false
1265
+ - job: 'api ๐Ÿงพ sbom | stage '
1266
+ artifacts: true
1267
+ retry: *a1
1268
+ interruptible: true
1269
+ allow_failure: false
1270
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | stage ':
1271
+ stage: stop stage
1272
+ image: path/to/docker/gcloud:the-version
1273
+ variables:
1274
+ KUBERNETES_CPU_REQUEST: '0.22'
1275
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1276
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1277
+ GIT_STRATEGY: none
1278
+ script:
1279
+ - collapseable_section_start "injectvars" "Injecting variables"
1280
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1281
+ - collapseable_section_end "injectvars"
1282
+ - set +e
1283
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_stage_api_GCLOUD_DEPLOY_credentialsKey")
1284
+ - gcloud run services delete pan-test-app-stage-api --project=google-project-id --region=europe-west6
1285
+ - gcloud scheduler jobs delete pan-test-app-stage-api-send-reminders-scheduler --project=google-project-id --location=europe-west6
1286
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-stage-api-migration --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1287
+ - gcloud run jobs delete pan-test-app-stage-api-migration --project=google-project-id --region=europe-west6
1288
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-stage-api-send-reminders --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1289
+ - gcloud run jobs delete pan-test-app-stage-api-send-reminders --project=google-project-id --region=europe-west6
1290
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/stage/api --quiet --delete-tags
1291
+ - 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
1292
+ - echo 'Disabling component in Dependency Track'
1293
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
1294
+ - set -e
1295
+ environment:
1296
+ name: stage/api
1297
+ action: stop
1298
+ rules:
1299
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1300
+ when: on_success
1301
+ - when: manual
1302
+ if: $CI_COMMIT_TAG
1303
+ needs: []
1304
+ retry: *a1
1305
+ interruptible: true
1306
+ allow_failure: true
1307
+ 'api ๐Ÿ”จ app | prod ':
1308
+ stage: build
1309
+ image: path/to/docker/jobs-default:the-version
1310
+ variables:
1311
+ KUBERNETES_CPU_REQUEST: '0.45'
1312
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1313
+ KUBERNETES_MEMORY_LIMIT: 4Gi
1314
+ script:
1315
+ - collapseable_section_start "injectvars" "Injecting variables"
1316
+ - export ENV_SHORT="prod"
1317
+ - export APP_DIR="api"
1318
+ - export ENV_TYPE="prod"
1319
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1320
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1321
+ - 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")"
1322
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1323
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1324
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1325
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1326
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1327
+ - export DB_NAME="pan-test-app-prod-api"
1328
+ - export DB_USER="my-user"
1329
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
1330
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1331
+ - 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"
1332
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-migration:run"
1333
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-send-reminders:run"
1334
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1335
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1336
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1337
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1338
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1339
+ - collapseable_section_end "injectvars"
1340
+ - collapseable_section_start "write-dotenv-api" "write dot env for api"
1341
+ - |-
1342
+ cat <<EOF > api/.env
1343
+ ENV_SHORT=prod
1344
+ APP_DIR=api
1345
+ ENV_TYPE=prod
1346
+ HOSTNAME=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1347
+ ROOT_URL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1348
+ HOSTNAME_INTERNAL=$(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1349
+ ROOT_URL_INTERNAL=$(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | escapeForDotEnv)
1350
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME=projectId:region:instancename
1351
+ DB_NAME=pan-test-app-prod-api
1352
+ DB_USER=my-user
1353
+ DB_PASSWORD=$(printf %s "$CL_prod_api_DB_PASSWORD" | escapeForDotEnv)
1354
+ DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1355
+ 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
1356
+ CLOUD_RUN_JOB_TRIGGER_URL_migration=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-migration:run
1357
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders=https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-send-reminders:run
1358
+ DEPLOY_CLOUD_RUN_PROJECT_ID=google-project-id
1359
+ DEPLOY_CLOUD_RUN_REGION=europe-west6
1360
+ GCLOUD_DEPLOY_credentialsKey=$(printf %s "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey" | escapeForDotEnv)
1361
+ GCLOUD_RUN_canonicalHostSuffix=$(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | escapeForDotEnv)
1362
+ _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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1363
+ EOF
1364
+ - collapseable_section_end "write-dotenv-api"
1365
+ - echo '{"id":"$(git describe --tags 2>/dev/null || git rev-parse HEAD)","time":"$CI_JOB_STARTED_AT"}' > api/__build_info.json
1366
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1367
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1368
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1369
+ - collapseable_section_end "nodeinstall"
1370
+ - cd api
1371
+ - collapseable_section_start "nodeinstall" "Ensure node version"
1372
+ - if [ -f ~/.nvm/nvm.sh ]; then source ~/.nvm/nvm.sh; fi
1373
+ - if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi
1374
+ - collapseable_section_end "nodeinstall"
1375
+ - collapseable_section_start "yarninstall" "Yarn install"
1376
+ - yarn install --immutable
1377
+ - collapseable_section_end "yarninstall"
1378
+ - yarn build
1379
+ cache:
1380
+ - key: api-yarn
1381
+ policy: pull-push
1382
+ paths:
1383
+ - api/.yarn
1384
+ - key: api-node-modules
1385
+ policy: pull-push
1386
+ paths:
1387
+ - api/node_modules
1388
+ artifacts:
1389
+ paths:
1390
+ - api/__build_info.json
1391
+ - api/.next
1392
+ - api/dist
1393
+ exclude:
1394
+ - api/.env
1395
+ expire_in: 1 day
1396
+ when: always
1397
+ reports: {}
1398
+ rules:
1399
+ - if: $CI_COMMIT_TAG
1400
+ needs: []
1401
+ retry: *a1
1402
+ interruptible: true
1403
+ 'api ๐Ÿ”จ docker | prod ':
1404
+ stage: build
1405
+ image: path/to/docker/docker-build:the-version
1406
+ services:
1407
+ - name: docker:24.0.6-dind
1408
+ command:
1409
+ - --tls=false
1410
+ - --registry-mirror=https://mirror.gcr.io
1411
+ variables:
1412
+ DOCKER_HOST: tcp://docker:2375
1413
+ DOCKER_TLS_CERTDIR: ''
1414
+ DOCKER_DRIVER: overlay2
1415
+ DOCKER_BUILDKIT: '1'
1416
+ KUBERNETES_CPU_REQUEST: '0.45'
1417
+ KUBERNETES_MEMORY_REQUEST: 1Gi
1418
+ KUBERNETES_MEMORY_LIMIT: 2Gi
1419
+ script:
1420
+ - collapseable_section_start "injectvars" "Injecting variables"
1421
+ - export APP_DIR="api"
1422
+ - export DOCKER_BUILD_CONTEXT="."
1423
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1424
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1425
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1426
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1427
+ - |-
1428
+ export DOCKER_COPY_AND_INSTALL_APP="COPY --chown=node:node $APP_DIR .
1429
+ RUN yarn plugin import workspace-tools
1430
+ RUN yarn workspaces focus --production && yarn rebuild"
1431
+ - |-
1432
+ export DOCKER_COPY_WORKSPACE_FILES="COPY --chown=node:node api/package.json /app/api/package.json
1433
+ COPY --chown=node:node api/yarn.lock /app/api/yarn.lock
1434
+ COPY --chown=node:node .yarnrc.yml /app/.yarnrc.yml
1435
+ COPY --chown=node:node .yarn /app/.yarn"
1436
+ - collapseable_section_end "injectvars"
1437
+ - ensureNodeDockerfile
1438
+ - collapseable_section_start "docker-login" "Docker Login"
1439
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1440
+ - gcloud auth configure-docker europe-west6-docker.pkg.dev
1441
+ - collapseable_section_end "docker-login"
1442
+ - collapseable_section_start "docker-build" "Docker build"
1443
+ - 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
1444
+ - collapseable_section_end "docker-build"
1445
+ - collapseable_section_start "docker-push" "Docker push and tag"
1446
+ - docker push $DOCKER_IMAGE:$DOCKER_IMAGE_TAG
1447
+ - docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_CACHE_IMAGE
1448
+ - docker push $DOCKER_CACHE_IMAGE
1449
+ - collapseable_section_end "docker-push"
1450
+ cache:
1451
+ - key: api-yarn
1452
+ policy: pull
1453
+ paths:
1454
+ - api/.yarn
1455
+ rules:
1456
+ - if: $CI_COMMIT_TAG
1457
+ needs:
1458
+ - 'api ๐Ÿ”จ app | prod '
1459
+ retry: *a1
1460
+ interruptible: true
1461
+ 'api ๐Ÿงพ sbom | prod ':
1462
+ stage: build
1463
+ image:
1464
+ name: aquasec/trivy:0.58.2
1465
+ entrypoint:
1466
+ - ''
1467
+ variables: {}
1468
+ script:
1469
+ - collapseable_section_start "injectvars" "Injecting variables"
1470
+ - collapseable_section_end "injectvars"
1471
+ - trivy fs --quiet --format cyclonedx --output "__sbom.json" api
1472
+ artifacts:
1473
+ paths:
1474
+ - __sbom.json
1475
+ rules:
1476
+ - if: $CI_COMMIT_TAG
1477
+ needs: []
1478
+ retry: *a1
1479
+ interruptible: true
1480
+ allow_failure: true
1481
+ 'api ๐Ÿš€ Deploy | prod ':
1482
+ stage: deploy prod
1483
+ image: path/to/docker/gcloud:the-version
1484
+ variables:
1485
+ KUBERNETES_CPU_REQUEST: '0.22'
1486
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1487
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1488
+ script:
1489
+ - collapseable_section_start "injectvars" "Injecting variables"
1490
+ - export ENV_SHORT="prod"
1491
+ - export APP_DIR="api"
1492
+ - export ENV_TYPE="prod"
1493
+ - export BUILD_INFO_BUILD_ID="$(git describe --tags 2>/dev/null || git rev-parse HEAD)"
1494
+ - export BUILD_INFO_BUILD_TIME="$CI_JOB_STARTED_AT"
1495
+ - 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")"
1496
+ - export HOSTNAME="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1497
+ - export ROOT_URL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1498
+ - export HOSTNAME_INTERNAL="$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1499
+ - export ROOT_URL_INTERNAL="https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')"
1500
+ - export CLOUD_SQL_INSTANCE_CONNECTION_NAME="projectId:region:instancename"
1501
+ - export DB_NAME="pan-test-app-prod-api"
1502
+ - export DB_USER="my-user"
1503
+ - export DB_PASSWORD="$CL_prod_api_DB_PASSWORD"
1504
+ - export DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME"
1505
+ - 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"
1506
+ - export CLOUD_RUN_JOB_TRIGGER_URL_migration="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-migration:run"
1507
+ - export CLOUD_RUN_JOB_TRIGGER_URL_send_reminders="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-send-reminders:run"
1508
+ - export DEPLOY_CLOUD_RUN_PROJECT_ID="google-project-id"
1509
+ - export DEPLOY_CLOUD_RUN_REGION="europe-west6"
1510
+ - export GCLOUD_DEPLOY_credentialsKey="$CL_prod_api_GCLOUD_DEPLOY_credentialsKey"
1511
+ - export GCLOUD_RUN_canonicalHostSuffix="$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix"
1512
+ - 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\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_migration\\",\\"CLOUD_RUN_JOB_TRIGGER_URL_send_reminders\\",\\"DEPLOY_CLOUD_RUN_PROJECT_ID\\",\\"DEPLOY_CLOUD_RUN_REGION\\",\\"GCLOUD_DEPLOY_credentialsKey\\",\\"GCLOUD_RUN_canonicalHostSuffix\\"]"
1513
+ - export DOCKER_REGISTRY="europe-west6-docker.pkg.dev"
1514
+ - export DOCKER_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api"
1515
+ - export DOCKER_CACHE_IMAGE="europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/caches/api"
1516
+ - export DOCKER_IMAGE_TAG="$CI_COMMIT_SHA"
1517
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1518
+ - collapseable_section_end "injectvars"
1519
+ - collapseable_section_start "prepare" "Prepare..."
1520
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1521
+ - export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe google-project-id --format="value(projectNumber)")
1522
+ - 'echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"'
1523
+ - collapseable_section_end "prepare"
1524
+ - collapseable_section_start "writeenvvars" "Write env vars to file"
1525
+ - |
1526
+ cat > ____envvars.yaml <<EOF
1527
+ ENV_SHORT: |-
1528
+ prod
1529
+ APP_DIR: |-
1530
+ api
1531
+ ENV_TYPE: |-
1532
+ prod
1533
+ BUILD_INFO_BUILD_ID: |-
1534
+ $(printf %s "$(git describe --tags 2>/dev/null || git rev-parse HEAD)" | sed '1!s/^/ /')
1535
+ BUILD_INFO_BUILD_TIME: |-
1536
+ $(printf %s "$CI_JOB_STARTED_AT" | sed '1!s/^/ /')
1537
+ BUILD_INFO_CURRENT_VERSION: |-
1538
+ $(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/^/ /')
1539
+ HOSTNAME: |-
1540
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1541
+ ROOT_URL: |-
1542
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1543
+ HOSTNAME_INTERNAL: |-
1544
+ $(printf %s "$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1545
+ ROOT_URL_INTERNAL: |-
1546
+ $(printf %s "https://$(printf %s "pan-test-app-prod-api-$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | awk '{print tolower($0)}')" | sed '1!s/^/ /')
1547
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME: |-
1548
+ projectId:region:instancename
1549
+ DB_NAME: |-
1550
+ pan-test-app-prod-api
1551
+ DB_USER: |-
1552
+ my-user
1553
+ DB_PASSWORD: |-
1554
+ $(printf %s "$CL_prod_api_DB_PASSWORD" | sed '1!s/^/ /')
1555
+ DATABASE_URL: |-
1556
+ postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME
1557
+ DATABASE_JDBC_URL: |-
1558
+ jdbc:postgresql:///$DB_NAME?cloudSqlInstance=$CLOUD_SQL_INSTANCE_CONNECTION_NAME&socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=$DB_USER&password=$DB_PASSWORD
1559
+ CLOUD_RUN_JOB_TRIGGER_URL_migration: |-
1560
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-migration:run
1561
+ CLOUD_RUN_JOB_TRIGGER_URL_send_reminders: |-
1562
+ https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-send-reminders:run
1563
+ DEPLOY_CLOUD_RUN_PROJECT_ID: |-
1564
+ google-project-id
1565
+ DEPLOY_CLOUD_RUN_REGION: |-
1566
+ europe-west6
1567
+ GCLOUD_RUN_canonicalHostSuffix: |-
1568
+ $(printf %s "$CL_prod_api_GCLOUD_RUN_canonicalHostSuffix" | sed '1!s/^/ /')
1569
+ _ALL_ENV_VAR_KEYS: |-
1570
+ ["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","CLOUD_RUN_JOB_TRIGGER_URL_migration","CLOUD_RUN_JOB_TRIGGER_URL_send_reminders","DEPLOY_CLOUD_RUN_PROJECT_ID","DEPLOY_CLOUD_RUN_REGION","GCLOUD_DEPLOY_credentialsKey","GCLOUD_RUN_canonicalHostSuffix"]
1571
+
1572
+ EOF
1573
+ - collapseable_section_end "writeenvvars"
1574
+ - collapseable_section_start "deploy" "Deploy to cloud run"
1575
+ - set +e
1576
+ - echo "ensuring Database..."
1577
+ - gcloud sql databases create pan-test-app-prod-api --instance=instancename --project projectId
1578
+ - set -e
1579
+ - |-
1580
+ exist_scheduler_names="$(
1581
+ gcloud scheduler jobs list --filter='httpTarget.uri ~ prod.*api' --format='value(name)' --limit=999 --location='europe-west6' --project='google-project-id'
1582
+ )"
1583
+ current_job_uri="https://europe-west6-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/google-project-id/jobs/pan-test-app-prod-api-send-reminders:run"
1584
+ current_scheduler_name="pan-test-app-prod-api-send-reminders-scheduler"
1585
+ if grep "$current_scheduler_name" <<<"$exist_scheduler_names" >/dev/null; then
1586
+ gcloud scheduler jobs update http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
1587
+ else
1588
+ gcloud scheduler jobs create http "$current_scheduler_name" --project=google-project-id --location=europe-west6 --uri="$current_job_uri" --http-method=POST --oauth-service-account-email="$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com" --schedule="0 * * * *" --max-retry-attempts=0
1589
+ fi
1590
+ - |-
1591
+ exist_job_names="$(
1592
+ gcloud run jobs list --filter='metadata.name ~ prod.*api' --format='value(name)' --limit=999 --project='google-project-id' --region='europe-west6'
1593
+ )"
1594
+ current_job_name="pan-test-app-prod-api-migration"
1595
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1596
+ gcloud run jobs update "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1597
+ else
1598
+ gcloud run jobs create "$current_job_name" --command="yarn,migrate" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=10m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1599
+ fi
1600
+ - |-
1601
+ current_job_name="pan-test-app-prod-api-send-reminders"
1602
+ if grep "$current_job_name" <<<"$exist_job_names" >/dev/null; then
1603
+ gcloud run jobs update "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1604
+ else
1605
+ gcloud run jobs create "$current_job_name" --command="yarn,job:send-reminders" --labels="customer-name=pan,component-name=api,app-name=test-app,env-type=prod,env-name=prod,build-type=node,cloud-run-job-name=$current_job_name" --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 --memory=512Mi --parallelism=1 --task-timeout=15m --env-vars-file=____envvars.yaml --max-retries=0 --set-cloudsql-instances=projectId:region:instancename
1606
+ fi
1607
+ - gcloud run jobs execute pan-test-app-prod-api-migration --project=google-project-id --region=europe-west6 --wait
1608
+ - 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=5 --cpu-throttling --allow-unauthenticated --ingress=all --cpu-boost
1609
+ - collapseable_section_end "deploy"
1610
+ - collapseable_section_start "cleanup" "Cleanup"
1611
+ - 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
1612
+ - 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
1613
+ - 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
1614
+ - collapseable_section_end "cleanup"
1615
+ - echo 'Uploading SBOM to Dependency Track'
1616
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "pan-test-app/api" "$ROOT_URL" "__sbom.json" vex.json || true
1617
+ - echo "CL_GITLAB_ENVIRONMENT_URL=$ROOT_URL" >> gitlab_environment.env
1618
+ environment:
1619
+ name: prod/api
1620
+ url: $CL_GITLAB_ENVIRONMENT_URL
1621
+ on_stop: 'api ๐Ÿ›‘ Stop โš ๏ธ | prod '
1622
+ artifacts:
1623
+ reports:
1624
+ dotenv: gitlab_environment.env
1625
+ rules:
1626
+ - when: manual
1627
+ if: $CI_COMMIT_TAG
1628
+ needs:
1629
+ - job: 'api ๐Ÿ”จ app | prod '
1630
+ artifacts: false
1631
+ - job: 'api ๐Ÿ”จ docker | prod '
1632
+ artifacts: false
1633
+ - job: 'api ๐Ÿงพ sbom | prod '
1634
+ artifacts: true
1635
+ retry: *a1
1636
+ interruptible: true
1637
+ allow_failure: true
1638
+ 'api ๐Ÿ›‘ Stop โš ๏ธ | prod ':
1639
+ stage: stop prod
1640
+ image: path/to/docker/gcloud:the-version
1641
+ variables:
1642
+ KUBERNETES_CPU_REQUEST: '0.22'
1643
+ KUBERNETES_MEMORY_REQUEST: 200Mi
1644
+ KUBERNETES_MEMORY_LIMIT: 400Mi
1645
+ GIT_STRATEGY: none
1646
+ script:
1647
+ - collapseable_section_start "injectvars" "Injecting variables"
1648
+ - export CLOUDSDK_CORE_DISABLE_PROMPTS="1"
1649
+ - collapseable_section_end "injectvars"
1650
+ - set +e
1651
+ - gcloud auth activate-service-account --key-file=<(echo "$CL_prod_api_GCLOUD_DEPLOY_credentialsKey")
1652
+ - gcloud run services delete pan-test-app-prod-api --project=google-project-id --region=europe-west6
1653
+ - gcloud scheduler jobs delete pan-test-app-prod-api-send-reminders-scheduler --project=google-project-id --location=europe-west6
1654
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-prod-api-migration --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1655
+ - gcloud run jobs delete pan-test-app-prod-api-migration --project=google-project-id --region=europe-west6
1656
+ - gcloud run jobs executions list --project=google-project-id --region=europe-west6 --job pan-test-app-prod-api-send-reminders --format="value(name)" | xargs -I {} gcloud run jobs executions delete {} --quiet --project=google-project-id --region=europe-west6
1657
+ - gcloud run jobs delete pan-test-app-prod-api-send-reminders --project=google-project-id --region=europe-west6
1658
+ - gcloud artifacts docker images delete europe-west6-docker.pkg.dev/google-project-id/catladder-deploy/pan-test-app/prod/api --quiet --delete-tags
1659
+ - 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
1660
+ - echo 'Disabling component in Dependency Track'
1661
+ - /dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "pan-test-app/api" "$CI_ENVIRONMENT_URL" || true
1662
+ - set -e
1663
+ environment:
1664
+ name: prod/api
1665
+ action: stop
1666
+ rules:
1667
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/
1668
+ when: on_success
1669
+ - when: manual
1670
+ if: $CI_COMMIT_TAG
1671
+ needs: []
1672
+ retry: *a1
1673
+ interruptible: true
1674
+ allow_failure: true
1675
+ create release:
1676
+ stage: release
1677
+ image: path/to/docker/semantic-release:the-version
1678
+ script:
1679
+ - semanticRelease
1680
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1681
+ rules:
1682
+ - &a2
1683
+ if: $CI_COMMIT_MESSAGE =~ /^chore\\(release\\).*/
1684
+ when: never
1685
+ - &a3
1686
+ if: $CI_PIPELINE_SOURCE == "schedule"
1687
+ when: never
1688
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $AUTO_RELEASE == "true"
1689
+ when: on_success
1690
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1691
+ when: manual
1692
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1693
+ when: manual
1694
+ โš ๏ธ force create release:
1695
+ stage: release
1696
+ image: path/to/docker/semantic-release:the-version
1697
+ script:
1698
+ - semanticRelease
1699
+ - echo '๐Ÿ‘‰ The project access token might be invald - run \`project-renew-token\` in catladder CLI to fix.'
1700
+ rules:
1701
+ - *a2
1702
+ - *a3
1703
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
1704
+ when: manual
1705
+ - if: $CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/
1706
+ when: manual
1707
+ needs: []
1708
+ "
1709
+ `;