@catladder/pipeline 0.0.0-node16-ddfae617 → 0.0.0-prettier-cbceeed9

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 (275) hide show
  1. package/bin/catladder-gitlab-dev.js +3 -0
  2. package/bin/catladder-gitlab.js +1 -1
  3. package/dist/build/base/createBuildJob.d.ts +2 -2
  4. package/dist/build/base/createBuildJob.js +15 -30
  5. package/dist/build/base/writeBuildInfo.d.ts +2 -0
  6. package/dist/build/base/{getBuildInfo.js → writeBuildInfo.js} +3 -6
  7. package/dist/build/custom/buildJob.d.ts +3 -0
  8. package/dist/build/custom/buildJob.js +83 -0
  9. package/dist/build/custom/index.d.ts +3 -0
  10. package/dist/build/custom/index.js +40 -0
  11. package/dist/build/docker.d.ts +33 -9
  12. package/dist/build/docker.js +51 -54
  13. package/dist/build/index.d.ts +6 -5
  14. package/dist/build/index.js +20 -6
  15. package/dist/build/node/buildJob.d.ts +2 -2
  16. package/dist/build/node/buildJob.js +3 -25
  17. package/dist/build/node/cache.d.ts +2 -2
  18. package/dist/build/node/cache.js +19 -22
  19. package/dist/build/node/index.d.ts +1 -1
  20. package/dist/build/node/index.js +3 -16
  21. package/dist/build/node/meteor.d.ts +1 -1
  22. package/dist/build/node/meteor.js +9 -20
  23. package/dist/build/node/testJob.d.ts +2 -2
  24. package/dist/build/node/testJob.js +7 -21
  25. package/dist/build/node/yarn.d.ts +1 -1
  26. package/dist/build/node/yarn.js +14 -15
  27. package/dist/build/rails/build.d.ts +3 -0
  28. package/dist/build/rails/build.js +51 -0
  29. package/dist/build/rails/index.d.ts +3 -0
  30. package/dist/build/rails/index.js +41 -0
  31. package/dist/build/rails/test.d.ts +3 -0
  32. package/dist/build/rails/test.js +94 -0
  33. package/dist/build/types.d.ts +84 -9
  34. package/dist/build/types.js +0 -4
  35. package/dist/bundles/catladder-gitlab/index.js +32979 -0
  36. package/dist/catladder-gitlab.js +7 -26
  37. package/dist/config/{configruedEnvs.test.d.ts → __tests__/configruedEnvs.test.d.ts} +0 -0
  38. package/dist/config/{configruedEnvs.test.js → __tests__/configruedEnvs.test.js} +10 -12
  39. package/dist/config/configruedEnvs.d.ts +1 -1
  40. package/dist/config/configruedEnvs.js +7 -22
  41. package/dist/config/index.js +0 -4
  42. package/dist/config/readConfig.d.ts +1 -1
  43. package/dist/config/readConfig.js +2 -13
  44. package/dist/constants.js +1 -1
  45. package/dist/context/{resolveReferences.test.d.ts → __tests__/resolveReferences.test.d.ts} +0 -0
  46. package/dist/context/__tests__/resolveReferences.test.js +336 -0
  47. package/dist/context/getEnvConfig.d.ts +2 -0
  48. package/dist/context/getEnvConfig.js +18 -0
  49. package/dist/context/getEnvType.d.ts +4 -0
  50. package/dist/context/getEnvType.js +13 -0
  51. package/dist/context/getEnvironment.d.ts +3 -0
  52. package/dist/{pipeline/createChildPipeline.test.js → context/getEnvironment.js} +42 -84
  53. package/dist/context/getEnvironmentContext.d.ts +4 -0
  54. package/dist/context/getEnvironmentContext.js +33 -0
  55. package/dist/context/getEnvironmentVariables.d.ts +10 -0
  56. package/dist/context/getEnvironmentVariables.js +260 -0
  57. package/dist/context/getLabels.d.ts +8 -0
  58. package/dist/context/getLabels.js +38 -0
  59. package/dist/context/index.d.ts +5 -6
  60. package/dist/context/index.js +158 -208
  61. package/dist/context/resolveReferences.d.ts +1 -3
  62. package/dist/context/resolveReferences.js +213 -52
  63. package/dist/defaults/index.d.ts +1 -1
  64. package/dist/deploy/base.d.ts +4 -2
  65. package/dist/deploy/base.js +38 -33
  66. package/dist/deploy/cloudRun/deployJob.d.ts +3 -0
  67. package/dist/deploy/cloudRun/deployJob.js +238 -0
  68. package/dist/deploy/cloudRun/index.d.ts +4 -0
  69. package/dist/deploy/cloudRun/index.js +112 -0
  70. package/dist/deploy/cloudRun/utils/createArgsString.d.ts +11 -0
  71. package/dist/deploy/cloudRun/utils/createArgsString.js +55 -0
  72. package/dist/deploy/cloudRun/utils/database.d.ts +4 -0
  73. package/dist/deploy/cloudRun/utils/database.js +64 -0
  74. package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.d.ts +2 -0
  75. package/dist/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.js +10 -0
  76. package/dist/deploy/cloudRun/utils/jobName.d.ts +1 -0
  77. package/dist/deploy/cloudRun/utils/jobName.js +8 -0
  78. package/dist/deploy/custom/deployJob.d.ts +2 -2
  79. package/dist/deploy/custom/deployJob.js +10 -16
  80. package/dist/deploy/custom/index.d.ts +2 -1
  81. package/dist/deploy/custom/index.js +14 -19
  82. package/dist/deploy/dockerTag/deployJob.d.ts +3 -0
  83. package/dist/deploy/dockerTag/deployJob.js +24 -0
  84. package/dist/deploy/dockerTag/index.d.ts +2 -0
  85. package/dist/deploy/dockerTag/index.js +17 -0
  86. package/dist/deploy/index.d.ts +12 -8
  87. package/dist/deploy/index.js +7 -20
  88. package/dist/deploy/kubernetes/additionalSecretKeys.d.ts +4 -0
  89. package/dist/deploy/kubernetes/additionalSecretKeys.js +24 -0
  90. package/dist/deploy/kubernetes/cloudSql/index.d.ts +13 -0
  91. package/dist/deploy/kubernetes/cloudSql/index.js +30 -0
  92. package/dist/deploy/kubernetes/deployJob.d.ts +2 -2
  93. package/dist/deploy/kubernetes/deployJob.js +17 -91
  94. package/dist/deploy/kubernetes/index.d.ts +3 -1
  95. package/dist/deploy/kubernetes/index.js +42 -4
  96. package/dist/deploy/kubernetes/kubeEnv.d.ts +9 -0
  97. package/dist/deploy/kubernetes/kubeEnv.js +72 -0
  98. package/dist/deploy/kubernetes/kubeValues.d.ts +97 -0
  99. package/dist/deploy/kubernetes/kubeValues.js +124 -0
  100. package/dist/deploy/kubernetes/mongodb.d.ts +18 -5
  101. package/dist/deploy/kubernetes/mongodb.js +96 -10
  102. package/dist/deploy/kubernetes/processSecretsAsFiles.d.ts +25 -21
  103. package/dist/deploy/kubernetes/processSecretsAsFiles.js +2 -10
  104. package/dist/deploy/types/base.d.ts +14 -0
  105. package/dist/deploy/types/base.js +3 -0
  106. package/dist/deploy/types/custom.d.ts +33 -0
  107. package/dist/deploy/types/custom.js +3 -0
  108. package/dist/deploy/types/dockerTag.d.ts +10 -0
  109. package/dist/deploy/types/dockerTag.js +3 -0
  110. package/dist/deploy/types/googleCloudRun.d.ts +121 -0
  111. package/dist/deploy/types/googleCloudRun.js +3 -0
  112. package/dist/deploy/types/index.d.ts +22 -0
  113. package/dist/deploy/types/index.js +31 -0
  114. package/dist/deploy/types/kubernetes.d.ts +276 -0
  115. package/dist/deploy/types/kubernetes.js +3 -0
  116. package/dist/deploy/utils.d.ts +2 -2
  117. package/dist/deploy/utils.js +3 -10
  118. package/dist/index.js +0 -10
  119. package/dist/pipeline/commitInfo/getBuildId.d.ts +1 -0
  120. package/dist/pipeline/commitInfo/getBuildId.js +135 -0
  121. package/dist/pipeline/commitInfo/getCommitInfo.d.ts +2 -0
  122. package/dist/pipeline/commitInfo/getCommitInfo.js +140 -0
  123. package/dist/pipeline/createAllJobs.d.ts +8 -0
  124. package/dist/{build/tests/storybook.test.js → pipeline/createAllJobs.js} +54 -104
  125. package/dist/pipeline/createChildPipeline.d.ts +2 -2
  126. package/dist/pipeline/createChildPipeline.js +40 -121
  127. package/dist/pipeline/createJobsForComponent.d.ts +3 -0
  128. package/dist/pipeline/{createJobs.js → createJobsForComponent.js} +33 -192
  129. package/dist/pipeline/gitlab/createGitlabJobs.d.ts +14 -0
  130. package/dist/pipeline/gitlab/createGitlabJobs.js +260 -0
  131. package/dist/pipeline/index.d.ts +1 -1
  132. package/dist/pipeline/index.js +1 -5
  133. package/dist/pipeline/packageManager.d.ts +1 -1
  134. package/dist/pipeline/packageManager.js +20 -173
  135. package/dist/pipeline/yarn/yarnUtils.d.ts +4 -0
  136. package/dist/pipeline/yarn/yarnUtils.js +193 -0
  137. package/dist/rules/index.d.ts +3 -1
  138. package/dist/rules/index.js +7 -6
  139. package/dist/runner/index.d.ts +2 -3
  140. package/dist/runner/index.js +0 -3
  141. package/dist/tsconfig.tsbuildinfo +1 -1
  142. package/dist/types/config.d.ts +19 -25
  143. package/dist/types/config.js +6 -16
  144. package/dist/types/context.d.ts +16 -3
  145. package/dist/types/environmentContext.d.ts +28 -0
  146. package/dist/types/environmentContext.js +3 -0
  147. package/dist/types/gitlab-types.d.ts +39 -7
  148. package/dist/types/index.js +0 -6
  149. package/dist/types/jobs.d.ts +25 -17
  150. package/dist/types/jobs.js +1 -1
  151. package/dist/types/pipeline.d.ts +1 -1
  152. package/dist/types/utils.d.ts +1 -0
  153. package/dist/types/utils.js +3 -0
  154. package/dist/utils/gitlab.d.ts +5 -0
  155. package/dist/utils/gitlab.js +48 -0
  156. package/dist/utils/index.js +5 -15
  157. package/examples/__snapshots__/cloud-run-memory-limit.ts.snap +1560 -0
  158. package/examples/__snapshots__/cloud-run-no-cpu-throttling.ts.snap +1560 -0
  159. package/examples/__snapshots__/cloud-run-non-public.ts.snap +1560 -0
  160. package/examples/__snapshots__/cloud-run-with-sql-reuse-db.ts.snap +3092 -0
  161. package/examples/__snapshots__/cloud-run-with-sql.ts.snap +3103 -0
  162. package/examples/__snapshots__/custom-build-job.ts.snap +1162 -0
  163. package/examples/__snapshots__/custom-envs.ts.snap +261 -0
  164. package/examples/__snapshots__/kubernetes-application-customization.ts.snap +2280 -0
  165. package/examples/__snapshots__/kubernetes-with-jobs.ts.snap +4077 -0
  166. package/examples/__snapshots__/rails-k8s-with-worker.ts.snap +1911 -0
  167. package/examples/__snapshots__/wait-for-other-deploy.ts.snap +1626 -0
  168. package/examples/__utils__/helpers.ts +14 -0
  169. package/examples/cloud-run-memory-limit.ts +28 -0
  170. package/examples/cloud-run-no-cpu-throttling.ts +33 -0
  171. package/examples/cloud-run-non-public.ts +27 -0
  172. package/examples/cloud-run-with-sql-reuse-db.ts +54 -0
  173. package/examples/cloud-run-with-sql.ts +61 -0
  174. package/examples/custom-build-job.ts +28 -0
  175. package/examples/custom-envs.ts +31 -0
  176. package/examples/kubernetes-application-customization.ts +57 -0
  177. package/examples/kubernetes-with-jobs.ts +68 -0
  178. package/examples/rails-k8s-with-worker.ts +95 -0
  179. package/examples/wait-for-other-deploy.ts +36 -0
  180. package/package.json +16 -13
  181. package/scripts/bundle +2 -0
  182. package/src/build/base/createBuildJob.ts +12 -5
  183. package/src/build/base/{getBuildInfo.ts → writeBuildInfo.ts} +2 -2
  184. package/src/build/custom/buildJob.ts +64 -0
  185. package/src/build/custom/index.ts +7 -0
  186. package/src/build/docker.ts +58 -33
  187. package/src/build/index.ts +24 -5
  188. package/src/build/node/buildJob.ts +2 -2
  189. package/src/build/node/cache.ts +19 -8
  190. package/src/build/node/index.ts +1 -1
  191. package/src/build/node/meteor.ts +8 -2
  192. package/src/build/node/testJob.ts +4 -2
  193. package/src/build/node/yarn.ts +21 -10
  194. package/src/build/rails/build.ts +38 -0
  195. package/src/build/rails/index.ts +8 -0
  196. package/src/build/rails/test.ts +86 -0
  197. package/src/build/types.ts +97 -2
  198. package/src/catladder-gitlab.ts +4 -2
  199. package/src/config/{configruedEnvs.test.ts → __tests__/configruedEnvs.test.ts} +3 -3
  200. package/src/config/configruedEnvs.ts +2 -7
  201. package/src/config/readConfig.ts +1 -1
  202. package/src/context/{resolveReferences.test.ts → __tests__/resolveReferences.test.ts} +23 -38
  203. package/src/context/getEnvConfig.ts +21 -0
  204. package/src/context/getEnvType.ts +17 -0
  205. package/src/context/getEnvironment.ts +40 -0
  206. package/src/context/getEnvironmentContext.ts +57 -0
  207. package/src/context/getEnvironmentVariables.ts +155 -0
  208. package/src/context/getLabels.ts +20 -0
  209. package/src/context/index.ts +28 -193
  210. package/src/context/resolveReferences.ts +35 -31
  211. package/src/defaults/index.ts +1 -1
  212. package/src/deploy/base.ts +43 -19
  213. package/src/deploy/cloudRun/deployJob.ts +276 -0
  214. package/src/deploy/cloudRun/index.ts +95 -0
  215. package/src/deploy/cloudRun/utils/createArgsString.ts +26 -0
  216. package/src/deploy/cloudRun/utils/database.ts +55 -0
  217. package/src/deploy/cloudRun/utils/gcloudServiceAccountLoginCommands.ts +14 -0
  218. package/src/deploy/cloudRun/utils/jobName.ts +2 -0
  219. package/src/deploy/custom/deployJob.ts +13 -3
  220. package/src/deploy/custom/index.ts +9 -1
  221. package/src/deploy/dockerTag/deployJob.ts +31 -0
  222. package/src/deploy/dockerTag/index.ts +9 -0
  223. package/src/deploy/index.ts +26 -17
  224. package/src/deploy/kubernetes/additionalSecretKeys.ts +23 -0
  225. package/src/deploy/kubernetes/cloudSql/index.ts +28 -0
  226. package/src/deploy/kubernetes/deployJob.ts +21 -78
  227. package/src/deploy/kubernetes/index.ts +42 -1
  228. package/src/deploy/kubernetes/kubeEnv.ts +48 -0
  229. package/src/deploy/kubernetes/kubeValues.ts +96 -0
  230. package/src/deploy/kubernetes/mongodb.ts +104 -7
  231. package/src/deploy/kubernetes/processSecretsAsFiles.ts +1 -1
  232. package/src/deploy/types/base.ts +17 -0
  233. package/src/deploy/types/custom.ts +36 -0
  234. package/src/deploy/types/dockerTag.ts +12 -0
  235. package/src/deploy/types/googleCloudRun.ts +179 -0
  236. package/src/deploy/types/index.ts +28 -0
  237. package/src/deploy/types/kubernetes.ts +301 -0
  238. package/src/deploy/utils.ts +6 -2
  239. package/src/pipeline/commitInfo/getBuildId.ts +6 -0
  240. package/src/pipeline/commitInfo/getCommitInfo.ts +12 -0
  241. package/src/pipeline/createAllJobs.ts +38 -0
  242. package/src/pipeline/createChildPipeline.ts +9 -20
  243. package/src/pipeline/createJobsForComponent.ts +64 -0
  244. package/src/pipeline/gitlab/createGitlabJobs.ts +149 -0
  245. package/src/pipeline/index.ts +1 -1
  246. package/src/pipeline/packageManager.ts +4 -38
  247. package/src/pipeline/yarn/yarnUtils.ts +37 -0
  248. package/src/rules/index.ts +9 -6
  249. package/src/runner/index.ts +2 -1
  250. package/src/types/config.ts +26 -13
  251. package/src/types/context.ts +23 -2
  252. package/src/types/environmentContext.ts +33 -0
  253. package/src/types/gitlab-types.ts +36 -6
  254. package/src/types/jobs.ts +30 -6
  255. package/src/types/pipeline.ts +1 -1
  256. package/src/types/utils.ts +7 -0
  257. package/src/utils/gitlab.ts +23 -0
  258. package/tsconfig.json +3 -1
  259. package/dist/build/base/getBuildInfo.d.ts +0 -2
  260. package/dist/build/tests/storybook.test.d.ts +0 -1
  261. package/dist/context/resolveReferences.test.js +0 -141
  262. package/dist/deploy/kubernetes/cloudsql.d.ts +0 -6
  263. package/dist/deploy/kubernetes/cloudsql.js +0 -16
  264. package/dist/deploy/types.d.ts +0 -196
  265. package/dist/deploy/types.js +0 -16
  266. package/dist/pipeline/createChildPipeline.test.d.ts +0 -1
  267. package/dist/pipeline/createJobs.d.ts +0 -3
  268. package/dist/pipeline/gitlab/makeGitlabJob.d.ts +0 -8
  269. package/dist/pipeline/gitlab/makeGitlabJob.js +0 -45
  270. package/src/build/tests/storybook.test.ts +0 -54
  271. package/src/deploy/kubernetes/cloudsql.ts +0 -12
  272. package/src/deploy/types.ts +0 -189
  273. package/src/pipeline/createChildPipeline.test.ts +0 -49
  274. package/src/pipeline/createJobs.ts +0 -195
  275. package/src/pipeline/gitlab/makeGitlabJob.ts +0 -16
@@ -0,0 +1,276 @@
1
+ import { dump } from "js-yaml";
2
+ import { isNil, merge, omit } from "lodash";
3
+ import { GCLOUD_DEPLOY_CREDENTIALS_KEY } from ".";
4
+ import { getDockerJobBaseProps, gitlabDockerLogin } from "../../build/docker";
5
+ import { getLabels } from "../../context/getLabels";
6
+ import { getRunnerImage } from "../../runner";
7
+ import type { Context } from "../../types/context";
8
+ import type { CatladderJob } from "../../types/jobs";
9
+ import { getBaseDeploymentJob, getBaseDeploymentStopJob } from "../base";
10
+ import type {
11
+ DeployConfigCloudRun,
12
+ DeployConfigCloudRunJob,
13
+ DeployConfigCloudRunJobWithSchedule,
14
+ DeployConfigCloudRunService,
15
+ } from "../types";
16
+ import { isOfDeployType } from "../types";
17
+ import { gcloudServiceAccountLoginCommands } from "./utils/gcloudServiceAccountLoginCommands";
18
+ import {
19
+ getDatabaseCreateScript,
20
+ getDatabaseDeleteScript,
21
+ } from "./utils/database";
22
+ import { allowFailureInScripts } from "../../utils/gitlab";
23
+ import { getCloudRunJobName } from "./utils/jobName";
24
+ import { createArgsString } from "./utils/createArgsString";
25
+
26
+ const setExtraVarsScripts = (deployConfig: DeployConfigCloudRun) => [
27
+ `export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe ${deployConfig.projectId} --format="value(projectNumber)")`,
28
+ `echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"`,
29
+ ];
30
+
31
+ export const createGoogleCloudRunDeployJobs = (
32
+ context: Context
33
+ ): CatladderJob[] => {
34
+ const deployConfig = context.componentConfig.deploy;
35
+ if (deployConfig === false) {
36
+ return [];
37
+ }
38
+ if (!isOfDeployType(deployConfig, "google-cloudrun")) {
39
+ // should not happen
40
+ throw new Error("deploy config is wrong");
41
+ }
42
+ const baseDeploymentJob = getBaseDeploymentJob(context);
43
+
44
+ const fullAppName = `${context.fullConfig.customerName}-${context.fullConfig.appName}`;
45
+ const dockerUrl = `${deployConfig.region}-docker.pkg.dev/${deployConfig.projectId}/catladder-deploy/${fullAppName}`;
46
+ const gcloudImageName = `${dockerUrl}/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG`;
47
+
48
+ const pushImageToArtifactsRegistry = [
49
+ gitlabDockerLogin,
50
+ `gcloud auth configure-docker ${deployConfig.region}-docker.pkg.dev`,
51
+ `docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
52
+ `docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG ${gcloudImageName}`,
53
+ `docker push ${gcloudImageName}`,
54
+ ];
55
+
56
+ const allEnvVars = omit(
57
+ context.environment.envVars,
58
+ GCLOUD_DEPLOY_CREDENTIALS_KEY
59
+ );
60
+
61
+ const labelsString = Object.entries(getLabels(context))
62
+ .map(([key, value]) => `${key}=${value}`)
63
+ .join(",");
64
+
65
+ const commonArgs = {
66
+ project: deployConfig.projectId,
67
+ region: deployConfig.region,
68
+ };
69
+
70
+ const commonDeployArgs = {
71
+ image: gcloudImageName,
72
+ ...commonArgs,
73
+ "set-cloudsql-instances": deployConfig.cloudSql
74
+ ? deployConfig.cloudSql.instanceConnectionName
75
+ : undefined,
76
+ labels: labelsString,
77
+ };
78
+
79
+ const serviceName = context.environment.fullName.toLowerCase();
80
+
81
+ const getFullJobName = (name: string) =>
82
+ getCloudRunJobName(context.environment.fullName, name);
83
+
84
+ const jobsWithNames = Object.entries(deployConfig.jobs ?? {})
85
+ // filter out disabled jobs
86
+ .filter((entry): entry is [string, DeployConfigCloudRunJob] =>
87
+ Boolean(entry[1])
88
+ )
89
+ .map(([name, job]) => ({
90
+ jobName: getFullJobName(name),
91
+ job,
92
+ }));
93
+ const jobsWithSchedule = jobsWithNames
94
+ .filter(
95
+ (
96
+ entry
97
+ ): entry is {
98
+ jobName: string;
99
+ job: DeployConfigCloudRunJobWithSchedule;
100
+ } => entry.job.when === "schedule"
101
+ )
102
+ .map(({ job, jobName }) => ({
103
+ job,
104
+ jobName,
105
+ schedulerName: jobName + "-scheduler",
106
+ }));
107
+
108
+ const getServiceDeployScript = (
109
+ service: DeployConfigCloudRunService | true | undefined,
110
+ nameSuffix?: string
111
+ ) => {
112
+ const customConfig = service !== true ? service : undefined;
113
+ const command =
114
+ service !== true
115
+ ? service?.command ?? context.componentConfig.build.startCommand
116
+ : undefined;
117
+
118
+ const argsString = createArgsString({
119
+ // command as empty string resets it to default (uses the image's entrypoint)
120
+ command: command ? '"' + command.split(" ").join(",") + '"' : '""',
121
+ ...commonDeployArgs,
122
+ "env-vars-file": "____envvars.yaml",
123
+ "min-instances": customConfig?.minInstances ?? 0,
124
+ "max-instances": customConfig?.maxInstances ?? 100,
125
+ "cpu-throttling": customConfig?.noCpuThrottling !== true,
126
+ memory: customConfig?.memory,
127
+ "allow-unauthenticated": customConfig?.allowUnauthenticated ?? true,
128
+ });
129
+
130
+ return `gcloud run deploy ${serviceName}${nameSuffix ?? ""} ${argsString}`;
131
+ };
132
+
133
+ const getJobCreateScriptsForJob = (
134
+ jobName: string,
135
+ job: DeployConfigCloudRunJob
136
+ ) => {
137
+ // due to some oversight from google, jobs create does not accept `--env-vars-file` 🤦
138
+ // lucky, update on the other hand accepts it... so let's just imediatly update it
139
+
140
+ // also we cannot upsert a job, so we have to create it and catch the error and then update
141
+ const commonDeployArgsString = createArgsString({
142
+ command: '"' + job.command.split(" ").join(",") + '"',
143
+ ...commonDeployArgs,
144
+ memory: job.memory || "512Mi",
145
+ });
146
+
147
+ const argsString = `${jobName} ${commonDeployArgsString}`;
148
+ return [
149
+ ...allowFailureInScripts([`gcloud beta run jobs create ${argsString}`]),
150
+ `gcloud beta run jobs update ${argsString} --env-vars-file=____envvars.yaml`,
151
+ ];
152
+ };
153
+
154
+ const commonArgsString = createArgsString(commonArgs);
155
+
156
+ const getJobCreateScripts = () =>
157
+ jobsWithNames
158
+ .map(({ job, jobName }) => getJobCreateScriptsForJob(jobName, job))
159
+ .flat();
160
+
161
+ const getJobRunScriptForJob = (jobName: string) => {
162
+ return `gcloud beta run jobs execute ${jobName} ${commonArgsString}`;
163
+ };
164
+
165
+ const getJobRunScripts = (when: DeployConfigCloudRunJob["when"]) =>
166
+ jobsWithNames
167
+ .filter(({ job }) => job.when === when)
168
+ .map(({ jobName }) => getJobRunScriptForJob(jobName));
169
+
170
+ const getCreateScheduleScripts = () => {
171
+ return jobsWithSchedule
172
+ .map(({ job, jobName, schedulerName }) => {
173
+ const argsString = createArgsString({
174
+ project: deployConfig.projectId,
175
+ location: deployConfig.region,
176
+ schedule: `"${job.schedule}"`,
177
+ uri: `"https://${deployConfig.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${deployConfig.projectId}/jobs/${jobName}:run"`,
178
+ "http-method": "POST",
179
+ "oauth-service-account-email":
180
+ "$GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com",
181
+ });
182
+ const commonArgs = `http ${schedulerName} ${argsString}`;
183
+ return [
184
+ ...allowFailureInScripts([
185
+ `gcloud scheduler jobs create ${commonArgs}`,
186
+ ]),
187
+ `gcloud scheduler jobs update ${commonArgs}`,
188
+ ];
189
+ })
190
+ .flat();
191
+ };
192
+
193
+ const getDeleteSchedulesScripts = () => {
194
+ const argsString = createArgsString({
195
+ project: deployConfig.projectId,
196
+ location: deployConfig.region,
197
+ });
198
+ return jobsWithSchedule
199
+ .map(({ schedulerName }) => {
200
+ return [
201
+ ...allowFailureInScripts([
202
+ `gcloud scheduler jobs delete ${schedulerName} ${argsString}`,
203
+ ]),
204
+ ];
205
+ })
206
+ .flat();
207
+ };
208
+
209
+ const getDeleteJobsScripts = () =>
210
+ jobsWithNames.map(
211
+ ({ jobName }) =>
212
+ `gcloud beta run jobs delete ${jobName} ${commonArgsString}`
213
+ );
214
+
215
+ const deployScripts = [
216
+ ...gcloudServiceAccountLoginCommands(context),
217
+ ...setExtraVarsScripts(deployConfig),
218
+ ...pushImageToArtifactsRegistry,
219
+ `echo "$ENV_VARS" > ____envvars.yaml`, // TODO: split secrets out
220
+ ...(deployConfig.cloudSql
221
+ ? getDatabaseCreateScript(context, deployConfig) // we create the db, so that we can also delete it afterwards
222
+ : []),
223
+ ...getCreateScheduleScripts(),
224
+ ...getJobCreateScripts(),
225
+ ...getJobRunScripts("preDeploy"),
226
+
227
+ ...(deployConfig.service !== false
228
+ ? [getServiceDeployScript(deployConfig.service)]
229
+ : []),
230
+ ...Object.entries(deployConfig.additionalServices ?? {}).map(
231
+ ([name, service]) => getServiceDeployScript(service, "-" + name)
232
+ ),
233
+ ...getJobRunScripts("postDeploy"),
234
+
235
+ `docker image rm ${gcloudImageName}`,
236
+ ];
237
+
238
+ const stopScripts = [
239
+ ...gcloudServiceAccountLoginCommands(context),
240
+ ...(deployConfig.service !== false
241
+ ? [`gcloud run services delete ${serviceName} ${commonArgsString}`]
242
+ : []),
243
+ ...Object.entries(deployConfig.additionalServices ?? {}).map(
244
+ ([name]) =>
245
+ `gcloud run services delete ${serviceName}-${name} ${commonArgsString}`
246
+ ),
247
+ ...getDeleteSchedulesScripts(),
248
+ ...getDeleteJobsScripts(),
249
+ ...(deployConfig.cloudSql && deployConfig.cloudSql.deleteDatabaseOnStop
250
+ ? getDatabaseDeleteScript(context, deployConfig)
251
+ : []),
252
+ ];
253
+ return [
254
+ merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
255
+ artifacts: { paths: ["____envvars.yaml"] },
256
+ variables: {
257
+ CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
258
+ ENV_VARS: dump(allEnvVars, {
259
+ lineWidth: -1,
260
+ quotingType: "'",
261
+ forceQuotes: true,
262
+ }),
263
+ },
264
+ image: getRunnerImage("gcloud"),
265
+ script: deployScripts,
266
+ }),
267
+
268
+ merge({}, getBaseDeploymentStopJob(context), {
269
+ image: getRunnerImage("gcloud"),
270
+ variables: {
271
+ CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
272
+ },
273
+ script: stopScripts,
274
+ }),
275
+ ];
276
+ };
@@ -0,0 +1,95 @@
1
+ import type { DeployTypeDefinition } from "..";
2
+ import { getSecretVarName } from "../../context";
3
+ import { sanitizeForBashVariable } from "../../utils/gitlab";
4
+ import type { EnvironmentContext } from "../../types/environmentContext";
5
+ import { createGoogleCloudRunDeployJobs } from "./deployJob";
6
+ import { getCloudRunJobName } from "./utils/jobName";
7
+
8
+ export const GCLOUD_DEPLOY_CREDENTIALS_KEY = "GCLOUD_DEPLOY_credentialsKey";
9
+
10
+ export const GCLOUD_RUN_CANONICAL_HOST_SUFFIX =
11
+ "GCLOUD_RUN_canonicalHostSuffix";
12
+
13
+ const getCloudSqlVariables = ({
14
+ deployConfigRaw,
15
+ environmentSlugPrefix,
16
+ env,
17
+ componentName,
18
+ fullConfig,
19
+ }: EnvironmentContext<any, "google-cloudrun">) => {
20
+ if (deployConfigRaw && deployConfigRaw.cloudSql) {
21
+ const DB_NAME = [
22
+ deployConfigRaw.cloudSql.dbNamePrefix ??
23
+ `${fullConfig.customerName}-${fullConfig.appName}`,
24
+ environmentSlugPrefix,
25
+ deployConfigRaw.cloudSql.dbBaseName ?? componentName,
26
+ ]
27
+ .filter(Boolean)
28
+ .join("-");
29
+
30
+ const additionalQueryParamsString = Object.entries(
31
+ deployConfigRaw.cloudSql.dbAdditionalQueryParams ?? {}
32
+ )
33
+ .map(([key, value]) => `&${key}=${value}`)
34
+ .join("");
35
+
36
+ return {
37
+ CLOUD_SQL_INSTANCE_CONNECTION_NAME:
38
+ deployConfigRaw.cloudSql.instanceConnectionName,
39
+ DB_NAME: DB_NAME,
40
+ DB_USER: deployConfigRaw.cloudSql.dbUser ?? "postgres",
41
+ DB_PASSWORD: "$" + getSecretVarName(env, componentName, "DB_PASSWORD"),
42
+ DATABASE_URL: `postgresql://$DB_USER:$DB_PASSWORD@localhost/$DB_NAME?host=/cloudsql/$CLOUD_SQL_INSTANCE_CONNECTION_NAME${additionalQueryParamsString}`,
43
+ 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${additionalQueryParamsString}`,
44
+ };
45
+ }
46
+ return {};
47
+ };
48
+ export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun"> = {
49
+ jobs: createGoogleCloudRunDeployJobs,
50
+ defaults: ({ deployConfigRaw, envType }) => {
51
+ if (deployConfigRaw && deployConfigRaw.cloudSql) {
52
+ return {
53
+ cloudSql: {
54
+ deleteDatabaseOnStop: envType === "review",
55
+ },
56
+ };
57
+ }
58
+ return {};
59
+ },
60
+ additionalSecretKeys: (ctx) => [
61
+ GCLOUD_DEPLOY_CREDENTIALS_KEY,
62
+ ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql
63
+ ? ["DB_PASSWORD"]
64
+ : []),
65
+ ],
66
+ getAdditionalEnvVars: (ctx) => {
67
+ const { fullName, env, componentName, deployConfigRaw } = ctx;
68
+ const HOST_CANONICAL =
69
+ fullName.toLowerCase() +
70
+ "-" +
71
+ (process.env[
72
+ getSecretVarName(env, componentName, GCLOUD_RUN_CANONICAL_HOST_SUFFIX)
73
+ ] ?? "unknown-host.example.com");
74
+
75
+ const jobTriggers =
76
+ deployConfigRaw && deployConfigRaw.jobs
77
+ ? Object.fromEntries(
78
+ Object.entries(deployConfigRaw.jobs).map(([name, job]) => [
79
+ "CLOUD_RUN_JOB_TRIGGER_URL_" + sanitizeForBashVariable(name),
80
+ `https://${
81
+ deployConfigRaw.region
82
+ }-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${
83
+ deployConfigRaw.projectId
84
+ }/jobs/${getCloudRunJobName(fullName, name)}:run`,
85
+ ])
86
+ )
87
+ : {};
88
+
89
+ return {
90
+ HOST_CANONICAL,
91
+ ...getCloudSqlVariables(ctx),
92
+ ...jobTriggers,
93
+ };
94
+ },
95
+ };
@@ -0,0 +1,26 @@
1
+ import { isNil } from "lodash";
2
+
3
+ /**
4
+ * creates arguments string:
5
+ *
6
+ * --key=value
7
+ *
8
+ * - undefined or null values will get removed completly
9
+ * - true will just be "--key"
10
+ * @param args args record
11
+ * @returns
12
+ */
13
+ export const createArgsString = (
14
+ args: Record<string, string | number | true | false | undefined>
15
+ ) =>
16
+ Object.entries(args)
17
+ .filter(([, value]) => !isNil(value))
18
+ .map(([key, value]) => {
19
+ if (value === true) {
20
+ return `--${key}`;
21
+ } else if (value === false) {
22
+ return `--no-${key}`;
23
+ }
24
+ return `--${key}=${value}`;
25
+ })
26
+ .join(" ");
@@ -0,0 +1,55 @@
1
+ import type { Context } from "../../../types";
2
+ import { allowFailureInScripts, repeatOnFailure } from "../../../utils/gitlab";
3
+ import type { DeployConfigCloudRun } from "../../types";
4
+
5
+ export const getDatabaseDeleteScript = (
6
+ context: Context,
7
+ deployConfig: DeployConfigCloudRun
8
+ ): string[] => {
9
+ if (!deployConfig.cloudSql || !deployConfig.cloudSql.deleteDatabaseOnStop) {
10
+ throw new Error("not possible");
11
+ }
12
+
13
+ const { DB_NAME } = context.environment.envVars ?? {};
14
+ if (!DB_NAME) {
15
+ throw new Error("error: env vars did not specify DB_NAME");
16
+ }
17
+
18
+ const [projectId, region, instanceId] =
19
+ deployConfig.cloudSql.instanceConnectionName.split(":");
20
+ // unfortunatly the database cannot be deleted right after the service has stopped, as it might still have connections
21
+ // we have to repeate this process
22
+ return [
23
+ `echo "deleting database ${DB_NAME}..."`,
24
+ `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"`,
25
+ repeatOnFailure(
26
+ `gcloud sql databases delete ${DB_NAME} --instance=${instanceId} --project ${projectId}`,
27
+ {
28
+ pauseInSeconds: 10,
29
+ }
30
+ ),
31
+ ];
32
+ };
33
+
34
+ export const getDatabaseCreateScript = (
35
+ context: Context,
36
+ deployConfig: DeployConfigCloudRun
37
+ ): string[] => {
38
+ if (!deployConfig.cloudSql) {
39
+ throw new Error("not possible");
40
+ }
41
+
42
+ const { DB_NAME } = context.environment.envVars ?? {};
43
+
44
+ if (!DB_NAME) {
45
+ throw new Error("error: env vars did not specify DB_NAME");
46
+ }
47
+
48
+ const [projectId, region, instanceId] =
49
+ deployConfig.cloudSql.instanceConnectionName.split(":");
50
+ // may fail if it already exists
51
+ return allowFailureInScripts([
52
+ `echo "ensuring Database..."`,
53
+ `gcloud sql databases create ${DB_NAME} --instance=${instanceId} --project ${projectId}`,
54
+ ]);
55
+ };
@@ -0,0 +1,14 @@
1
+ import { GCLOUD_DEPLOY_CREDENTIALS_KEY } from "..";
2
+ import { getSecretVarNameForContext } from "../../../context";
3
+ import type { Context } from "../../../types";
4
+
5
+ export const gcloudServiceAccountLoginCommands = (context: Context) => {
6
+ return [
7
+ `echo $${getSecretVarNameForContext(
8
+ context,
9
+ GCLOUD_DEPLOY_CREDENTIALS_KEY
10
+ )} > ./____keyfile.json
11
+ `,
12
+ `gcloud auth activate-service-account --key-file="./____keyfile.json"`,
13
+ ];
14
+ };
@@ -0,0 +1,2 @@
1
+ export const getCloudRunJobName = (fullAppName: string, jobName: string) =>
2
+ fullAppName.toLowerCase() + "-" + jobName.toLowerCase();
@@ -1,6 +1,9 @@
1
1
  import { merge } from "lodash";
2
- import { Context } from "../../types/context";
3
- import { CatladderJob } from "../../types/jobs";
2
+
3
+ import { getYarnInstall } from "../../build/node/yarn";
4
+ import { getRunnerImage } from "../../runner";
5
+ import type { Context } from "../../types/context";
6
+ import type { CatladderJob } from "../../types/jobs";
4
7
  import { getBaseDeploymentJob } from "../base";
5
8
  import { isOfDeployType } from "../types";
6
9
 
@@ -15,9 +18,16 @@ export const createCustomDeployJobs = (context: Context): CatladderJob[] => {
15
18
  }
16
19
  const baseDeploymentJob = getBaseDeploymentJob(context);
17
20
 
21
+ const yarnInstall = getYarnInstall(context);
18
22
  return [
19
23
  merge({}, baseDeploymentJob, {
20
- script: [`cd ${context.componentConfig.dir}`, ...deployConfig.script],
24
+ image: deployConfig.jobImage ?? getRunnerImage("jobs-default"),
25
+ cache: deployConfig.jobCache ?? [],
26
+ script: [
27
+ `cd ${context.componentConfig.dir}`,
28
+ ...(deployConfig.requiresYarnInstall ? yarnInstall : []),
29
+ ...deployConfig.script,
30
+ ],
21
31
  }),
22
32
  ];
23
33
  };
@@ -1 +1,9 @@
1
- export * from "./deployJob";
1
+ import type { DeployTypeDefinition } from "..";
2
+ import { createCustomDeployJobs } from "./deployJob";
3
+
4
+ export const CUSTOM_DEPLOY_TYPE: DeployTypeDefinition<"custom"> = {
5
+ jobs: createCustomDeployJobs,
6
+ defaults: () => ({}),
7
+ additionalSecretKeys: () => [],
8
+ getAdditionalEnvVars: () => ({}),
9
+ };
@@ -0,0 +1,31 @@
1
+ import { merge } from "lodash";
2
+ import { getDockerJobBaseProps, gitlabDockerLogin } from "../../build/docker";
3
+
4
+ import type { Context } from "../../types/context";
5
+ import type { CatladderJob } from "../../types/jobs";
6
+ import { getBaseDeploymentJob } from "../base";
7
+ import { isOfDeployType } from "../types";
8
+
9
+ export const createDockerTagDeployJobs = (context: Context): CatladderJob[] => {
10
+ const deployConfig = context.componentConfig.deploy;
11
+ if (deployConfig === false) {
12
+ return [];
13
+ }
14
+ if (!isOfDeployType(deployConfig, "dockerTag")) {
15
+ // should not happen
16
+ throw new Error("deploy config is not dockerTag");
17
+ }
18
+ const baseDeploymentJob = getBaseDeploymentJob(context);
19
+ const tag = deployConfig.tag;
20
+ return [
21
+ merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
22
+ script: [
23
+ gitlabDockerLogin,
24
+ `docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
25
+ `docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG $DOCKER_IMAGE:${tag}`,
26
+ `docker push $DOCKER_IMAGE:${tag}`,
27
+ `echo "pushed as $DOCKER_IMAGE:${tag}"`,
28
+ ],
29
+ }),
30
+ ];
31
+ };
@@ -0,0 +1,9 @@
1
+ import type { DeployTypeDefinition } from "..";
2
+ import { createDockerTagDeployJobs } from "./deployJob";
3
+
4
+ export const DOCKER_TAG_DEPLOY_TYPE: DeployTypeDefinition<"dockerTag"> = {
5
+ jobs: createDockerTagDeployJobs,
6
+ defaults: () => ({}),
7
+ additionalSecretKeys: () => [],
8
+ getAdditionalEnvVars: () => ({}),
9
+ };
@@ -1,25 +1,34 @@
1
- import { Context } from "../types/context";
2
- import { CatladderJob } from "../types/jobs";
3
- import { createCustomDeployJobs } from "./custom";
4
- import { createKubernetesDeployJobs } from "./kubernetes";
5
- import { DeployConfig } from "./types";
1
+ import type { Context } from "../types/context";
2
+ import type { EnvironmentContext } from "../types/environmentContext";
3
+ import type { CatladderJob } from "../types/jobs";
4
+ import type { PartialDeep } from "../types/utils";
5
+ import { GCLOUD_RUN_DEPLOY_TYPE } from "./cloudRun";
6
+ import { CUSTOM_DEPLOY_TYPE } from "./custom";
7
+ import { DOCKER_TAG_DEPLOY_TYPE } from "./dockerTag";
8
+ import { KUBERNETES_DEPLOY_TYPE } from "./kubernetes";
9
+ import type { DeployConfigGeneric, DeployConfigType } from "./types";
10
+ export * from "./cloudRun";
6
11
  export * from "./kubernetes";
7
12
  export * from "./types";
8
13
  export * from "./utils";
14
+
15
+ export type DeployTypeDefinition<T extends DeployConfigType> = {
16
+ jobs: (context: Context) => CatladderJob[];
17
+ defaults: (
18
+ envContext: EnvironmentContext<any, T>
19
+ ) => PartialDeep<DeployConfigGeneric<T>>;
20
+ additionalSecretKeys: (envContext: EnvironmentContext<any, T>) => string[];
21
+ getAdditionalEnvVars: (
22
+ envContext: EnvironmentContext<any, T>
23
+ ) => Record<string, string | undefined | null>;
24
+ };
9
25
  export type DeployTypes = {
10
- [type in DeployConfig["type"]]: {
11
- jobs: (context: Context) => CatladderJob[];
12
- defaults: () => Partial<Extract<DeployConfig, { type: type }>>;
13
- };
26
+ [T in DeployConfigType]: DeployTypeDefinition<T>;
14
27
  };
15
28
 
16
29
  export const DEPLOY_TYPES: DeployTypes = {
17
- kubernetes: {
18
- jobs: createKubernetesDeployJobs,
19
- defaults: () => ({}),
20
- },
21
- custom: {
22
- jobs: createCustomDeployJobs,
23
- defaults: () => ({}),
24
- },
30
+ kubernetes: KUBERNETES_DEPLOY_TYPE,
31
+ custom: CUSTOM_DEPLOY_TYPE,
32
+ dockerTag: DOCKER_TAG_DEPLOY_TYPE,
33
+ "google-cloudrun": GCLOUD_RUN_DEPLOY_TYPE,
25
34
  };
@@ -0,0 +1,23 @@
1
+ import type { EnvironmentContext } from "../../types/environmentContext";
2
+
3
+ export const additionalKubernetesSecretKeys = ({
4
+ deployConfigRaw,
5
+ }: EnvironmentContext<any, "kubernetes">) => {
6
+ if (!deployConfigRaw) {
7
+ return [];
8
+ }
9
+ const keys = [];
10
+ if (deployConfigRaw.values?.mongodb?.enabled) {
11
+ keys.push("MONGODB_ROOT_PASSWORD");
12
+ if (deployConfigRaw.values.mongodb.architecture === "replicaset") {
13
+ keys.push("MONGODB_REPLICASET_KEY");
14
+ }
15
+ }
16
+
17
+ if (deployConfigRaw.values?.cloudsql?.enabled) {
18
+ keys.push("POSTGRESQL_PASSWORD");
19
+ keys.push("cloudsqlProxyCredentials");
20
+ }
21
+
22
+ return keys;
23
+ };
@@ -0,0 +1,28 @@
1
+ import { getSecretVarNameForContext } from "../../../context";
2
+ import type { Context } from "../../../types";
3
+ import { isOfDeployType } from "../../types";
4
+
5
+ export const hasKubernetesCloudSQL = (context: Context) => {
6
+ if (isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
7
+ return context.componentConfig.deploy.values?.cloudsql?.enabled;
8
+ }
9
+ return false;
10
+ };
11
+
12
+ export const getKubernetesCloudSQLConfig = (context: Context) => {
13
+ if (isOfDeployType(context.componentConfig.deploy, "kubernetes")) {
14
+ return context.componentConfig.deploy.values?.cloudsql;
15
+ }
16
+ throw new Error("cannot get cloud sql config");
17
+ };
18
+
19
+ export const createCloudsqlBaseConfig = (context: Context) => {
20
+ return {
21
+ cloudsql: {
22
+ proxyCredentials: `$${getSecretVarNameForContext(
23
+ context,
24
+ "cloudsqlProxyCredentials"
25
+ )}`,
26
+ },
27
+ };
28
+ };