@catladder/pipeline 0.0.0-more-collapse-deeb54d7 โ†’ 0.0.0-multiple-gitlab-includes-1a40efc0

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