@catladder/pipeline 0.0.1

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 (80) hide show
  1. package/Dockerfile +84 -0
  2. package/dist/scripts/magic/createChildPipeline/index.d.ts +5 -0
  3. package/dist/scripts/magic/createChildPipeline/index.js +141 -0
  4. package/dist/scripts/magic/createPipeline.d.ts +14 -0
  5. package/dist/scripts/magic/createPipeline.js +80 -0
  6. package/dist/scripts/magic/index.d.ts +2 -0
  7. package/dist/scripts/magic/index.js +16 -0
  8. package/dist/scripts/magic/sample-config.d.ts +3 -0
  9. package/dist/scripts/magic/sample-config.js +77 -0
  10. package/dist/scripts/magic/types/build/docker.d.ts +2 -0
  11. package/dist/scripts/magic/types/build/docker.js +63 -0
  12. package/dist/scripts/magic/types/build/index.d.ts +6 -0
  13. package/dist/scripts/magic/types/build/index.js +8 -0
  14. package/dist/scripts/magic/types/build/node.d.ts +3 -0
  15. package/dist/scripts/magic/types/build/node.js +118 -0
  16. package/dist/scripts/magic/types/build/types.d.ts +7 -0
  17. package/dist/scripts/magic/types/build/types.js +2 -0
  18. package/dist/scripts/magic/types/config.d.ts +49 -0
  19. package/dist/scripts/magic/types/config.js +17 -0
  20. package/dist/scripts/magic/types/context.d.ts +12 -0
  21. package/dist/scripts/magic/types/context.js +2 -0
  22. package/dist/scripts/magic/types/deploy/index.d.ts +6 -0
  23. package/dist/scripts/magic/types/deploy/index.js +8 -0
  24. package/dist/scripts/magic/types/deploy/kubernetes.d.ts +3 -0
  25. package/dist/scripts/magic/types/deploy/kubernetes.js +46 -0
  26. package/dist/scripts/magic/types/deploy/types.d.ts +41 -0
  27. package/dist/scripts/magic/types/deploy/types.js +7 -0
  28. package/dist/scripts/magic/types/gitlab-types.d.ts +63 -0
  29. package/dist/scripts/magic/types/gitlab-types.js +2 -0
  30. package/dist/scripts/magic/types/index.d.ts +3 -0
  31. package/dist/scripts/magic/types/index.js +15 -0
  32. package/dist/scripts/magic.d.ts +2 -0
  33. package/dist/scripts/magic.js +43 -0
  34. package/dist/scripts/monorepoGenerate.d.ts +2 -0
  35. package/dist/scripts/monorepoGenerate.js +164 -0
  36. package/dist/scripts/printAllValues.d.ts +2 -0
  37. package/dist/scripts/printAllValues.js +58 -0
  38. package/dist/scripts/printBuildEnv.d.ts +2 -0
  39. package/dist/scripts/printBuildEnv.js +77 -0
  40. package/dist/scripts/utils/extractAllValues.d.ts +1 -0
  41. package/dist/scripts/utils/extractAllValues.js +78 -0
  42. package/dist/scripts/utils/extractBuildEnv.d.ts +5 -0
  43. package/dist/scripts/utils/extractBuildEnv.js +152 -0
  44. package/dist/scripts/utils/extractValuesFromEnvVars.d.ts +2 -0
  45. package/dist/scripts/utils/extractValuesFromEnvVars.js +63 -0
  46. package/dist/scripts/utils/extractValuesFromMr.d.ts +2 -0
  47. package/dist/scripts/utils/extractValuesFromMr.js +86 -0
  48. package/dist/tests/extractValuesFromMr.test.d.ts +1 -0
  49. package/dist/tests/extractValuesFromMr.test.js +68 -0
  50. package/package.json +21 -0
  51. package/scripts/getCommitInfo +11 -0
  52. package/scripts/kubernetesCreateSecret +8 -0
  53. package/scripts/kubernetesDelete +4 -0
  54. package/scripts/kubernetesDeploy +57 -0
  55. package/scripts/kubernetesEnsureNamespace +3 -0
  56. package/scripts/magic/createChildPipeline/index.ts +163 -0
  57. package/scripts/magic/createPipeline.ts +48 -0
  58. package/scripts/magic/index.ts +2 -0
  59. package/scripts/magic/sample-config.ts +78 -0
  60. package/scripts/magic/types/build/docker.ts +36 -0
  61. package/scripts/magic/types/build/index.ts +11 -0
  62. package/scripts/magic/types/build/node.ts +107 -0
  63. package/scripts/magic/types/build/types.ts +9 -0
  64. package/scripts/magic/types/config.ts +54 -0
  65. package/scripts/magic/types/context.ts +13 -0
  66. package/scripts/magic/types/deploy/index.ts +11 -0
  67. package/scripts/magic/types/deploy/kubernetes.ts +38 -0
  68. package/scripts/magic/types/deploy/types.ts +29 -0
  69. package/scripts/magic/types/gitlab-types.ts +77 -0
  70. package/scripts/magic/types/index.ts +3 -0
  71. package/scripts/magic.ts +51 -0
  72. package/scripts/monorepoGenerate.ts +104 -0
  73. package/scripts/printAllValues.ts +17 -0
  74. package/scripts/printBuildEnv.ts +22 -0
  75. package/scripts/utils/extractAllValues.ts +32 -0
  76. package/scripts/utils/extractBuildEnv.ts +92 -0
  77. package/scripts/utils/extractValuesFromEnvVars.ts +21 -0
  78. package/scripts/utils/extractValuesFromMr.ts +39 -0
  79. package/tests/extractValuesFromMr.test.ts +156 -0
  80. package/tsconfig.json +10 -0
@@ -0,0 +1,163 @@
1
+ import { merge } from "lodash";
2
+ import slugify from "slugify";
3
+ import { GitlabJobDef, GitlabJobs } from "../types/gitlab-types";
4
+ import { buildJobCreators } from "../types/build";
5
+ import { Config } from "../types/config";
6
+ import { Context, Environment } from "../types/context";
7
+ import { deployJobCreators } from "../types/deploy";
8
+
9
+ const createRawJobs = (context: Context): GitlabJobs => {
10
+ const buildJobs =
11
+ buildJobCreators[context.componentConfig.build.type](context);
12
+ const deployJobs =
13
+ deployJobCreators[context.componentConfig.deploy.type](context);
14
+
15
+ return [...buildJobs, ...deployJobs];
16
+ };
17
+
18
+ const getEnvironment = (
19
+ config: Config,
20
+ componentName: string,
21
+ env: string
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
+ const envConfig = componentConfig.env?.[env] ?? {};
30
+
31
+ const mergedConfig = merge({}, defaultConfig, envConfig);
32
+
33
+ const publicEnvVars = mergedConfig.vars?.public ?? {};
34
+ const secretEnvVarsRaw = mergedConfig.vars?.secret ?? {}; // TODO, map to gl secrets?
35
+ const secretEnvVars = {}; // TODO
36
+ const referencedRaw = mergedConfig.vars?.fromComponents ?? {};
37
+
38
+ const referenced = Object.entries(referencedRaw).reduce(
39
+ (acc, [otherApp, mapping]) => {
40
+ // TODO: prevent infinit looop
41
+ const { variables } = getEnvironment(config, otherApp, env);
42
+
43
+ return Object.fromEntries(
44
+ Object.entries(mapping).map(([ourKey, otherKey]) => [
45
+ ourKey,
46
+ variables[otherKey],
47
+ ])
48
+ );
49
+ },
50
+ {}
51
+ );
52
+
53
+ const envType = componentConfig.env?.[env]?.type ?? env;
54
+ const environmentName =
55
+ envType === "review"
56
+ ? `${env}-${componentName}/$CI_COMMIT_REF_NAME`
57
+ : `${env}-${componentName}`;
58
+
59
+ const KUBE_APP_NAME =
60
+ envType === "review"
61
+ ? `${componentName}-$CI_COMMIT_REF_SLUG`
62
+ : componentName;
63
+
64
+ const KUBE_NAMESPACE = `${config.customerName}-${config.appName}-${env}`;
65
+
66
+ const APP_SLUG = slugify(KUBE_APP_NAME);
67
+
68
+ const CANONICAL_HOST = `${config.appName}-${APP_SLUG}.${config.customerName}.panter.cloud`;
69
+
70
+ const hostname = mergedConfig.hostname ?? CANONICAL_HOST;
71
+ const url = `https://${hostname}`;
72
+
73
+ const predefinedVariables = {
74
+ CANONICAL_URL: url,
75
+ ROOT_URL: url,
76
+ KUBE_NAMESPACE,
77
+ };
78
+ const variables = {
79
+ ...predefinedVariables,
80
+ ...publicEnvVars,
81
+ ...secretEnvVars,
82
+ ...referenced,
83
+ };
84
+
85
+ return {
86
+ fullName: environmentName,
87
+ shortName: env,
88
+ url: url,
89
+ variables,
90
+ };
91
+ };
92
+
93
+ export const createContext = (
94
+ componentName: string,
95
+ config: Config
96
+ ): Context => {
97
+ const componentConfig = config.components[componentName];
98
+ if (!componentConfig) {
99
+ throw new Error("unknown component " + componentName);
100
+ }
101
+ return {
102
+ fullConfig: config,
103
+ componentConfig,
104
+ componentName,
105
+ };
106
+ };
107
+
108
+ const getFullJobName = (name: string, componentName: string, env?: string) => {
109
+ if (env) {
110
+ return `${env} ${componentName} ${name}`;
111
+ }
112
+ return `${componentName} ${name}`;
113
+ };
114
+
115
+ const replaceReferences = (
116
+ def: GitlabJobDef,
117
+ componentName: string,
118
+ env?: string
119
+ ): GitlabJobDef => {
120
+ return {
121
+ ...def,
122
+ needs: def.needs?.map((n) => getFullJobName(n, componentName, env)),
123
+ dependencies: def.dependencies?.map((n) =>
124
+ getFullJobName(n, componentName, env)
125
+ ),
126
+ };
127
+ };
128
+
129
+ export const createJobs = (
130
+ envs: string[],
131
+ config: Config,
132
+ componentName: string
133
+ ): Record<string, GitlabJobDef> => {
134
+ const context = createContext(componentName, config);
135
+ const jobs = createRawJobs(context);
136
+ const environments = envs.map((e) =>
137
+ getEnvironment(config, componentName, e)
138
+ );
139
+ return jobs.reduce((acc, job) => {
140
+ if (!job.env) {
141
+ const def = job.job();
142
+
143
+ return {
144
+ ...acc,
145
+ [getFullJobName(job.name, componentName)]: replaceReferences(
146
+ def,
147
+ componentName
148
+ ),
149
+ };
150
+ }
151
+ return {
152
+ ...acc,
153
+ ...environments.reduce((envacc, environment) => {
154
+ const def = job.job(environment);
155
+ return {
156
+ ...acc,
157
+ [getFullJobName(job.name, componentName, environment.shortName)]:
158
+ replaceReferences(def, componentName, environment.shortName),
159
+ };
160
+ }, {}),
161
+ };
162
+ }, {});
163
+ };
@@ -0,0 +1,48 @@
1
+ import { createJobs } from "./createChildPipeline";
2
+ import { Config, ENV_TYPES, PipelineTrigger } from "./types/config";
3
+
4
+ export const createPipeline = async (
5
+ trigger: PipelineTrigger,
6
+ config: Config
7
+ ) => {
8
+ const envs = Object.keys(ENV_TYPES).filter(
9
+ (e) => ENV_TYPES[e as keyof typeof ENV_TYPES].trigger === trigger
10
+ );
11
+ const components = Object.keys(config.components);
12
+
13
+ // 2. write the triggering pipeline
14
+
15
+ const jobs = components.reduce((acc, componentName) => {
16
+ return {
17
+ ...acc,
18
+ ...createJobs(envs, config, componentName),
19
+ };
20
+ }, {});
21
+
22
+ const rules = [
23
+ // same as rules "always", but with `changes` to only trigger changed branches
24
+ { if: "$CI_COMMIT_TAG" },
25
+ {
26
+ if: "$CI_COMMIT_MESSAGE =~ /^chore(release).*/",
27
+ when: "never",
28
+ },
29
+ { if: "$CI_COMMIT_BRANCH =~ /^[0-9]+.([0-9]+|x).x$/" },
30
+ {
31
+ if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH",
32
+ },
33
+
34
+ { if: "$CI_MERGE_REQUEST_ID" },
35
+ ];
36
+
37
+ const mainPipeline = {
38
+ image:
39
+ "git.panter.ch:5001/catladder/gitlab-ci/pipeline:$PIPELINE_IMAGE_TAG",
40
+ workflow: {
41
+ rules,
42
+ },
43
+ stages: ["setup", "test", "build", "deploy", "verify", "actions"],
44
+ ...jobs,
45
+ };
46
+
47
+ return mainPipeline;
48
+ };
@@ -0,0 +1,2 @@
1
+ export { createPipeline } from "./createPipeline";
2
+ export * from "./types";
@@ -0,0 +1,78 @@
1
+ import { Config } from "./types/config";
2
+
3
+ const sampleConfig: Config = {
4
+ customerName: "pan",
5
+ appName: "fonsi",
6
+ components: {
7
+ web: {
8
+ dir: "web",
9
+ build: {
10
+ type: "node-static",
11
+ },
12
+ deploy: {
13
+ type: "kubernetes",
14
+ values: {
15
+ application: {
16
+ resources: {
17
+ limits: {
18
+ cpu: "100m",
19
+ },
20
+ },
21
+ },
22
+ },
23
+ },
24
+ vars: {
25
+ public: {
26
+ GOOGLE_TAG_MANAGER_ID: "1234",
27
+ },
28
+ fromComponents: {
29
+ api: {
30
+ API_URL: "ROOT_URL",
31
+ },
32
+ },
33
+ },
34
+ env: {
35
+ prod: {
36
+ hostname: "fudilo.ch",
37
+ vars: {},
38
+ deploy: {
39
+ type: "kubernetes",
40
+ values: {
41
+ application: {
42
+ resources: {
43
+ limits: {
44
+ cpu: "1000m",
45
+ },
46
+ },
47
+ },
48
+ },
49
+ },
50
+ },
51
+ myCustomProd: {
52
+ type: "prod",
53
+ hostname: "fudilo2.ch",
54
+ },
55
+ },
56
+ },
57
+ api: {
58
+ env: {
59
+ prod: {
60
+ hostname: "api.fudilo.ch",
61
+ },
62
+ myCustomProd: {
63
+ type: "prod",
64
+ hostname: "api.fudilo2.ch",
65
+ },
66
+ },
67
+ build: {
68
+ type: "node",
69
+ },
70
+ deploy: {
71
+ type: "kubernetes",
72
+ },
73
+ dir: "api",
74
+ },
75
+ },
76
+ };
77
+
78
+ export default sampleConfig;
@@ -0,0 +1,36 @@
1
+ import { GitlabJobDef } from "../gitlab-types";
2
+
3
+ export const createDockerBuildJob = ({
4
+ script,
5
+ }: Pick<GitlabJobDef, "script">): GitlabJobDef => {
6
+ const base: Omit<GitlabJobDef, "script"> = {
7
+ stage: "build",
8
+ image:
9
+ "git.panter.ch:5001/catladder/gitlab-ci/docker-build:$PIPELINE_IMAGE_TAG",
10
+ interruptible: true,
11
+ services: [
12
+ {
13
+ name: "docker:20-dind", // see see https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27300#note_466755332
14
+ command: ["--tls=false"],
15
+ },
16
+ ],
17
+ variables: {
18
+ DOCKER_DRIVER: "overlay2",
19
+ IMAGE_NAME: "$CI_REGISTRY_IMAGE/$COMPONENT_NAME",
20
+ CACHE_IMAGE: "$CI_REGISTRY_IMAGE/$COMPONENT_NAME/cache:cache",
21
+ },
22
+ };
23
+
24
+ return {
25
+ ...base,
26
+ script: [
27
+ ...script,
28
+ "docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY",
29
+ "docker pull $CACHE_IMAGE || true",
30
+ "docker build --network host --cache-from $CACHE_IMAGE --tag $IMAGE_NAME:$IMAGE_TAG $DOCKER_DIR",
31
+ "docker push $IMAGE_NAME:$IMAGE_TAG",
32
+ "docker tag $IMAGE_NAME:$IMAGE_TAG $CACHE_IMAGE",
33
+ "docker push $CACHE_IMAGE",
34
+ ],
35
+ };
36
+ };
@@ -0,0 +1,11 @@
1
+ import { GitlabJobs } from "../gitlab-types";
2
+ import { Context } from "../context";
3
+ import { createNodeJobs } from "./node";
4
+ import { BuildConfig } from "./types";
5
+
6
+ export const buildJobCreators: {
7
+ [type in BuildConfig["type"]]: (context: Context) => GitlabJobs;
8
+ } = {
9
+ node: createNodeJobs,
10
+ "node-static": createNodeJobs, // TODO
11
+ };
@@ -0,0 +1,107 @@
1
+ import {
2
+ GitlabJobDef,
3
+ GitlabJobCache,
4
+ GitlabJobs,
5
+ Retry,
6
+ } from "../gitlab-types";
7
+ import { Context } from "../context";
8
+ import { createDockerBuildJob } from "./docker";
9
+
10
+ const yarnInstall = [
11
+ "cd $APP_PATH",
12
+ "if [ -f ./.nvmrc ]; then source /root/.nvm/nvm.sh && nvm install <<< .nvmrc; fi",
13
+ "yarn install --frozen-lockfile",
14
+ ];
15
+
16
+ const baseRetry: Retry = {
17
+ max: 2,
18
+ when: ["runner_system_failure", "stuck_or_timeout_failure"],
19
+ };
20
+
21
+ const createNodeTestJobs = (context: Context): GitlabJobs => {
22
+ const cache: GitlabJobCache[] = [
23
+ {
24
+ key: "node-modules",
25
+ policy: "pull-push",
26
+ paths: ["node_modules", "**/node_modules/"],
27
+ },
28
+ ];
29
+ const base: Omit<GitlabJobDef, "script"> = {
30
+ variables: {
31
+ APP_PATH: context.componentConfig.dir,
32
+ },
33
+ cache,
34
+ stage: "test",
35
+ interruptible: true,
36
+ needs: [],
37
+ retry: baseRetry,
38
+ };
39
+ return [
40
+ {
41
+ name: "test",
42
+ env: false,
43
+ job: () => ({
44
+ ...base,
45
+ script: [...yarnInstall, "yarn test"],
46
+ }),
47
+ },
48
+ {
49
+ name: "lint",
50
+ env: false,
51
+ job: () => ({
52
+ ...base,
53
+ script: [...yarnInstall, "yarn lint"],
54
+ }),
55
+ },
56
+ {
57
+ name: "audit",
58
+ env: false,
59
+ job: () => ({
60
+ ...base,
61
+ script: [...yarnInstall, "yarn audit"],
62
+ }),
63
+ },
64
+ ];
65
+ };
66
+
67
+ const createNodeBuildJobs = (context: Context): GitlabJobs => {
68
+ const buildInfo = [
69
+ ". getCommitInfo", // TODO: inline
70
+ `echo '{"id":"'$BUILD_ID'","commit":"'$BUILD_COMMIT'","tag":"'$BUILD_TAG'","time":"'$BUILD_TIME'"}' > $APP_DIR/__build_info.json`,
71
+ ];
72
+
73
+ return [
74
+ {
75
+ name: "app-build",
76
+ env: true,
77
+ job: (environment) => ({
78
+ variables: environment.variables,
79
+ retry: baseRetry,
80
+ interruptible: true,
81
+ stage: "build",
82
+ script: [...buildInfo, ...yarnInstall, "yarn build"],
83
+ artifacts: {
84
+ paths: [
85
+ context.componentConfig.dir + "/__build_info.json",
86
+ context.componentConfig.dir + "/dist",
87
+ context.componentConfig.dir + "/.next",
88
+ ],
89
+ },
90
+ }),
91
+ },
92
+ {
93
+ name: "docker-build",
94
+ env: true,
95
+ job: () => ({
96
+ ...createDockerBuildJob({
97
+ script: ["ensureNodeDockerfile"], // TOOD: inline
98
+ }),
99
+ needs: ["app-build"],
100
+ }),
101
+ },
102
+ ];
103
+ };
104
+
105
+ export const createNodeJobs = (context: Context): GitlabJobs => {
106
+ return [...createNodeBuildJobs(context), ...createNodeTestJobs(context)];
107
+ };
@@ -0,0 +1,9 @@
1
+ export type BuildConfigNode = {
2
+ type: "node";
3
+ };
4
+
5
+ export type BuildConfigNodeStatic = {
6
+ type: "node-static";
7
+ };
8
+
9
+ export type BuildConfig = BuildConfigNode | BuildConfigNodeStatic;
@@ -0,0 +1,54 @@
1
+ import { BuildConfig } from "./build/types";
2
+ import { DeployConfig } from "./deploy/types";
3
+
4
+ export type PipelineTrigger = "mainBranch" | "mr" | "taggedRelease";
5
+
6
+ export const ENV_TYPES = {
7
+ dev: {
8
+ trigger: "mainBranch",
9
+ },
10
+ review: {
11
+ trigger: "mr",
12
+ },
13
+ prod: {
14
+ trigger: "taggedRelease",
15
+ },
16
+ stage: {
17
+ trigger: "taggedRelease",
18
+ },
19
+ } as const;
20
+ type EnvType = keyof typeof ENV_TYPES;
21
+
22
+ type DefaultEnvConfig = {
23
+ deploy: DeployConfig;
24
+ build: BuildConfig;
25
+ vars?: {
26
+ public?: Record<string, any>;
27
+ secret?: Record<string, string>;
28
+ fromComponents?: {
29
+ [otherApp: string]: Record<string, string>;
30
+ };
31
+ };
32
+ };
33
+ type EnvConfig<E extends EnvType = EnvType> = {
34
+ type?: E;
35
+ hostname?: string;
36
+ } & Partial<DefaultEnvConfig>;
37
+
38
+ export type Env = {
39
+ dev?: EnvConfig<"dev">;
40
+ stage?: EnvConfig<"stage">;
41
+ review?: EnvConfig<"review">;
42
+ prod?: EnvConfig<"prod">;
43
+ } & Record<string, EnvConfig>;
44
+
45
+ export type ComponentConfig = {
46
+ env?: Env;
47
+ dir: string;
48
+ } & DefaultEnvConfig;
49
+
50
+ export type Config = {
51
+ customerName: string;
52
+ appName: string;
53
+ components: Record<string, ComponentConfig>;
54
+ };
@@ -0,0 +1,13 @@
1
+ import { ComponentConfig, Config, PipelineTrigger } from "./config";
2
+
3
+ export type Environment = {
4
+ fullName: string;
5
+ shortName: string;
6
+ url: string;
7
+ variables: Record<string, string>;
8
+ };
9
+ export type Context = {
10
+ componentConfig: ComponentConfig;
11
+ componentName: string;
12
+ fullConfig: Config;
13
+ };
@@ -0,0 +1,11 @@
1
+ import { GitlabJobs } from "../gitlab-types";
2
+ import { ComponentConfig } from "../config";
3
+ import { Context } from "../context";
4
+ import { createKubernetesDeployJobs } from "./kubernetes";
5
+
6
+ export const deployJobCreators: {
7
+ [type in ComponentConfig["deploy"]["type"]]: (context: Context) => GitlabJobs;
8
+ } = {
9
+ kubernetes: createKubernetesDeployJobs,
10
+ serverless: () => [],
11
+ };
@@ -0,0 +1,38 @@
1
+ import { GitlabJobs } from "../gitlab-types";
2
+ import { Context } from "../context";
3
+ import { isOfType } from "./types";
4
+
5
+ export const createKubernetesDeployJobs = (context: Context): GitlabJobs => {
6
+ const deployConfig = context.componentConfig.deploy;
7
+ if (!isOfType(deployConfig, "kubernetes")) {
8
+ // should not happen
9
+ throw new Error("deploy config is not kubernetes");
10
+ }
11
+
12
+ return [
13
+ {
14
+ name: "deploy-to-kubernetes",
15
+ env: true,
16
+ job: (environment) => ({
17
+ variables: {
18
+ ...environment.variables,
19
+ RELEASE_NAME: "${CUSTOMER_NAME}-${APP_NAME}-${CI_ENVIRONMENT_SLUG}",
20
+ },
21
+ stage: "deploy",
22
+ dependencies: [],
23
+ script: [
24
+ "kubernetesEnsureNamespace",
25
+ "kubernetesCreateSecret",
26
+ "kubernetesDeploy",
27
+ ],
28
+ environment: {
29
+ name: environment.fullName,
30
+ url: environment.url,
31
+ kubernetes: {
32
+ namespace: environment.variables.KUBE_NAMESPACE,
33
+ },
34
+ },
35
+ }),
36
+ },
37
+ ];
38
+ };
@@ -0,0 +1,29 @@
1
+ export type DeployConfigBase = {};
2
+ export type DeployConfigKubernetes = {
3
+ type: "kubernetes";
4
+ additionalHelmArgs?: string[];
5
+ values?: {
6
+ application?: {
7
+ resources?: {
8
+ limits?: {
9
+ cpu?: any;
10
+ };
11
+ requests?: {
12
+ cpu?: any;
13
+ };
14
+ };
15
+ } & Record<string, any>;
16
+ } & Record<string, any>;
17
+ } & DeployConfigBase;
18
+
19
+ export type DeployConfigServerless = {
20
+ type: "serverless";
21
+ };
22
+ export type DeployConfig = DeployConfigKubernetes | DeployConfigServerless;
23
+
24
+ export const isOfType = <T extends DeployConfig["type"]>(
25
+ t: DeployConfig,
26
+ type: T
27
+ ): t is Extract<DeployConfig, { type: T }> => {
28
+ return t.type === type;
29
+ };
@@ -0,0 +1,77 @@
1
+ import { Environment } from "./context";
2
+
3
+ export type GitlabStage =
4
+ | "setup"
5
+ | "test"
6
+ | "build"
7
+ | "deploy"
8
+ | "verify"
9
+ | "actions";
10
+
11
+ export type Artifacts = {
12
+ paths: string[];
13
+ };
14
+ export type GitlabJobCache = {
15
+ key: string;
16
+ policy?: string;
17
+ paths: string[];
18
+ };
19
+ export type GitlabRule = {
20
+ if: string;
21
+ when?: "always" | "on_success" | "manual" | "never"; // todo
22
+ };
23
+ export type Retry = {
24
+ max: number;
25
+ when: string[];
26
+ };
27
+
28
+ export type Service = {
29
+ name: string;
30
+ command: string[];
31
+ };
32
+
33
+ export type GitlabEnvironment = {
34
+ url: string;
35
+ name: string;
36
+ kubernetes?: {
37
+ namespace?: string;
38
+ };
39
+ };
40
+ export type GitlabJobDef = {
41
+ stage: GitlabStage;
42
+ before_script?: string[];
43
+ script: string[];
44
+ interruptible?: boolean;
45
+ needs?: string[];
46
+ rules?: GitlabRule[];
47
+ cache?: GitlabJobCache | GitlabJobCache[];
48
+ artifacts?: Artifacts;
49
+ retry?: Retry;
50
+ services?: Service[];
51
+ image?: string;
52
+ variables?: GitlabVariables;
53
+ dependencies?: string[];
54
+ environment?: GitlabEnvironment;
55
+ };
56
+
57
+ export type GitlabVariables = Record<string, string | undefined>;
58
+
59
+ export type JobEnvDependent = {
60
+ name: string;
61
+ env: true;
62
+ job: (environment: Environment) => GitlabJobDef;
63
+ };
64
+
65
+ export type JobNonEnv = {
66
+ name: string;
67
+ env: false;
68
+ job: () => GitlabJobDef;
69
+ };
70
+ export type GitlabJob = JobEnvDependent | JobNonEnv;
71
+ export type GitlabJobs = GitlabJob[];
72
+
73
+ export type GitlabPipeline = {
74
+ variables: GitlabVariables;
75
+ stages: GitlabStage[];
76
+ jobs: GitlabJobs;
77
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./config";
2
+ export * from "./gitlab-types";
3
+ export * from "./context";