@catladder/pipeline 1.153.0 → 1.154.0

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 (153) hide show
  1. package/dist/build/artifacts/createBuildJobArtifact.d.ts +3 -0
  2. package/dist/build/artifacts/createBuildJobArtifact.js +97 -0
  3. package/dist/build/base/createAppBuildJob.d.ts +3 -3
  4. package/dist/build/base/createAppBuildJob.js +9 -15
  5. package/dist/build/base/index.d.ts +6 -2
  6. package/dist/build/base/index.js +14 -5
  7. package/dist/build/base/writeDotEnv.js +2 -1
  8. package/dist/build/custom/__tests__/testJob.test.js +1 -1
  9. package/dist/build/custom/buildJob.js +3 -10
  10. package/dist/build/docker.js +3 -3
  11. package/dist/build/index.d.ts +13 -6
  12. package/dist/build/index.js +29 -7
  13. package/dist/build/node/buildJob.d.ts +7 -2
  14. package/dist/build/node/buildJob.js +40 -33
  15. package/dist/build/node/cache.d.ts +2 -2
  16. package/dist/build/node/cache.js +8 -4
  17. package/dist/build/node/index.d.ts +2 -2
  18. package/dist/build/node/meteor.js +3 -6
  19. package/dist/build/node/testJob.d.ts +3 -2
  20. package/dist/build/node/testJob.js +9 -4
  21. package/dist/build/node/yarn.js +1 -1
  22. package/dist/build/rails/build.d.ts +1 -1
  23. package/dist/build/rails/build.js +7 -2
  24. package/dist/build/rails/test.d.ts +1 -1
  25. package/dist/build/rails/test.js +5 -0
  26. package/dist/build/sbom.js +3 -2
  27. package/dist/build/types.d.ts +48 -4
  28. package/dist/build/types.js +7 -1
  29. package/dist/bundles/catladder-gitlab/index.js +2 -2
  30. package/dist/constants.js +1 -1
  31. package/dist/context/createAllComponentsContext.d.ts +12 -0
  32. package/dist/context/createAllComponentsContext.js +159 -0
  33. package/dist/context/createComponentContext.d.ts +1 -5
  34. package/dist/context/createComponentContext.js +82 -20
  35. package/dist/context/createWorkspaceContext.d.ts +16 -0
  36. package/dist/context/createWorkspaceContext.js +173 -0
  37. package/dist/context/getBuildInfoVariables.d.ts +1 -1
  38. package/dist/context/getEnvironmentContext.d.ts +1 -1
  39. package/dist/context/getEnvironmentVariables.d.ts +2 -2
  40. package/dist/context/getEnvironmentVariables.js +5 -4
  41. package/dist/context/getLabels.js +5 -5
  42. package/dist/deploy/base/deploy.d.ts +1 -1
  43. package/dist/deploy/base/deploy.js +18 -5
  44. package/dist/deploy/cloudRun/artifactsRegistry.js +2 -2
  45. package/dist/deploy/cloudRun/createJobs/common.d.ts +4 -4
  46. package/dist/deploy/cloudRun/index.d.ts +2 -2
  47. package/dist/deploy/custom/index.d.ts +2 -2
  48. package/dist/deploy/dockerTag/index.d.ts +2 -2
  49. package/dist/deploy/index.d.ts +7 -7
  50. package/dist/deploy/kubernetes/additionalSecretKeys.d.ts +3 -1
  51. package/dist/deploy/kubernetes/cloudSql/index.js +1 -1
  52. package/dist/deploy/kubernetes/deployJob.js +2 -2
  53. package/dist/deploy/kubernetes/index.d.ts +2 -2
  54. package/dist/deploy/sbom.d.ts +1 -1
  55. package/dist/deploy/sbom.js +4 -3
  56. package/dist/deploy/types/index.d.ts +3 -3
  57. package/dist/pipeline/createAllJobs.d.ts +12 -10
  58. package/dist/pipeline/createAllJobs.js +94 -51
  59. package/dist/pipeline/createJobsForComponent.js +2 -3
  60. package/dist/pipeline/createJobsForWorkspace.d.ts +3 -0
  61. package/dist/pipeline/createJobsForWorkspace.js +12 -0
  62. package/dist/pipeline/createMainPipeline.js +26 -6
  63. package/dist/pipeline/gitlab/createGitlabJobs.d.ts +3 -16
  64. package/dist/pipeline/gitlab/createGitlabJobs.js +191 -73
  65. package/dist/pipeline/packageManager.d.ts +3 -2
  66. package/dist/pipeline/packageManager.js +43 -15
  67. package/dist/tsconfig.tsbuildinfo +1 -1
  68. package/dist/types/config.d.ts +5 -4
  69. package/dist/types/context.d.ts +80 -12
  70. package/dist/types/context.js +10 -1
  71. package/dist/types/environmentContext.d.ts +5 -6
  72. package/dist/types/jobs.d.ts +5 -0
  73. package/examples/__snapshots__/cloud-run-memory-limit.ts.snap +8 -8
  74. package/examples/__snapshots__/cloud-run-meteor-with-worker.ts.snap +8 -0
  75. package/examples/__snapshots__/cloud-run-no-cpu-throttling.ts.snap +8 -8
  76. package/examples/__snapshots__/cloud-run-no-service.ts.snap +8 -8
  77. package/examples/__snapshots__/cloud-run-non-public.ts.snap +8 -8
  78. package/examples/__snapshots__/cloud-run-post-stop-job.ts.snap +8 -8
  79. package/examples/__snapshots__/cloud-run-service-gen2.ts.snap +8 -8
  80. package/examples/__snapshots__/cloud-run-service-increase-timout.ts.snap +8 -8
  81. package/examples/__snapshots__/cloud-run-service-with-volumes.ts.snap +8 -8
  82. package/examples/__snapshots__/cloud-run-storybook.ts.snap +4 -8
  83. package/examples/__snapshots__/cloud-run-with-ngnix.ts.snap +4 -8
  84. package/examples/__snapshots__/cloud-run-with-sql-reuse-db.ts.snap +16 -16
  85. package/examples/__snapshots__/cloud-run-with-sql.ts.snap +589 -1097
  86. package/examples/__snapshots__/cloud-run-with-worker.ts.snap +8 -8
  87. package/examples/__snapshots__/custom-build-job-with-tests.ts.snap +4 -0
  88. package/examples/__snapshots__/custom-build-job.ts.snap +4 -0
  89. package/examples/__snapshots__/custom-deploy.ts.snap +8 -8
  90. package/examples/__snapshots__/custom-envs.ts.snap +18 -12
  91. package/examples/__snapshots__/custom-sbom-java.ts.snap +4 -0
  92. package/examples/__snapshots__/kubernetes-application-customization.ts.snap +8 -8
  93. package/examples/__snapshots__/kubernetes-with-cloud-sql-legacy.ts.snap +8 -8
  94. package/examples/__snapshots__/kubernetes-with-cloud-sql.ts.snap +8 -8
  95. package/examples/__snapshots__/kubernetes-with-jobs.ts.snap +16 -16
  96. package/examples/__snapshots__/kubernetes-with-mongodb.ts.snap +8 -8
  97. package/examples/__snapshots__/local-dot-env.ts.snap +8 -8
  98. package/examples/__snapshots__/meteor-kubernetes.ts.snap +8 -0
  99. package/examples/__snapshots__/multiline-var.ts.snap +16 -16
  100. package/examples/__snapshots__/native-app.ts.snap +24 -16
  101. package/examples/__snapshots__/node-build-with-custom-image.ts.snap +8 -8
  102. package/examples/__snapshots__/node-build-with-docker-additions.ts.snap +8 -8
  103. package/examples/__snapshots__/wait-for-other-deploy.ts.snap +16 -16
  104. package/examples/cloud-run-with-sql.ts +9 -2
  105. package/package.json +1 -1
  106. package/src/build/artifacts/createBuildJobArtifact.ts +61 -0
  107. package/src/build/base/createAppBuildJob.ts +26 -22
  108. package/src/build/base/index.ts +31 -4
  109. package/src/build/base/writeDotEnv.ts +6 -2
  110. package/src/build/custom/__tests__/testJob.test.ts +4 -4
  111. package/src/build/custom/buildJob.ts +2 -13
  112. package/src/build/docker.ts +6 -8
  113. package/src/build/index.ts +39 -7
  114. package/src/build/node/buildJob.ts +68 -56
  115. package/src/build/node/cache.ts +17 -8
  116. package/src/build/node/index.ts +4 -2
  117. package/src/build/node/meteor.ts +3 -9
  118. package/src/build/node/testJob.ts +21 -7
  119. package/src/build/node/yarn.ts +2 -2
  120. package/src/build/rails/build.ts +14 -4
  121. package/src/build/rails/test.ts +9 -1
  122. package/src/build/sbom.ts +7 -2
  123. package/src/build/types.ts +68 -4
  124. package/src/context/createAllComponentsContext.ts +31 -0
  125. package/src/context/createComponentContext.ts +59 -20
  126. package/src/context/createWorkspaceContext.ts +56 -0
  127. package/src/context/getBuildInfoVariables.ts +2 -1
  128. package/src/context/getEnvironmentContext.ts +2 -2
  129. package/src/context/getEnvironmentVariables.ts +12 -7
  130. package/src/context/getLabels.ts +3 -3
  131. package/src/deploy/base/deploy.ts +33 -7
  132. package/src/deploy/cloudRun/artifactsRegistry.ts +3 -4
  133. package/src/deploy/cloudRun/createJobs/common.ts +4 -4
  134. package/src/deploy/cloudRun/index.ts +68 -67
  135. package/src/deploy/custom/index.ts +2 -2
  136. package/src/deploy/dockerTag/index.ts +8 -7
  137. package/src/deploy/index.ts +11 -9
  138. package/src/deploy/kubernetes/additionalSecretKeys.ts +3 -1
  139. package/src/deploy/kubernetes/cloudSql/index.ts +1 -1
  140. package/src/deploy/kubernetes/deployJob.ts +2 -2
  141. package/src/deploy/kubernetes/index.ts +42 -41
  142. package/src/deploy/sbom.ts +9 -4
  143. package/src/pipeline/createAllJobs.ts +56 -55
  144. package/src/pipeline/createChildPipeline.ts +1 -0
  145. package/src/pipeline/createJobsForComponent.ts +5 -4
  146. package/src/pipeline/createJobsForWorkspace.ts +12 -0
  147. package/src/pipeline/createMainPipeline.ts +38 -23
  148. package/src/pipeline/gitlab/createGitlabJobs.ts +283 -119
  149. package/src/pipeline/packageManager.ts +25 -9
  150. package/src/types/config.ts +4 -1
  151. package/src/types/context.ts +108 -12
  152. package/src/types/environmentContext.ts +6 -7
  153. package/src/types/jobs.ts +3 -1
@@ -1,9 +1,9 @@
1
- import type { DeployTypeDefinition } from "..";
1
+ import type { DeployConfigCloudRun, DeployTypeDefinition } from "..";
2
2
  import {
3
- BashExpression,
4
3
  getBashVariable,
5
4
  joinBashExpressions,
6
5
  } from "../../bash/BashExpression";
6
+ import type { BuildConfig } from "../../build";
7
7
  import { getSecretVarName } from "../../context";
8
8
  import type { EnvironmentContext } from "../../types/environmentContext";
9
9
  import { sanitizeForBashVariable } from "../../utils/gitlab";
@@ -27,7 +27,7 @@ const getCloudSqlVariables = ({
27
27
  env,
28
28
  componentName,
29
29
  fullConfig,
30
- }: EnvironmentContext<any, "google-cloudrun">) => {
30
+ }: EnvironmentContext<BuildConfig, DeployConfigCloudRun>) => {
31
31
  if (deployConfigRaw && deployConfigRaw.cloudSql) {
32
32
  const DB_NAME = getFullDbName(
33
33
  deployConfigRaw.cloudSql,
@@ -56,71 +56,72 @@ const getCloudSqlVariables = ({
56
56
  }
57
57
  return {};
58
58
  };
59
- export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun"> = {
60
- jobs: createGoogleCloudRunDeployJobs,
61
- defaults: ({ deployConfigRaw, envType }) => {
62
- if (deployConfigRaw && deployConfigRaw.cloudSql) {
63
- return {
64
- cloudSql: {
65
- deleteDatabaseOnStop: envType === "review",
66
- },
67
- };
68
- }
69
- return {};
70
- },
71
- additionalSecretKeys: (ctx) => [
72
- {
73
- key: GCLOUD_DEPLOY_CREDENTIALS_KEY,
74
- hidden: true,
75
- },
76
- {
77
- key: GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
78
- hidden: true,
59
+ export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<DeployConfigCloudRun> =
60
+ {
61
+ jobs: createGoogleCloudRunDeployJobs,
62
+ defaults: ({ deployConfigRaw, envType }) => {
63
+ if (deployConfigRaw && deployConfigRaw.cloudSql) {
64
+ return {
65
+ cloudSql: {
66
+ deleteDatabaseOnStop: envType === "review",
67
+ },
68
+ };
69
+ }
70
+ return {};
79
71
  },
80
- ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql
81
- ? [{ key: "DB_PASSWORD" }]
82
- : []),
83
- ],
84
- getAdditionalEnvVars: (ctx) => {
85
- const { fullName, env, componentName, deployConfigRaw } = ctx;
72
+ additionalSecretKeys: (ctx) => [
73
+ {
74
+ key: GCLOUD_DEPLOY_CREDENTIALS_KEY,
75
+ hidden: true,
76
+ },
77
+ {
78
+ key: GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
79
+ hidden: true,
80
+ },
81
+ ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql
82
+ ? [{ key: "DB_PASSWORD" }]
83
+ : []),
84
+ ],
85
+ getAdditionalEnvVars: (ctx) => {
86
+ const { fullName, env, componentName, deployConfigRaw } = ctx;
86
87
 
87
- const HOST_INTERNAL = joinBashExpressions(
88
- [
89
- fullName,
90
- getBashVariable(
91
- getSecretVarName(
92
- env,
93
- componentName,
94
- GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
88
+ const HOST_INTERNAL = joinBashExpressions(
89
+ [
90
+ fullName,
91
+ getBashVariable(
92
+ getSecretVarName(
93
+ env,
94
+ componentName,
95
+ GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
96
+ ),
95
97
  ),
96
- ),
97
- ],
98
- "-",
99
- ).toLowerCase();
100
- const jobTriggers =
101
- deployConfigRaw && deployConfigRaw.jobs
102
- ? Object.fromEntries(
103
- Object.entries(deployConfigRaw.jobs).map(([name, job]) => [
104
- "CLOUD_RUN_JOB_TRIGGER_URL_" + sanitizeForBashVariable(name),
105
- `https://${
106
- deployConfigRaw.region
107
- }-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${
108
- deployConfigRaw.projectId
109
- }/jobs/${getCloudRunJobName(fullName, name)}:run`,
110
- ]),
111
- )
112
- : {};
98
+ ],
99
+ "-",
100
+ ).toLowerCase();
101
+ const jobTriggers =
102
+ deployConfigRaw && deployConfigRaw.jobs
103
+ ? Object.fromEntries(
104
+ Object.entries(deployConfigRaw.jobs).map(([name, job]) => [
105
+ "CLOUD_RUN_JOB_TRIGGER_URL_" + sanitizeForBashVariable(name),
106
+ `https://${
107
+ deployConfigRaw.region
108
+ }-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${
109
+ deployConfigRaw.projectId
110
+ }/jobs/${getCloudRunJobName(fullName, name)}:run`,
111
+ ]),
112
+ )
113
+ : {};
113
114
 
114
- return {
115
- HOST_INTERNAL,
116
- ...getCloudSqlVariables(ctx),
117
- ...jobTriggers,
118
- DEPLOY_CLOUD_RUN_PROJECT_ID: deployConfigRaw
119
- ? deployConfigRaw.projectId
120
- : undefined,
121
- DEPLOY_CLOUD_RUN_REGION: deployConfigRaw
122
- ? deployConfigRaw.region
123
- : undefined,
124
- };
125
- },
126
- };
115
+ return {
116
+ HOST_INTERNAL,
117
+ ...getCloudSqlVariables(ctx),
118
+ ...jobTriggers,
119
+ DEPLOY_CLOUD_RUN_PROJECT_ID: deployConfigRaw
120
+ ? deployConfigRaw.projectId
121
+ : undefined,
122
+ DEPLOY_CLOUD_RUN_REGION: deployConfigRaw
123
+ ? deployConfigRaw.region
124
+ : undefined,
125
+ };
126
+ },
127
+ };
@@ -1,7 +1,7 @@
1
- import type { DeployTypeDefinition } from "..";
1
+ import type { DeployConfigCustom, DeployTypeDefinition } from "..";
2
2
  import { createCustomDeployJobs } from "./deployJob";
3
3
 
4
- export const CUSTOM_DEPLOY_TYPE: DeployTypeDefinition<"custom"> = {
4
+ export const CUSTOM_DEPLOY_TYPE: DeployTypeDefinition<DeployConfigCustom> = {
5
5
  jobs: createCustomDeployJobs,
6
6
  defaults: () => ({}),
7
7
  additionalSecretKeys: () => [],
@@ -1,9 +1,10 @@
1
- import type { DeployTypeDefinition } from "..";
1
+ import type { DeployConfigDockerTag, DeployTypeDefinition } from "..";
2
2
  import { createDockerTagDeployJobs } from "./deployJob";
3
3
 
4
- export const DOCKER_TAG_DEPLOY_TYPE: DeployTypeDefinition<"dockerTag"> = {
5
- jobs: createDockerTagDeployJobs,
6
- defaults: () => ({}),
7
- additionalSecretKeys: () => [],
8
- getAdditionalEnvVars: () => ({}),
9
- };
4
+ export const DOCKER_TAG_DEPLOY_TYPE: DeployTypeDefinition<DeployConfigDockerTag> =
5
+ {
6
+ jobs: createDockerTagDeployJobs,
7
+ defaults: () => ({}),
8
+ additionalSecretKeys: () => [],
9
+ getAdditionalEnvVars: () => ({}),
10
+ };
@@ -1,4 +1,4 @@
1
- import type { SecretEnvVar } from "..";
1
+ import type { BuildConfig, SecretEnvVar } from "..";
2
2
  import type { BashExpression } from "../bash/BashExpression";
3
3
  import type { ComponentContext } from "../types/context";
4
4
  import type { EnvironmentContext } from "../types/environmentContext";
@@ -8,26 +8,28 @@ import { GCLOUD_RUN_DEPLOY_TYPE } from "./cloudRun";
8
8
  import { CUSTOM_DEPLOY_TYPE } from "./custom";
9
9
  import { DOCKER_TAG_DEPLOY_TYPE } from "./dockerTag";
10
10
  import { KUBERNETES_DEPLOY_TYPE } from "./kubernetes";
11
- import type { DeployConfigGeneric, DeployConfigType } from "./types";
11
+ import type {
12
+ DeployConfig,
13
+ DeployConfigGeneric,
14
+ DeployConfigType,
15
+ } from "./types";
12
16
  export * from "./cloudRun";
13
17
  export * from "./kubernetes";
14
18
  export * from "./types";
15
19
  export * from "./utils";
16
20
 
17
- export type DeployTypeDefinition<T extends DeployConfigType> = {
21
+ export type DeployTypeDefinition<D extends DeployConfig> = {
18
22
  jobs: (context: ComponentContext) => CatladderJob[];
19
- defaults: (
20
- envContext: EnvironmentContext<any, T>,
21
- ) => PartialDeep<DeployConfigGeneric<T>>;
23
+ defaults: (envContext: EnvironmentContext<BuildConfig, D>) => PartialDeep<D>;
22
24
  additionalSecretKeys: (
23
- envContext: EnvironmentContext<any, T>,
25
+ envContext: EnvironmentContext<BuildConfig, D>,
24
26
  ) => SecretEnvVar[];
25
27
  getAdditionalEnvVars: (
26
- envContext: EnvironmentContext<any, T>,
28
+ envContext: EnvironmentContext<BuildConfig, D>,
27
29
  ) => Record<string, string | BashExpression | undefined | null>;
28
30
  };
29
31
  export type DeployTypes = {
30
- [T in DeployConfigType]: DeployTypeDefinition<T>;
32
+ [T in DeployConfigType]: DeployTypeDefinition<DeployConfigGeneric<T>>;
31
33
  };
32
34
 
33
35
  export const DEPLOY_TYPES: DeployTypes = {
@@ -1,8 +1,10 @@
1
+ import type { BuildConfig } from "../../build";
1
2
  import type { EnvironmentContext } from "../../types/environmentContext";
3
+ import type { DeployConfigKubernetes } from "../types";
2
4
 
3
5
  export const additionalKubernetesSecretKeys = ({
4
6
  deployConfigRaw,
5
- }: EnvironmentContext<any, "kubernetes">) => {
7
+ }: EnvironmentContext<BuildConfig, DeployConfigKubernetes>) => {
6
8
  if (!deployConfigRaw) {
7
9
  return [];
8
10
  }
@@ -66,7 +66,7 @@ export const createKubernetesCloudsqlBaseValues = (
66
66
  config,
67
67
  context.fullConfig,
68
68
  context.environment.slugPrefix,
69
- context.componentName,
69
+ context.name,
70
70
  ),
71
71
  },
72
72
  };
@@ -39,14 +39,14 @@ export const createKubernetesDeployJobs = (
39
39
  ...context.environment.envVars,
40
40
  RELEASE_NAME: context.environment.fullName,
41
41
  HELM_EXPERIMENTAL_OCI: "1",
42
- KUBE_DOCKER_IMAGE_PULL_SECRET: `gitlab-registry-${context.componentName}`,
42
+ KUBE_DOCKER_IMAGE_PULL_SECRET: `gitlab-registry-${context.name}`,
43
43
  HELM_GITLAB_CHART_NAME:
44
44
  deployConfig.chartName ?? "/helm-charts/the-panter-chart",
45
45
  HELM_ARGS: [
46
46
  ...(deployConfig.debug ? ["--debug"] : []),
47
47
  ...(deployConfig.additionalHelmArgs ?? []),
48
48
  ].join(" "),
49
- COMPONENT_NAME: context.componentName,
49
+ COMPONENT_NAME: context.name,
50
50
  /** @deprecated */
51
51
  BUILD_ID: context.environment.envVars.BUILD_INFO_BUILD_ID,
52
52
  },
@@ -1,49 +1,50 @@
1
1
  import slugify from "slugify";
2
- import type { DeployTypeDefinition } from "..";
2
+ import type { DeployConfigKubernetes, DeployTypeDefinition } from "..";
3
3
  import { getKubernetesNamespace } from "..";
4
4
  import { joinBashExpressions } from "../../bash/BashExpression";
5
5
  import { additionalKubernetesSecretKeys } from "./additionalSecretKeys";
6
6
  import { createKubernetesDeployJobs } from "./deployJob";
7
7
  export * from "./cloudSql";
8
- export const KUBERNETES_DEPLOY_TYPE: DeployTypeDefinition<"kubernetes"> = {
9
- jobs: createKubernetesDeployJobs,
10
- defaults: () => ({}),
11
- additionalSecretKeys: additionalKubernetesSecretKeys,
12
- getAdditionalEnvVars: ({
13
- componentName,
14
- fullConfig,
15
- deployConfigRaw,
16
- env,
17
- reviewSlug,
18
- envType,
19
- }) => {
20
- const KUBE_APP_NAME_PREFIX =
21
- envType === "review" && reviewSlug ? reviewSlug.concat("-") : "";
22
- const KUBE_APP_NAME = KUBE_APP_NAME_PREFIX.concat(componentName);
23
- const KUBE_NAMESPACE = getKubernetesNamespace(fullConfig, env);
24
- const componentSlug = slugify(componentName);
8
+ export const KUBERNETES_DEPLOY_TYPE: DeployTypeDefinition<DeployConfigKubernetes> =
9
+ {
10
+ jobs: createKubernetesDeployJobs,
11
+ defaults: () => ({}),
12
+ additionalSecretKeys: additionalKubernetesSecretKeys,
13
+ getAdditionalEnvVars: ({
14
+ componentName,
15
+ fullConfig,
16
+ deployConfigRaw,
17
+ env,
18
+ reviewSlug,
19
+ envType,
20
+ }) => {
21
+ const KUBE_APP_NAME_PREFIX =
22
+ envType === "review" && reviewSlug ? reviewSlug.concat("-") : "";
23
+ const KUBE_APP_NAME = KUBE_APP_NAME_PREFIX.concat(componentName);
24
+ const KUBE_NAMESPACE = getKubernetesNamespace(fullConfig, env);
25
+ const componentSlug = slugify(componentName);
25
26
 
26
- const domainCanonical =
27
- (deployConfigRaw && deployConfigRaw.cluster?.domainCanonical) || // for convenience, we allow clusters to define a canonical domain, because a cluster has a fixed ip and you will usually have a domain pointing to that cluster
28
- fullConfig.domainCanonical ||
29
- "panter.cloud";
27
+ const domainCanonical =
28
+ (deployConfigRaw && deployConfigRaw.cluster?.domainCanonical) || // for convenience, we allow clusters to define a canonical domain, because a cluster has a fixed ip and you will usually have a domain pointing to that cluster
29
+ fullConfig.domainCanonical ||
30
+ "panter.cloud";
30
31
 
31
- const HOST_INTERNAL = joinBashExpressions(
32
- [
33
- componentSlug,
34
- ...(envType === "review" && reviewSlug ? [reviewSlug] : []),
35
- env,
36
- fullConfig.appName,
37
- fullConfig.customerName,
38
- domainCanonical,
39
- ],
40
- ".",
41
- ); // default for kubernetes and rest
42
- return {
43
- KUBE_NAMESPACE,
44
- KUBE_APP_NAME,
45
- KUBE_APP_NAME_PREFIX,
46
- HOST_INTERNAL,
47
- };
48
- },
49
- };
32
+ const HOST_INTERNAL = joinBashExpressions(
33
+ [
34
+ componentSlug,
35
+ ...(envType === "review" && reviewSlug ? [reviewSlug] : []),
36
+ env,
37
+ fullConfig.appName,
38
+ fullConfig.customerName,
39
+ domainCanonical,
40
+ ],
41
+ ".",
42
+ ); // default for kubernetes and rest
43
+ return {
44
+ KUBE_NAMESPACE,
45
+ KUBE_APP_NAME,
46
+ KUBE_APP_NAME_PREFIX,
47
+ HOST_INTERNAL,
48
+ };
49
+ },
50
+ };
@@ -1,8 +1,13 @@
1
- import type { ComponentContext } from "../types/context";
2
1
  import { SBOM_FILE } from "../build/sbom";
2
+ import {
3
+ componentContextIsStandaloneBuild,
4
+ type ComponentContext,
5
+ } from "../types/context";
3
6
 
4
7
  export const sbomDeactivated = (context: ComponentContext) =>
5
- context.build.config.type === "custom" && context.build.config.sbom === false;
8
+ componentContextIsStandaloneBuild(context) &&
9
+ context.build.config.type === "custom" &&
10
+ context.build.config.sbom === false;
6
11
 
7
12
  export const getDependencyTrackUploadScript = (
8
13
  context: ComponentContext,
@@ -11,7 +16,7 @@ export const getDependencyTrackUploadScript = (
11
16
  ? []
12
17
  : [
13
18
  "echo 'Uploading SBOM to Dependency Track'",
14
- `/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "${context.fullConfig.customerName}-${context.fullConfig.appName}/${context.componentName}" "${context.environment.url}" "${SBOM_FILE}" vex.json || true`,
19
+ `/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" upload "${context.fullConfig.customerName}-${context.fullConfig.appName}/${context.name}" "${context.environment.url}" "${SBOM_FILE}" vex.json || true`,
15
20
  ];
16
21
  };
17
22
 
@@ -22,6 +27,6 @@ export const getDependencyTrackDeleteScript = (
22
27
  ? []
23
28
  : [
24
29
  "echo 'Disabling component in Dependency Track'",
25
- `/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "${context.fullConfig.customerName}-${context.fullConfig.appName}/${context.componentName}" "${context.environment.url}" || true`,
30
+ `/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "${context.fullConfig.customerName}-${context.fullConfig.appName}/${context.name}" "${context.environment.url}" || true`,
26
31
  ];
27
32
  };
@@ -1,71 +1,72 @@
1
- import { getAllEnvsByTrigger } from "../config";
2
- import { createComponentContext } from "../context";
3
- import type {
4
- ComponentContext,
5
- Config,
6
- PipelineTrigger,
7
- PipelineType,
8
- } from "../types";
1
+ import type { CreateAllComponentsContextProps } from "../context/createAllComponentsContext";
2
+ import { createAllComponentsContext } from "../context/createAllComponentsContext";
3
+ import { createWorkspaceContext } from "../context/createWorkspaceContext";
4
+ import type { ComponentContext, WorkspaceContext } from "../types";
5
+ import { componentContextHasWorkspaceBuild } from "../types";
9
6
  import type { CatladderJob } from "../types/jobs";
10
7
  import { createJobsForComponentContext } from "./createJobsForComponent";
8
+ import { createJobsForWorkspace } from "./createJobsForWorkspace";
11
9
 
12
- export type AllCatladderJobs = Array<{
13
- context: ComponentContext;
14
- jobs: Array<CatladderJob>;
15
- }>;
16
-
17
- export type AllJobsContext = {
18
- config: Config;
19
- trigger: PipelineTrigger;
20
- pipelineType: PipelineType;
21
- };
22
-
23
- const createAllComponentContext = async ({
24
- config,
25
- trigger,
26
- pipelineType,
27
- }: AllJobsContext): Promise<
28
- Array<{
29
- env: string;
30
- componentName: string;
10
+ export type AllCatladderJobs = {
11
+ workspaces: Array<{
12
+ context: WorkspaceContext;
13
+ jobs: Array<CatladderJob>;
14
+ }>;
15
+ components: Array<{
31
16
  context: ComponentContext;
32
- }>
33
- > => {
34
- return await Promise.all(
35
- Object.keys(config.components).flatMap((componentName) => {
36
- const envs = getAllEnvsByTrigger(config, componentName, trigger);
37
- return envs.map(async (env) => {
38
- const context = await createComponentContext({
39
- config,
40
- componentName,
41
- env,
42
- trigger,
43
- pipelineType,
44
- });
45
-
46
- return {
47
- env,
48
- componentName,
49
- context,
50
- };
51
- });
52
- }),
53
- );
17
+ jobs: Array<CatladderJob>;
18
+ }>;
54
19
  };
55
20
 
56
21
  export const createAllJobs = async ({
57
22
  config,
58
23
  trigger,
59
24
  pipelineType,
60
- }: AllJobsContext): Promise<AllCatladderJobs> => {
61
- const allComponentContext = await createAllComponentContext({
25
+ }: CreateAllComponentsContextProps): Promise<AllCatladderJobs> => {
26
+ const allComponentsContext = await createAllComponentsContext({
62
27
  config,
63
28
  trigger,
64
29
  pipelineType,
65
30
  });
66
31
 
67
- return allComponentContext.map(({ context }) => ({
68
- context,
69
- jobs: createJobsForComponentContext(context),
70
- }));
32
+ return {
33
+ workspaces: await Promise.all(
34
+ Object.keys(config.builds ?? {}).map(async (workspaceName) => {
35
+ const componentsInAllEnvs = allComponentsContext.filter(
36
+ (context) =>
37
+ componentContextHasWorkspaceBuild(context) &&
38
+ context.build.workspaceName === workspaceName,
39
+ );
40
+
41
+ const allEnvs = [...new Set(componentsInAllEnvs.map(({ env }) => env))];
42
+
43
+ return await Promise.all(
44
+ allEnvs.map(async (env) => {
45
+ const workspaceContext = await createWorkspaceContext({
46
+ components: componentsInAllEnvs.filter(
47
+ ({ env: componentEnv }) => componentEnv === env,
48
+ ),
49
+ workspaceName,
50
+ config,
51
+ trigger,
52
+ pipelineType,
53
+ env,
54
+ });
55
+
56
+ return {
57
+ context: workspaceContext,
58
+ jobs: createJobsForWorkspace(workspaceContext),
59
+ };
60
+ }),
61
+ );
62
+ }),
63
+ ).then((f) => f.flat()),
64
+
65
+ components: allComponentsContext.map((context) => {
66
+ return {
67
+ context,
68
+ jobs: createJobsForComponentContext(context),
69
+ };
70
+ }),
71
+ };
71
72
  };
@@ -17,6 +17,7 @@ export const createChildPipeline = async <T extends PipelineType>(
17
17
  trigger,
18
18
  pipelineType,
19
19
  });
20
+
20
21
  const stages = getPipelineStages(config);
21
22
 
22
23
  if (pipelineType === "gitlab") {
@@ -24,10 +24,11 @@ const getCustomJobs = (context: ComponentContext) => {
24
24
  export const createJobsForComponentContext = (
25
25
  context: ComponentContext,
26
26
  ): CatladderJob[] => {
27
- const buildJobs = BUILD_TYPES[context.build.config.type].jobs(context);
28
- const deployJobs = context.deploy?.config
29
- ? DEPLOY_TYPES[context.deploy?.config.type].jobs(context)
30
- : [];
27
+ const buildJobs = BUILD_TYPES[context.build.buildType].jobs(context);
28
+ const deployJobs =
29
+ context.componentConfig.deploy !== false
30
+ ? DEPLOY_TYPES[context.componentConfig.deploy.type].jobs(context)
31
+ : [];
31
32
 
32
33
  const customJobs = getCustomJobs(context);
33
34
  return [...buildJobs, ...deployJobs, ...customJobs];
@@ -0,0 +1,12 @@
1
+ import { WORKSPACE_BUILD_TYPES } from "../build";
2
+ import type { WorkspaceContext } from "../types/context";
3
+ import type { CatladderJob } from "../types/jobs";
4
+
5
+ export const createJobsForWorkspace = (
6
+ context: WorkspaceContext,
7
+ ): CatladderJob[] => {
8
+ const buildJobs =
9
+ WORKSPACE_BUILD_TYPES[context.build.buildType].jobs(context);
10
+
11
+ return buildJobs;
12
+ };
@@ -5,11 +5,13 @@ import {
5
5
  RULE_NEVER_ON_RELEASE_COMMIT,
6
6
  } from "../rules";
7
7
  import type {
8
+ ComponentContext,
8
9
  GitlabJobDef,
9
10
  GitlabRule,
10
11
  Pipeline,
11
12
  PipelineTrigger,
12
13
  PipelineType,
14
+ WorkspaceContext,
13
15
  } from "../types";
14
16
  import { ALL_PIPELINE_TRIGGERS, type Config } from "../types/config";
15
17
  import { createAllJobs } from "./createAllJobs";
@@ -35,40 +37,53 @@ export const createMainPipeline = async <T extends PipelineType>(
35
37
  getGitlabRulesForTrigger(trigger),
36
38
  ),
37
39
  ),
38
- );
40
+ ).then((j) => j.flat());
41
+
42
+ const allWorkspaceJobs = allJobsPerTrigger
43
+ .filter((j) => j.context.type === "workspace") // sort by componentName in the same order as they appear in the config
44
+ // this is purely for better readability in git diffs when you add new components
45
+ .sort((a, b) => {
46
+ const workspaceNames = Object.keys(config.builds ?? {});
47
+ const aIndex = workspaceNames.findIndex(
48
+ (c) => c === (a.context as WorkspaceContext).name,
49
+ );
50
+ const bIndex = workspaceNames.findIndex(
51
+ (c) => c === (b.context as WorkspaceContext).name,
52
+ );
53
+ return aIndex - bIndex;
54
+ });
39
55
 
40
- const allJobs = allJobsPerTrigger
41
- .flat()
56
+ const allComponentJobs = allJobsPerTrigger
57
+ .filter((j) => j.context.type === "component")
42
58
  // sort by componentName in the same order as they appear in the config
43
59
  // this is purely for better readability in git diffs when you add new components
44
60
  .sort((a, b) => {
45
61
  const componentNames = Object.keys(config.components);
46
62
  const aIndex = componentNames.findIndex(
47
- (c) => c === a.context.componentName,
63
+ (c) => c === (a.context as ComponentContext).name,
48
64
  );
49
65
  const bIndex = componentNames.findIndex(
50
- (c) => c === b.context.componentName,
66
+ (c) => c === (b.context as ComponentContext).name,
51
67
  );
52
68
  return aIndex - bIndex;
53
- })
54
-
55
- .reduce(
56
- (acc, { gitlabJob, name }) => {
57
- // merge jobs, if a job is already there, merge the rules
58
- // this is currently needed because of envMode: "none", which creates the same job for all triggers, so it can appear multiple times
59
- if (acc[name]) {
60
- acc[name].rules = [
61
- ...(acc[name].rules ?? []),
62
- ...(gitlabJob.rules ?? []),
63
- ];
64
- } else {
65
- acc[name] = gitlabJob;
66
- }
69
+ });
70
+ const allJobs = [...allWorkspaceJobs, ...allComponentJobs].reduce(
71
+ (acc, { gitlabJob, name }) => {
72
+ // merge jobs, if a job is already there, merge the rules
73
+ // this is currently needed because of envMode: "none", which creates the same job for all triggers, so it can appear multiple times
74
+ if (acc[name]) {
75
+ acc[name].rules = [
76
+ ...(acc[name].rules ?? []),
77
+ ...(gitlabJob.rules ?? []),
78
+ ];
79
+ } else {
80
+ acc[name] = gitlabJob;
81
+ }
67
82
 
68
- return acc;
69
- },
70
- {} as { [key: string]: GitlabJobDef },
71
- );
83
+ return acc;
84
+ },
85
+ {} as { [key: string]: GitlabJobDef },
86
+ );
72
87
 
73
88
  return createGitlabPipelineWithDefaults({
74
89
  stages: [...stages, "release"],