@catladder/pipeline 0.0.7 → 1.0.2

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 (211) hide show
  1. package/babel-inline.json +11 -0
  2. package/bin/catladder-gitlab.js +3 -0
  3. package/dist/build/base/constants.d.ts +7 -0
  4. package/dist/build/base/constants.js +11 -0
  5. package/dist/build/base/createBuildJob.d.ts +5 -0
  6. package/dist/build/base/createBuildJob.js +99 -0
  7. package/dist/build/docker.d.ts +5 -0
  8. package/dist/build/docker.js +95 -0
  9. package/dist/build/index.d.ts +12 -0
  10. package/dist/build/index.js +63 -0
  11. package/dist/build/node/buildJob.d.ts +3 -0
  12. package/dist/build/node/buildJob.js +97 -0
  13. package/dist/build/node/cache.d.ts +4 -0
  14. package/dist/build/node/cache.js +67 -0
  15. package/dist/build/node/constants.d.ts +6 -0
  16. package/dist/build/node/constants.js +10 -0
  17. package/dist/build/node/index.d.ts +5 -0
  18. package/dist/build/node/index.js +63 -0
  19. package/dist/build/node/meteor.d.ts +3 -0
  20. package/dist/build/node/meteor.js +103 -0
  21. package/dist/build/node/testJob.d.ts +3 -0
  22. package/dist/build/node/testJob.js +112 -0
  23. package/dist/build/node/yarn.d.ts +2 -0
  24. package/dist/build/node/yarn.js +12 -0
  25. package/dist/build/tests/storybook.test.d.ts +1 -0
  26. package/dist/build/tests/storybook.test.js +221 -0
  27. package/dist/build/types.d.ts +63 -0
  28. package/dist/build/types.js +16 -0
  29. package/dist/catladder-gitlab.d.ts +1 -0
  30. package/dist/catladder-gitlab.js +44 -0
  31. package/dist/config/configruedEnvs.d.ts +4 -0
  32. package/dist/config/configruedEnvs.js +86 -0
  33. package/dist/config/configruedEnvs.test.d.ts +1 -0
  34. package/dist/config/configruedEnvs.test.js +103 -0
  35. package/dist/config/index.d.ts +2 -0
  36. package/dist/config/index.js +24 -0
  37. package/dist/config/readConfig.d.ts +2 -0
  38. package/dist/config/readConfig.js +47 -0
  39. package/dist/constants.d.ts +2 -0
  40. package/dist/constants.js +6 -0
  41. package/dist/context/index.d.ts +5 -0
  42. package/dist/context/index.js +211 -0
  43. package/dist/defaults/index.d.ts +2 -0
  44. package/dist/defaults/index.js +8 -0
  45. package/dist/deploy/base.d.ts +9 -0
  46. package/dist/deploy/base.js +94 -0
  47. package/dist/deploy/index.d.ts +11 -0
  48. package/dist/deploy/index.js +34 -0
  49. package/dist/deploy/kubernetes/cloudsql.d.ts +6 -0
  50. package/dist/deploy/kubernetes/cloudsql.js +16 -0
  51. package/dist/deploy/kubernetes/deployJob.d.ts +3 -0
  52. package/dist/deploy/kubernetes/deployJob.js +148 -0
  53. package/dist/deploy/kubernetes/index.d.ts +1 -0
  54. package/dist/deploy/kubernetes/index.js +22 -0
  55. package/dist/deploy/kubernetes/mongodb.d.ts +15 -0
  56. package/dist/deploy/kubernetes/mongodb.js +23 -0
  57. package/dist/deploy/types.d.ts +92 -0
  58. package/dist/deploy/types.js +16 -0
  59. package/dist/index.d.ts +8 -0
  60. package/dist/index.js +36 -0
  61. package/dist/pipeline/createChildPipeline.d.ts +9 -0
  62. package/dist/pipeline/createChildPipeline.js +266 -0
  63. package/dist/pipeline/createChildPipeline.test.d.ts +1 -0
  64. package/dist/pipeline/createChildPipeline.test.js +199 -0
  65. package/dist/pipeline/createJobs.d.ts +3 -0
  66. package/dist/pipeline/createJobs.js +331 -0
  67. package/dist/pipeline/index.d.ts +2 -0
  68. package/dist/pipeline/index.js +24 -0
  69. package/dist/pipeline/yarnInfo.d.ts +2 -0
  70. package/dist/pipeline/yarnInfo.js +296 -0
  71. package/dist/rules/index.d.ts +3 -0
  72. package/dist/rules/index.js +27 -0
  73. package/dist/runner/index.d.ts +3 -0
  74. package/dist/runner/index.js +12 -0
  75. package/dist/tsconfig.tsbuildinfo +1 -0
  76. package/dist/types/config.d.ts +73 -0
  77. package/dist/types/config.js +80 -0
  78. package/dist/types/context.d.ts +36 -0
  79. package/dist/types/context.js +3 -0
  80. package/dist/types/gitlab-types.d.ts +86 -0
  81. package/dist/types/gitlab-types.js +5 -0
  82. package/dist/{scripts/magic/types → types}/index.d.ts +1 -1
  83. package/dist/types/index.js +26 -0
  84. package/dist/utils/index.d.ts +2 -0
  85. package/dist/utils/index.js +18 -0
  86. package/package.json +30 -9
  87. package/src/build/base/constants.ts +7 -0
  88. package/src/build/base/createBuildJob.ts +46 -0
  89. package/{scripts/magic → src}/build/docker.ts +15 -2
  90. package/src/build/index.ts +42 -0
  91. package/src/build/node/buildJob.ts +54 -0
  92. package/src/build/node/cache.ts +36 -0
  93. package/src/build/node/constants.ts +6 -0
  94. package/src/build/node/index.ts +17 -0
  95. package/src/build/node/meteor.ts +75 -0
  96. package/src/build/node/testJob.ts +80 -0
  97. package/src/build/node/yarn.ts +8 -0
  98. package/src/build/tests/storybook.test.ts +46 -0
  99. package/src/build/types.ts +75 -0
  100. package/src/catladder-gitlab.ts +52 -0
  101. package/src/config/configruedEnvs.test.ts +97 -0
  102. package/src/config/configruedEnvs.ts +56 -0
  103. package/src/config/index.ts +2 -0
  104. package/src/config/readConfig.ts +36 -0
  105. package/src/constants.ts +2 -0
  106. package/src/context/index.ts +194 -0
  107. package/src/defaults/index.ts +6 -0
  108. package/src/deploy/base.ts +101 -0
  109. package/src/deploy/index.ts +19 -0
  110. package/src/deploy/kubernetes/cloudsql.ts +13 -0
  111. package/src/deploy/kubernetes/deployJob.ts +116 -0
  112. package/src/deploy/kubernetes/index.ts +1 -0
  113. package/src/deploy/kubernetes/mongodb.ts +20 -0
  114. package/src/deploy/types.ts +60 -0
  115. package/src/index.ts +8 -0
  116. package/{scripts/magic/tests/createPipeline.test.ts → src/pipeline/createChildPipeline.test.ts} +5 -4
  117. package/src/pipeline/createChildPipeline.ts +51 -0
  118. package/src/pipeline/createJobs.ts +158 -0
  119. package/src/pipeline/index.ts +2 -0
  120. package/src/pipeline/yarnInfo.ts +54 -0
  121. package/src/rules/index.ts +37 -0
  122. package/src/runner/index.ts +10 -0
  123. package/src/types/config.ts +88 -0
  124. package/src/types/context.ts +36 -0
  125. package/src/types/gitlab-types.ts +94 -0
  126. package/{scripts/magic → src}/types/index.ts +0 -0
  127. package/src/utils/index.ts +10 -0
  128. package/tsconfig.json +4 -2
  129. package/Dockerfile +0 -84
  130. package/dist/scripts/createSamplePipeline.d.ts +0 -2
  131. package/dist/scripts/createSamplePipeline.js +0 -14
  132. package/dist/scripts/magic/build/docker.d.ts +0 -2
  133. package/dist/scripts/magic/build/docker.js +0 -68
  134. package/dist/scripts/magic/build/index.d.ts +0 -9
  135. package/dist/scripts/magic/build/index.js +0 -12
  136. package/dist/scripts/magic/build/node.d.ts +0 -6
  137. package/dist/scripts/magic/build/node.js +0 -150
  138. package/dist/scripts/magic/build/types.d.ts +0 -18
  139. package/dist/scripts/magic/build/types.js +0 -7
  140. package/dist/scripts/magic/context/index.d.ts +0 -3
  141. package/dist/scripts/magic/context/index.js +0 -122
  142. package/dist/scripts/magic/createChildPipeline/index.d.ts +0 -3
  143. package/dist/scripts/magic/createChildPipeline/index.js +0 -68
  144. package/dist/scripts/magic/createPipeline.d.ts +0 -14
  145. package/dist/scripts/magic/createPipeline.js +0 -80
  146. package/dist/scripts/magic/deploy/index.d.ts +0 -9
  147. package/dist/scripts/magic/deploy/index.js +0 -12
  148. package/dist/scripts/magic/deploy/kubernetes.d.ts +0 -5
  149. package/dist/scripts/magic/deploy/kubernetes.js +0 -62
  150. package/dist/scripts/magic/deploy/types.d.ts +0 -41
  151. package/dist/scripts/magic/deploy/types.js +0 -7
  152. package/dist/scripts/magic/index.d.ts +0 -2
  153. package/dist/scripts/magic/index.js +0 -16
  154. package/dist/scripts/magic/sample-config.d.ts +0 -3
  155. package/dist/scripts/magic/sample-config.js +0 -77
  156. package/dist/scripts/magic/tests/createPipeline.test.d.ts +0 -1
  157. package/dist/scripts/magic/tests/createPipeline.test.js +0 -89
  158. package/dist/scripts/magic/types/config.d.ts +0 -49
  159. package/dist/scripts/magic/types/config.js +0 -17
  160. package/dist/scripts/magic/types/context.d.ts +0 -19
  161. package/dist/scripts/magic/types/context.js +0 -2
  162. package/dist/scripts/magic/types/gitlab-types.d.ts +0 -57
  163. package/dist/scripts/magic/types/gitlab-types.js +0 -2
  164. package/dist/scripts/magic/types/index.js +0 -15
  165. package/dist/scripts/magic.d.ts +0 -2
  166. package/dist/scripts/magic.js +0 -43
  167. package/dist/scripts/monorepoGenerate.d.ts +0 -2
  168. package/dist/scripts/monorepoGenerate.js +0 -164
  169. package/dist/scripts/printAllValues.d.ts +0 -2
  170. package/dist/scripts/printAllValues.js +0 -58
  171. package/dist/scripts/printBuildEnv.d.ts +0 -2
  172. package/dist/scripts/printBuildEnv.js +0 -77
  173. package/dist/scripts/utils/extractAllValues.d.ts +0 -1
  174. package/dist/scripts/utils/extractAllValues.js +0 -78
  175. package/dist/scripts/utils/extractBuildEnv.d.ts +0 -5
  176. package/dist/scripts/utils/extractBuildEnv.js +0 -152
  177. package/dist/scripts/utils/extractValuesFromEnvVars.d.ts +0 -2
  178. package/dist/scripts/utils/extractValuesFromEnvVars.js +0 -63
  179. package/dist/scripts/utils/extractValuesFromMr.d.ts +0 -2
  180. package/dist/scripts/utils/extractValuesFromMr.js +0 -86
  181. package/dist/tests/extractValuesFromMr.test.d.ts +0 -1
  182. package/dist/tests/extractValuesFromMr.test.js +0 -68
  183. package/scripts/createSamplePipeline.ts +0 -10
  184. package/scripts/getCommitInfo +0 -11
  185. package/scripts/kubernetesCreateSecret +0 -9
  186. package/scripts/kubernetesDelete +0 -4
  187. package/scripts/kubernetesDeploy +0 -55
  188. package/scripts/kubernetesEnsureNamespace +0 -3
  189. package/scripts/magic/build/index.ts +0 -18
  190. package/scripts/magic/build/node.ts +0 -143
  191. package/scripts/magic/build/types.ts +0 -21
  192. package/scripts/magic/context/index.ts +0 -127
  193. package/scripts/magic/createChildPipeline/index.ts +0 -60
  194. package/scripts/magic/createPipeline.ts +0 -52
  195. package/scripts/magic/deploy/index.ts +0 -19
  196. package/scripts/magic/deploy/kubernetes.ts +0 -65
  197. package/scripts/magic/deploy/types.ts +0 -29
  198. package/scripts/magic/index.ts +0 -2
  199. package/scripts/magic/sample-config.ts +0 -78
  200. package/scripts/magic/types/config.ts +0 -54
  201. package/scripts/magic/types/context.ts +0 -21
  202. package/scripts/magic/types/gitlab-types.ts +0 -69
  203. package/scripts/magic.ts +0 -51
  204. package/scripts/monorepoGenerate.ts +0 -104
  205. package/scripts/printAllValues.ts +0 -17
  206. package/scripts/printBuildEnv.ts +0 -22
  207. package/scripts/utils/extractAllValues.ts +0 -32
  208. package/scripts/utils/extractBuildEnv.ts +0 -94
  209. package/scripts/utils/extractValuesFromEnvVars.ts +0 -21
  210. package/scripts/utils/extractValuesFromMr.ts +0 -39
  211. package/tests/extractValuesFromMr.test.ts +0 -156
@@ -0,0 +1,75 @@
1
+ export type BuildConfigBase = {
2
+ startCommand?: string;
3
+ extraVars?: Record<string, string>;
4
+ /**
5
+ * define the build command
6
+ */
7
+ buildCommand?: string | string[] | null;
8
+
9
+ /**
10
+ * customize docker build
11
+ */
12
+ docker?: {
13
+ additionsBegin?: string[];
14
+ additionsEnd?: string[];
15
+ };
16
+
17
+ /**
18
+ * customize lint, set false to disable
19
+ */
20
+ lint?:
21
+ | false
22
+ | {
23
+ command?: string | string[];
24
+ };
25
+
26
+ /**
27
+ * customize test, set false to disable
28
+ */
29
+ test?:
30
+ | false
31
+ | {
32
+ command?: string | string[];
33
+ };
34
+
35
+ /**
36
+ * customize audit, set false to disable
37
+ */
38
+ audit?:
39
+ | false
40
+ | {
41
+ command?: string | string[];
42
+ };
43
+ };
44
+
45
+ export type BuildConfigNodeBase = BuildConfigBase;
46
+
47
+ export type BuildConfigNode = {
48
+ type: "node";
49
+ } & BuildConfigNodeBase;
50
+
51
+ export type BuildConfigNodeStatic = BuildConfigNodeBase & {
52
+ type: "node-static";
53
+ startCommand?: never;
54
+ };
55
+
56
+ export type BuildConfigMeteor = BuildConfigNodeBase & {
57
+ type: "meteor";
58
+ };
59
+
60
+ export type BuildConfigStorybook = BuildConfigNodeBase & {
61
+ type: "storybook";
62
+ startCommand?: never;
63
+ };
64
+ export type BuildConfig =
65
+ | BuildConfigNode
66
+ | BuildConfigNodeStatic
67
+ | BuildConfigStorybook
68
+ | BuildConfigMeteor;
69
+
70
+ export const isOfBuildType = <T extends Array<BuildConfig["type"]>>(
71
+ t: BuildConfig,
72
+ ...types: T
73
+ ): t is Extract<BuildConfig, { type: T[number] }> => {
74
+ return types.includes(t.type);
75
+ };
@@ -0,0 +1,52 @@
1
+ import { writeFileSync } from "fs";
2
+ import { readConfigSync } from "./config";
3
+ import { PIPELINE_IMAGE_TAG } from "./constants";
4
+ import { createChildPipeline } from "./pipeline";
5
+ import { PipelineTrigger } from "./types";
6
+
7
+ const {
8
+ CI_MERGE_REQUEST_ID,
9
+ CI_COMMIT_TAG,
10
+ CI_COMMIT_BRANCH,
11
+ CI_DEFAULT_BRANCH,
12
+ } = process.env;
13
+
14
+ const isDefaultBranch = CI_COMMIT_BRANCH == CI_DEFAULT_BRANCH;
15
+ const isHotfixBranch = false; // TODO: $CI_COMMIT_BRANCH =~ /^[0-9]+\.([0-9]+|x)\.x$/
16
+ const isMergeRequest = Boolean(CI_MERGE_REQUEST_ID);
17
+ const isTaggedRelease = Boolean(CI_COMMIT_TAG);
18
+
19
+ console.info(`catladder version ${PIPELINE_IMAGE_TAG}`);
20
+
21
+ const trigger: PipelineTrigger | null =
22
+ isMergeRequest || isHotfixBranch
23
+ ? "mr"
24
+ : isDefaultBranch
25
+ ? "mainBranch"
26
+ : isTaggedRelease
27
+ ? "taggedRelease"
28
+ : null;
29
+ if (trigger) {
30
+ const config = readConfigSync();
31
+ if (!config) {
32
+ throw new Error("no catladder config found");
33
+ }
34
+ createChildPipeline(trigger, config).then((mainPipeline) => {
35
+ writeFileSync(`__pipeline.yml`, JSON.stringify(mainPipeline, null, 2), {
36
+ encoding: "utf-8",
37
+ });
38
+ });
39
+ } else {
40
+ throw new Error(
41
+ "no matching trigger: " +
42
+ JSON.stringify(
43
+ {
44
+ isMergeRequest,
45
+ isDefaultBranch,
46
+ isTaggedRelease,
47
+ },
48
+ null,
49
+ 2
50
+ )
51
+ );
52
+ }
@@ -0,0 +1,97 @@
1
+ import { getAllEnvsByTrigger } from ".";
2
+ import { Config } from "../types";
3
+
4
+ describe("getAllEnvsByTrigger", () => {
5
+ const SIMPLE_CONFIG: Config = {
6
+ appName: "my-app",
7
+ customerName: "pan",
8
+ components: {
9
+ app1: {
10
+ dir: "dir1",
11
+ build: {
12
+ type: "node",
13
+ },
14
+ deploy: { type: "kubernetes" },
15
+ },
16
+ app2: {
17
+ dir: "dir2",
18
+ build: {
19
+ type: "node",
20
+ },
21
+ deploy: { type: "kubernetes" },
22
+ env: {
23
+ dev2: {
24
+ type: "dev",
25
+ },
26
+ review2: {
27
+ type: "review",
28
+ },
29
+ stage2: {
30
+ type: "stage",
31
+ },
32
+ prod2: {
33
+ type: "prod",
34
+ },
35
+ },
36
+ },
37
+ app3: {
38
+ dir: "dir2",
39
+ build: {
40
+ type: "node",
41
+ },
42
+ deploy: { type: "kubernetes" },
43
+ env: {
44
+ dev: false,
45
+ review: false,
46
+ stage: false,
47
+ prod: false,
48
+ },
49
+ },
50
+ },
51
+ };
52
+
53
+ describe("mainBranch", () => {
54
+ it("always includes dev if not disabled", () => {
55
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app1", "mainBranch");
56
+ expect(envs).toEqual(["dev"]);
57
+ });
58
+ it("returns additional dev environments", () => {
59
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app2", "mainBranch");
60
+ expect(envs).toEqual(["dev", "dev2"]);
61
+ });
62
+ it("does not include disabled envs", () => {
63
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app3", "mainBranch");
64
+ expect(envs).toEqual([]);
65
+ });
66
+ });
67
+
68
+ describe("mr", () => {
69
+ it("always includes review if not disabled", () => {
70
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app1", "mr");
71
+ expect(envs).toEqual(["review"]);
72
+ });
73
+ it("returns additional dev environments", () => {
74
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app2", "mr");
75
+ expect(envs).toEqual(["review", "review2"]);
76
+ });
77
+ it("does not include disabled envs", () => {
78
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app3", "mr");
79
+ expect(envs).toEqual([]);
80
+ });
81
+ });
82
+
83
+ describe("taggedRelease", () => {
84
+ it("always includes review if not disabled", () => {
85
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app1", "taggedRelease");
86
+ expect(envs).toEqual(["stage", "prod"]);
87
+ });
88
+ it("returns additional dev environments", () => {
89
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app2", "taggedRelease");
90
+ expect(envs).toEqual(["stage", "prod", "stage2", "prod2"]);
91
+ });
92
+ it("does not include disabled envs", () => {
93
+ const envs = getAllEnvsByTrigger(SIMPLE_CONFIG, "app3", "taggedRelease");
94
+ expect(envs).toEqual([]);
95
+ });
96
+ });
97
+ });
@@ -0,0 +1,56 @@
1
+ import {
2
+ Config,
3
+ DEFAULT_ENV_TYPES,
4
+ EnvType,
5
+ getEnvTypesByTrigger,
6
+ PipelineTrigger,
7
+ } from "../types";
8
+
9
+ const getConfiguredAndDefaultEnvs = (
10
+ config: Config,
11
+ componentName: string,
12
+ envTypes: EnvType[]
13
+ ) => {
14
+ const configuredEnvs = config.components[componentName].env ?? {};
15
+ // the default envs have the same name as the env types
16
+ // these can be disabled with settimg them to `false`
17
+ // this is the list of all not disabled envs. These are always returned
18
+ const enabledDefaultEnvs = envTypes.filter(
19
+ (e) => configuredEnvs[e] !== false
20
+ );
21
+
22
+ const configuredCustomEnvs = Object.entries(
23
+ config.components[componentName].env ?? {}
24
+ )
25
+ .filter(
26
+ ([, config]) =>
27
+ config &&
28
+ "type" in config &&
29
+ config.type &&
30
+ envTypes.includes(config.type)
31
+ )
32
+ .map(([envName]) => envName);
33
+
34
+ return [...new Set([...enabledDefaultEnvs, ...configuredCustomEnvs])];
35
+ };
36
+
37
+ export const getAllEnvs = (config: Config, componentName: string) => {
38
+ return getConfiguredAndDefaultEnvs(config, componentName, DEFAULT_ENV_TYPES);
39
+ };
40
+
41
+ export const getAllEnvsInAllComponents = (config: Config) => {
42
+ return [
43
+ ...new Set(
44
+ Object.keys(config.components).flatMap((c) => getAllEnvs(config, c))
45
+ ),
46
+ ];
47
+ };
48
+
49
+ export const getAllEnvsByTrigger = (
50
+ config: Config,
51
+ componentName: string,
52
+ trigger: PipelineTrigger
53
+ ) => {
54
+ const envTypesByTrigger = getEnvTypesByTrigger(trigger);
55
+ return getConfiguredAndDefaultEnvs(config, componentName, envTypesByTrigger);
56
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./configruedEnvs";
2
+ export * from "./readConfig";
@@ -0,0 +1,36 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { register } from "ts-node";
3
+ import { load } from "js-yaml";
4
+ import { Config } from "../types";
5
+
6
+ // allows us to load ts files
7
+
8
+ const fullPath = (directory: string, ext: string) =>
9
+ directory + "/catladder." + ext;
10
+
11
+ export const readConfigSync = (
12
+ directory: string = process.cwd()
13
+ ): Config | null => {
14
+ register({
15
+ cwd: directory,
16
+ transpileOnly: true,
17
+ compilerOptions: {
18
+ module: "commonjs",
19
+ },
20
+ });
21
+
22
+ const found = ["ts", "js", "yml", "yaml"].find((extension) =>
23
+ existsSync(fullPath(directory, extension))
24
+ );
25
+ if (found) {
26
+ if (found === "ts" || found === "js") {
27
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
28
+ return require(fullPath(directory, found)).default;
29
+ } else {
30
+ return load(
31
+ readFileSync(fullPath(directory, found), { encoding: "utf-8" })
32
+ ) as Config;
33
+ }
34
+ }
35
+ return null;
36
+ };
@@ -0,0 +1,2 @@
1
+ export const PIPELINE_IMAGE_TAG = process.env.INLINE_PIPELINE_IMAGE_TAG || "";
2
+ export const DOCKER_REGISTRY = process.env.INLINE_DOCKER_REGISTRY || "";
@@ -0,0 +1,194 @@
1
+ import { merge } from "lodash";
2
+ import slugify from "slugify";
3
+ import { BUILD_TYPES } from "../build";
4
+ import { BuildConfig } from "../build/types";
5
+ import { DEPLOY_TYPES } from "../deploy";
6
+ import { DeployConfig } from "../deploy/types";
7
+ import { Config, isKnowEnvType, DevLocalEnvConfig } from "../types/config";
8
+ import { CommitInfo, Context, Environment, YarnInfo } from "../types/context";
9
+
10
+ const sanitizeForEnVar = (s: string) => s.replace(/-/g, "_");
11
+ export const getSecretVarName = (
12
+ env: string,
13
+ componentName: string,
14
+ key: string
15
+ ) => `CL_${sanitizeForEnVar(env)}_${sanitizeForEnVar(componentName)}_${key}`; // remove dash from component name
16
+ export const getEnvironment = (
17
+ config: Config,
18
+ componentName: string,
19
+ env: string,
20
+ commitInfo?: CommitInfo,
21
+ skipReferences = false // to prevent infinit loop
22
+ ): Environment => {
23
+ const componentConfig = config.components[componentName];
24
+ if (!componentConfig) {
25
+ throw new Error("unknown component " + componentName);
26
+ }
27
+
28
+ const defaultConfig = componentConfig;
29
+
30
+ const envConfig = componentConfig.env?.[env] ?? {};
31
+ if (envConfig === false) {
32
+ throw new Error("env is disabled: " + env);
33
+ }
34
+
35
+ const mergedConfig = merge({}, defaultConfig, envConfig);
36
+
37
+ // env type: if its set manually, use that, otherwise use the known env types
38
+
39
+ const basePredefinedVariables = {
40
+ ENV_SHORT: env,
41
+ APP_DIR: componentConfig.dir,
42
+ };
43
+ const envType = envConfig?.type ?? (isKnowEnvType(env) ? env : null);
44
+ if (!envType) {
45
+ throw new Error(
46
+ "Missing type in environment " + env + " in component " + componentName
47
+ );
48
+ }
49
+ const environmentName =
50
+ envType === "review" && commitInfo
51
+ ? `${env}/${commitInfo.refName}/${componentName}`
52
+ : `${env}/${componentName}`;
53
+
54
+ const environmentSlug =
55
+ envType === "review" && commitInfo
56
+ ? `${env}-${commitInfo.refSlug}-${componentName}`
57
+ : `${env}-${componentName}`;
58
+
59
+ let predefinedVariables: Record<string, string>;
60
+ let hostname: string;
61
+ let url: string;
62
+ if (envType === "local") {
63
+ const devLocalConfig: DevLocalEnvConfig = mergedConfig;
64
+ const port = devLocalConfig.port ?? 3000;
65
+ hostname = "localhost:" + port;
66
+ url = "http://" + hostname;
67
+ predefinedVariables = {
68
+ ROOT_URL: url,
69
+ PORT: port.toString(),
70
+ };
71
+ } else {
72
+ const KUBE_NAMESPACE = `${config.customerName}-${config.appName}-${env}`;
73
+ const RELEASE_NAME = `${config.customerName}-${config.appName}-${environmentSlug}`;
74
+
75
+ const componentSlug = slugify(componentName);
76
+ const envInUrl =
77
+ envType === "review" && commitInfo ? `${commitInfo.refSlug}.${env}` : env;
78
+
79
+ const HOST_CANONICAL = `${config.appName}-${componentSlug}.${envInUrl}.${config.customerName}.panter.cloud`;
80
+
81
+ hostname = mergedConfig?.hostname ?? HOST_CANONICAL;
82
+ const url = `https://${hostname}`;
83
+
84
+ const KUBE_APP_NAME =
85
+ envType === "review" && commitInfo
86
+ ? `${componentName}-${commitInfo.refSlug}`
87
+ : componentName;
88
+
89
+ predefinedVariables = {
90
+ ...basePredefinedVariables,
91
+ HOST_CANONICAL,
92
+ ROOT_URL: url,
93
+ KUBE_NAMESPACE,
94
+ KUBE_APP_NAME,
95
+ RELEASE_NAME,
96
+ };
97
+ }
98
+ const publicEnvVars = mergedConfig.vars?.public ?? {};
99
+ const secretEnvVarKeys = mergedConfig.vars?.secret ?? [];
100
+ const secretEnvVars = Object.fromEntries(
101
+ secretEnvVarKeys.map((key) => [
102
+ key,
103
+ `$${getSecretVarName(env, componentName, key)}`,
104
+ ])
105
+ );
106
+ const referencedRaw = mergedConfig.vars?.fromComponents ?? {};
107
+
108
+ const referenced = skipReferences
109
+ ? {}
110
+ : Object.entries(referencedRaw).reduce((acc, [otherApp, mapping]) => {
111
+ const { envVars } = getEnvironment(
112
+ config,
113
+ otherApp,
114
+ env,
115
+ commitInfo,
116
+ true // prevent infinit loop
117
+ );
118
+
119
+ return {
120
+ ...acc,
121
+ ...Object.fromEntries(
122
+ Object.entries(mapping).map(([ourKey, otherKey]) => [
123
+ ourKey,
124
+ envVars[otherKey],
125
+ ])
126
+ ),
127
+ };
128
+ }, {});
129
+
130
+ const envVars = {
131
+ ...predefinedVariables,
132
+ ...secretEnvVars,
133
+ ...referenced,
134
+ ...publicEnvVars,
135
+ };
136
+
137
+ return {
138
+ envType,
139
+ hostname,
140
+ fullName: environmentName,
141
+ slug: environmentSlug,
142
+ shortName: env,
143
+ url: predefinedVariables.ROOT_URL,
144
+ envVars,
145
+ secretEnvVarKeys,
146
+ };
147
+ };
148
+
149
+ export const createContext = (
150
+ config: Config,
151
+ componentName: string,
152
+ env: string,
153
+ commitInfo?: CommitInfo,
154
+ yarnInfo?: YarnInfo
155
+ ): Context => {
156
+ if (!/^[a-z0-9-]+$/.test(componentName)) {
157
+ throw new Error(
158
+ "componentName may only contain lower case letters, numbers and -"
159
+ );
160
+ }
161
+ const rawConfig = config.components[componentName];
162
+ if (!rawConfig) {
163
+ throw new Error("unknown component " + componentName);
164
+ }
165
+ // envs can override the config
166
+ const envConfig = rawConfig.env?.[env] ?? {};
167
+ const componentConfigWithoutDefaults = merge({}, rawConfig, envConfig);
168
+
169
+ // fill in defaults of build and deploy
170
+ const defaults: {
171
+ build: Partial<BuildConfig>;
172
+ deploy: Partial<DeployConfig>;
173
+ } = componentConfigWithoutDefaults.deploy
174
+ ? {
175
+ build:
176
+ BUILD_TYPES[componentConfigWithoutDefaults.build.type].defaults(),
177
+ deploy:
178
+ DEPLOY_TYPES[componentConfigWithoutDefaults.deploy.type].defaults(),
179
+ }
180
+ : {
181
+ build: {},
182
+ deploy: {},
183
+ };
184
+ const componentConfig = merge({}, defaults, componentConfigWithoutDefaults);
185
+
186
+ return {
187
+ fullConfig: config,
188
+ componentConfig,
189
+ componentName,
190
+ environment: getEnvironment(config, componentName, env, commitInfo),
191
+ commitInfo,
192
+ yarnInfo,
193
+ };
194
+ };
@@ -0,0 +1,6 @@
1
+ import { Retry } from "../types";
2
+
3
+ export const BASE_RETRY: Retry = {
4
+ max: 2,
5
+ when: ["runner_system_failure", "stuck_or_timeout_failure"],
6
+ };
@@ -0,0 +1,101 @@
1
+ import { GitlabJob, Context, GitlabJobDef } from "../types";
2
+
3
+ export const DEPLOY_JOB_NAME = "🚀 Deploy";
4
+ export const STOP_JOB_NAME = "🛑 Stop ⚠️";
5
+
6
+ const DEPLOY_RUNNER_VARIABLES = {
7
+ KUBERNETES_CPU_REQUEST: "0.5",
8
+ KUBERNETES_CPU_LIMIT: "1",
9
+ KUBERNETES_MEMORY_REQUEST: "200Mi",
10
+ KUBERNETES_MEMORY_LIMIT: "500Mi",
11
+ };
12
+ type JobWithoutScript = Omit<GitlabJob, "job"> & {
13
+ job: Omit<GitlabJobDef, "script">;
14
+ };
15
+ export const getBaseDeploymentJob = (context: Context): JobWithoutScript => {
16
+ const environment = {
17
+ name: context.environment.fullName,
18
+ url: context.environment.url,
19
+ };
20
+
21
+ const autoStop =
22
+ context.environment.envType === "review"
23
+ ? "2 weeks"
24
+ : context.environment.envType === "dev"
25
+ ? "3 weeks"
26
+ : undefined;
27
+
28
+ return {
29
+ name: DEPLOY_JOB_NAME,
30
+ envMode: "stagePerEnv", // makes it easier to run manual tasks er env
31
+ // we don't want to deploy when there is a broken test
32
+ needsStages: [
33
+ {
34
+ stage: "build",
35
+ artifacts: false,
36
+ },
37
+ {
38
+ stage: "test",
39
+ artifacts: false,
40
+ },
41
+ ], // workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/220758
42
+ job: {
43
+ rules: [
44
+ context.environment.envType === "prod"
45
+ ? {
46
+ when: "manual",
47
+ }
48
+ : {
49
+ when: "on_success",
50
+ },
51
+ ],
52
+ stage: "deploy",
53
+ dependencies: [],
54
+ variables: {
55
+ ...DEPLOY_RUNNER_VARIABLES,
56
+ },
57
+ environment: {
58
+ ...environment,
59
+ on_stop: STOP_JOB_NAME,
60
+ auto_stop_in: autoStop,
61
+ },
62
+ },
63
+ };
64
+ };
65
+
66
+ export const getBaseDeploymentStopJob = (
67
+ context: Context
68
+ ): JobWithoutScript => {
69
+ const environment = {
70
+ name: context.environment.fullName,
71
+ url: context.environment.url,
72
+ };
73
+ return {
74
+ name: STOP_JOB_NAME,
75
+ envMode: "stagePerEnv", // makes it easier to run manual tasks er env
76
+ job: {
77
+ needs: [DEPLOY_JOB_NAME],
78
+ rules: [
79
+ {
80
+ if: "$CI_COMMIT_BRANCH =~ /^[0-9]+\\.([0-9]+|x)\\.x$/", // automatic on hotfix branches
81
+ when: "on_success",
82
+ allow_failure: true,
83
+ },
84
+ {
85
+ when: "manual",
86
+ allow_failure: true,
87
+ },
88
+ ],
89
+ variables: {
90
+ ...DEPLOY_RUNNER_VARIABLES,
91
+ GIT_STRATEGY: "none",
92
+ },
93
+ stage: "stop",
94
+ dependencies: [],
95
+ environment: {
96
+ ...environment,
97
+ action: "stop",
98
+ },
99
+ },
100
+ };
101
+ };
@@ -0,0 +1,19 @@
1
+ import { GitlabJobs } from "../types/gitlab-types";
2
+ import { Context } from "../types/context";
3
+ import { createKubernetesDeployJobs } from "./kubernetes";
4
+ import { DeployConfig } from "./types";
5
+
6
+ export type DeployTypes = {
7
+ [type in DeployConfig["type"]]: {
8
+ jobs: (context: Context) => GitlabJobs;
9
+ defaults: () => Partial<Extract<DeployConfig, { type: type }>>;
10
+ };
11
+ };
12
+
13
+ export * from "./types";
14
+ export const DEPLOY_TYPES: DeployTypes = {
15
+ kubernetes: {
16
+ jobs: createKubernetesDeployJobs,
17
+ defaults: () => ({}),
18
+ },
19
+ };
@@ -0,0 +1,13 @@
1
+ import { Context, getSecretVarName } from "../..";
2
+
3
+ export const createCloudsqlBaseConfig = (context: Context) => {
4
+ return {
5
+ cloudsql: {
6
+ proxyCredentials: `$${getSecretVarName(
7
+ context.environment.shortName,
8
+ context.componentName,
9
+ "cloudsqlProxyCredentials"
10
+ )}`,
11
+ },
12
+ };
13
+ };