@catladder/pipeline 1.153.1 → 1.154.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 (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 +4 -4
  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 +77 -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 -7
  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 -6
  130. package/src/context/getLabels.ts +2 -2
  131. package/src/deploy/base/deploy.ts +33 -7
  132. package/src/deploy/cloudRun/artifactsRegistry.ts +2 -3
  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 +105 -11
  152. package/src/types/environmentContext.ts +6 -7
  153. package/src/types/jobs.ts +3 -1
@@ -1,5 +1,5 @@
1
1
  import { BashExpression } from "../../bash/BashExpression";
2
- import type { BuildContext, ComponentContext, Context } from "../../types";
2
+ import type { Context } from "../../types";
3
3
  import { ensureArray } from "../../utils";
4
4
  import { collapseableSection } from "../../utils/gitlab";
5
5
 
@@ -32,7 +32,7 @@ export const getYarnInstall = (
32
32
  },
33
33
  ) => {
34
34
  const postInstall =
35
- "postInstall" in context.build.config
35
+ context.type !== "workspace" && "postInstall" in context.build.config
36
36
  ? context.build.config.postInstall
37
37
  : null;
38
38
  return [
@@ -1,6 +1,11 @@
1
- import type { ComponentContext } from "../..";
1
+ import {
2
+ componentContextIsStandaloneBuild,
3
+ type BuildConfigRails,
4
+ type BuildContextStandalone,
5
+ type ComponentContext,
6
+ } from "../..";
2
7
  import type { CatladderJob } from "../../types/jobs";
3
- import { createBuildJobs } from "../base";
8
+ import { createComponentBuildJobs } from "../base";
4
9
  import {
5
10
  getDockerBuildDefaultScript,
6
11
  gitlabDockerLogin,
@@ -17,8 +22,13 @@ export const createRailsBuildJobs = (
17
22
  throw new Error("build type is not rails");
18
23
  }
19
24
 
25
+ // if its not a standalone build, we don't need to run tests
26
+ if (!componentContextIsStandaloneBuild(context)) {
27
+ throw new Error("workspace builds are not supported for rails apps");
28
+ }
29
+
20
30
  if (hasDockerfile(context)) {
21
- return createBuildJobs(context, {
31
+ return createComponentBuildJobs(context, {
22
32
  appBuild: undefined,
23
33
  dockerBuild: {
24
34
  script: getDockerBuildDefaultScript(context),
@@ -32,7 +42,7 @@ export const createRailsBuildJobs = (
32
42
  const packEnvArgs = Object.entries(cnbConf?.buildVars ?? {})
33
43
  .map(([k, v]) => `--env '${k}${v ? `=${v}` : ""}'`)
34
44
  .join(" ");
35
- return createBuildJobs(context, {
45
+ return createComponentBuildJobs(context, {
36
46
  appBuild: undefined,
37
47
  dockerBuild: {
38
48
  variables: {
@@ -1,4 +1,7 @@
1
- import type { ComponentContext } from "../..";
1
+ import {
2
+ componentContextIsStandaloneBuild,
3
+ type ComponentContext,
4
+ } from "../..";
2
5
  import type { CatladderJob } from "../../types/jobs";
3
6
  import { ensureArray, notNil } from "../../utils";
4
7
 
@@ -11,6 +14,11 @@ export const createRailsTestJobs = (
11
14
  return [];
12
15
  }
13
16
 
17
+ // if its not a standalone build, we don't need to run tests
18
+ if (!componentContextIsStandaloneBuild(context)) {
19
+ return [];
20
+ }
21
+
14
22
  const buildConfig = context.build.config;
15
23
 
16
24
  const base: Omit<CatladderJob, "script" | "name"> = {
package/src/build/sbom.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { isStandaloneBuildConfig } from ".";
1
2
  import type { ComponentContext } from "../types/context";
2
3
  import type { CatladderJob } from "../types/jobs";
3
4
  import { ensureArray } from "../utils";
@@ -18,12 +19,16 @@ export const createSbomBuildJob = (context: ComponentContext): CatladderJob => {
18
19
  ];
19
20
 
20
21
  const image =
21
- buildConfig.type === "custom" && buildConfig.sbom !== false
22
+ isStandaloneBuildConfig(buildConfig) &&
23
+ buildConfig.type === "custom" &&
24
+ buildConfig.sbom !== false
22
25
  ? buildConfig.sbom?.jobImage ?? defaultImage
23
26
  : defaultImage;
24
27
 
25
28
  const script =
26
- buildConfig.type === "custom" && buildConfig.sbom !== false
29
+ isStandaloneBuildConfig(buildConfig) &&
30
+ buildConfig.type === "custom" &&
31
+ buildConfig.sbom !== false
27
32
  ? ensureArray(buildConfig.sbom?.command) ?? defaultScript
28
33
  : defaultScript;
29
34
 
@@ -129,6 +129,12 @@ export type BuildConfigMeteor = BuildConfigNodeBase & {
129
129
  docker?: Omit<BuildConfigDockerBuiltInMeteor, "type"> | BuildConfigDocker;
130
130
  };
131
131
 
132
+ export type BuildConfigNodeLike =
133
+ | BuildConfigNode
134
+ | BuildConfigNodeStatic
135
+ | BuildConfigStorybook
136
+ | BuildConfigMeteor;
137
+
132
138
  type BuildConfigDockerWithAdditions = {
133
139
  /**
134
140
  * Custom Dockerfile lines integrated in the generated Dockerfile before the standard build steps.
@@ -261,7 +267,18 @@ export type BuildConfigStorybook = BuildConfigNodeBase & {
261
267
  type: "storybook";
262
268
  startCommand?: never;
263
269
  };
264
- export type BuildConfig =
270
+
271
+ export type BuildConfigFromWorkspace = {
272
+ from: string;
273
+ docker?: BuildConfigDocker;
274
+ startCommand?: string;
275
+ /**
276
+ * additional paths for artifacts,
277
+ * by default "dist" and ".next" are allways included
278
+ */
279
+ artifactsPaths?: string[];
280
+ };
281
+ export type BuildConfigStandalone =
265
282
  | BuildConfigNode
266
283
  | BuildConfigNodeStatic
267
284
  | BuildConfigStorybook
@@ -269,16 +286,63 @@ export type BuildConfig =
269
286
  | BuildConfigCustom
270
287
  | BuildConfigRails;
271
288
 
272
- export type BuildConfigType = BuildConfig["type"];
289
+ export type BuildConfig = BuildConfigFromWorkspace | BuildConfigStandalone;
273
290
 
274
- export type BuildConfigGeneric<T extends BuildConfigType> = Extract<
291
+ export type BuildConfigStandaloneType = BuildConfigStandalone["type"];
292
+
293
+ export type BuildConfigGeneric<T extends BuildConfigStandaloneType> = Extract<
275
294
  BuildConfig,
276
295
  { type: T }
277
296
  >;
278
297
 
279
- export const isOfBuildType = <T extends Array<BuildConfigType>>(
298
+ export const isStandaloneBuildConfig = (
299
+ t: BuildConfig | false,
300
+ ): t is BuildConfigStandalone => {
301
+ if (!t) return false;
302
+ return !("from" in t);
303
+ };
304
+
305
+ export const isOfBuildType = <T extends Array<BuildConfigStandaloneType>>(
280
306
  t: BuildConfig,
281
307
  ...types: T
282
308
  ): t is Extract<BuildConfig, { type: T[number] }> => {
309
+ if (!isStandaloneBuildConfig(t)) return false;
283
310
  return types.includes(t.type);
284
311
  };
312
+
313
+ export type WorkspaceBuildConfigBase = {
314
+ dir?: string;
315
+ /**
316
+ * customize lint, set false to disable
317
+ */
318
+ lint?: false | TestJobCustom;
319
+
320
+ /**
321
+ * customize test, set false to disable
322
+ */
323
+ test?: false | TestJobCustom;
324
+
325
+ /**
326
+ * customize audit, set false to disable
327
+ */
328
+ audit?: false | TestJobCustom;
329
+ /**
330
+ * additional vars only for the runner.
331
+ * Also if you use services: that require env vars, you need to set them here.
332
+ *
333
+ */
334
+ runnerVariables?: Record<string, string>;
335
+
336
+ /**
337
+ * additional CI/CD artifacts reports,
338
+ * use to display information in merge requests, pipeline views and security dashboards.
339
+ */
340
+ artifactsReports?: BuildConfigArtifactsReports;
341
+ };
342
+
343
+ export type WorkspaceBuildConfigNode = {
344
+ type: "node";
345
+ buildCommand?: string | string[];
346
+ } & WorkspaceBuildConfigBase;
347
+
348
+ export type WorkspaceBuildConfig = WorkspaceBuildConfigNode;
@@ -0,0 +1,31 @@
1
+ import { getAllEnvsByTrigger } from "../config/configruedEnvs";
2
+ import type { ComponentContext, PipelineType } from "../types";
3
+ import type { Config, PipelineTrigger } from "../types/config";
4
+ import { createComponentContext } from "./createComponentContext";
5
+
6
+ export type CreateAllComponentsContextProps = {
7
+ config: Config;
8
+ trigger: PipelineTrigger;
9
+ pipelineType: PipelineType;
10
+ };
11
+
12
+ export const createAllComponentsContext = async ({
13
+ config,
14
+ trigger,
15
+ pipelineType,
16
+ }: CreateAllComponentsContextProps): Promise<Array<ComponentContext>> => {
17
+ return await Promise.all(
18
+ Object.keys(config.components).flatMap((componentName) => {
19
+ const envs = getAllEnvsByTrigger(config, componentName, trigger);
20
+ return envs.map(async (env) => {
21
+ return await createComponentContext({
22
+ config,
23
+ componentName,
24
+ env,
25
+ trigger,
26
+ pipelineType,
27
+ });
28
+ });
29
+ }),
30
+ );
31
+ };
@@ -1,16 +1,20 @@
1
1
  import { isFunction } from "lodash";
2
- import { BUILD_TYPES } from "../build";
3
- import type { BuildConfig, BuildConfigType } from "../build/types";
2
+ import { BUILD_TYPES, isStandaloneBuildConfig } from "../build";
3
+ import type { BuildConfig } from "../build/types";
4
4
  import { DEPLOY_TYPES } from "../deploy";
5
5
  import type { DeployConfig, DeployConfigType } from "../deploy/types";
6
+ import { getPackageManagerInfoForComponent } from "../pipeline/packageManager";
6
7
  import type { PipelineType } from "../types";
7
8
  import type { Config, PipelineTrigger } from "../types/config";
8
- import type { ComponentContext } from "../types/context";
9
+ import type {
10
+ BuildContext,
11
+ BuildContextComponent,
12
+ ComponentContext,
13
+ } from "../types/context";
9
14
  import type { PartialDeep } from "../types/utils";
10
15
  import { mergeWithMergingArrays } from "../utils";
11
16
  import { getEnvironment } from "./getEnvironment";
12
17
  import { getEnvironmentContext } from "./getEnvironmentContext";
13
- import { getPackageManagerInfoForComponent } from "../pipeline/packageManager";
14
18
 
15
19
  export type CreateComponentContextContext = {
16
20
  config: Config;
@@ -37,23 +41,30 @@ export const createComponentContext = async (
37
41
  const envContext = getEnvironmentContext(ctx);
38
42
 
39
43
  const componentConfigWithoutDefaults = envContext.envConfigRaw;
44
+
45
+ const resolvedBuildType = isStandaloneBuildConfig(
46
+ componentConfigWithoutDefaults.build,
47
+ )
48
+ ? componentConfigWithoutDefaults.build.type
49
+ : ctx.config.builds?.[componentConfigWithoutDefaults.build.from].type;
50
+ if (!resolvedBuildType) {
51
+ throw new Error("build type not found, is the build config correct?");
52
+ }
40
53
  const defaults: {
41
54
  build: PartialDeep<BuildConfig>;
42
55
  deploy: PartialDeep<DeployConfig>;
43
56
  } = componentConfigWithoutDefaults.deploy
44
57
  ? {
45
- build:
46
- BUILD_TYPES[
47
- componentConfigWithoutDefaults.build.type as BuildConfigType
48
- ].defaults(envContext),
58
+ build: BUILD_TYPES[resolvedBuildType].defaults(envContext),
49
59
  deploy: DEPLOY_TYPES[
50
60
  componentConfigWithoutDefaults.deploy.type as DeployConfigType
51
61
  ].defaults(envContext as any),
52
62
  }
53
63
  : {
54
- build: {},
64
+ build: BUILD_TYPES[resolvedBuildType].defaults(envContext),
55
65
  deploy: {},
56
66
  };
67
+
57
68
  const componentConfig = mergeWithMergingArrays(
58
69
  defaults,
59
70
  componentConfigWithoutDefaults,
@@ -61,21 +72,54 @@ export const createComponentContext = async (
61
72
 
62
73
  const environment = await getEnvironment(ctx);
63
74
  const { deploy, build, customJobs, dir } = componentConfig;
75
+ const getComponentDirs: BuildContext["getComponentDirs"] = (mode) => [
76
+ dir,
77
+ // also copy workspace dependencies in monorepo if packages are shared and they create build artifacts
78
+ ...(mode === "all"
79
+ ? packageManagerInfo.currentWorkspaceDependencies ?? []
80
+ : []),
81
+ ];
82
+ const _getBuildContext = (): BuildContextComponent => {
83
+ if (isStandaloneBuildConfig(build)) {
84
+ return {
85
+ dir: dir,
86
+ getComponentDirs,
87
+ config: build,
88
+ buildType: build.type,
89
+ type: "standalone",
90
+ };
91
+ }
92
+ // must be shared build
93
+ const referencedBuild = ctx.config.builds?.[build.from];
94
+ if (!referencedBuild) {
95
+ throw new Error("build.from not found in config");
96
+ }
97
+ return {
98
+ dir: dir,
99
+ getComponentDirs,
100
+ config: build,
101
+ workspaceBuildConfig: referencedBuild,
102
+ workspaceName: build.from,
103
+ buildType: referencedBuild.type,
104
+ type: "fromWorkspace",
105
+ };
106
+ };
107
+ const buildContext: BuildContextComponent = _getBuildContext();
64
108
  const context: Omit<ComponentContext, "customJobs"> = {
109
+ type: "component",
110
+ name: ctx.componentName,
111
+ componentName: ctx.componentName,
112
+ env: ctx.env,
65
113
  fullConfig: ctx.config,
66
114
  componentConfig,
67
- env: ctx.env,
68
115
 
69
- build: {
70
- dir: dir,
71
- config: build,
72
- },
116
+ build: buildContext,
73
117
  deploy: deploy
74
118
  ? {
75
119
  config: deploy,
76
120
  }
77
121
  : null,
78
- componentName: ctx.componentName,
122
+
79
123
  environment,
80
124
  packageManagerInfo: packageManagerInfo,
81
125
  pipelineType: ctx.pipelineType,
@@ -89,8 +133,3 @@ export const createComponentContext = async (
89
133
  customJobs: resolvedCustomJobs,
90
134
  };
91
135
  };
92
-
93
- /**
94
- * @deprecated use createComponentContext instead
95
- */
96
- export const createContext = createComponentContext;
@@ -0,0 +1,56 @@
1
+ import {
2
+ WORKSPACE_BUILD_TYPES,
3
+ type Config,
4
+ type PipelineTrigger,
5
+ type PipelineType,
6
+ type WorkspaceContext,
7
+ } from "..";
8
+ import { getPackageManagerInfoBase } from "../pipeline/packageManager";
9
+ import { mergeWithMergingArrays } from "../utils";
10
+ import { uniq } from "lodash";
11
+
12
+ export async function createWorkspaceContext({
13
+ env,
14
+ components,
15
+ workspaceName,
16
+ config,
17
+ pipelineType,
18
+ trigger,
19
+ }: {
20
+ env: string;
21
+ components: WorkspaceContext["components"];
22
+ workspaceName: string;
23
+ config: Config;
24
+ pipelineType: PipelineType;
25
+ trigger: PipelineTrigger;
26
+ }): Promise<WorkspaceContext> {
27
+ const workspaceConfigRaw = config.builds?.[workspaceName];
28
+ if (!workspaceConfigRaw) {
29
+ throw new Error(`Workspace ${workspaceName} not found in config`);
30
+ }
31
+
32
+ const defaults = WORKSPACE_BUILD_TYPES[workspaceConfigRaw.type].defaults();
33
+
34
+ const workspaceConfig = mergeWithMergingArrays(defaults, workspaceConfigRaw);
35
+ return {
36
+ name: workspaceName,
37
+ pipelineType,
38
+ trigger,
39
+ type: "workspace",
40
+
41
+ workspaceConfig,
42
+
43
+ env,
44
+ components,
45
+ fullConfig: config,
46
+ packageManagerInfo: await getPackageManagerInfoBase(),
47
+ build: {
48
+ type: "workspace",
49
+ dir: workspaceConfig.dir ?? ".",
50
+ getComponentDirs: (mode) =>
51
+ uniq(components.flatMap((c) => c.build.getComponentDirs(mode))),
52
+ buildType: workspaceConfig.type,
53
+ config: workspaceConfig,
54
+ },
55
+ };
56
+ }
@@ -1,6 +1,7 @@
1
1
  import { BashExpression } from "../bash/BashExpression";
2
2
  import type { BashExpressionPerPipelineType } from "../bash/bashExpressionPerPipelineType";
3
3
  import { getBashExpressionPerPipelineType } from "../bash/bashExpressionPerPipelineType";
4
+ import type { BuildConfig } from "../build";
4
5
  import type { EnvironmentContext } from "../types/environmentContext";
5
6
 
6
7
  const BUILD_TIME: BashExpressionPerPipelineType = {
@@ -20,7 +21,7 @@ const CURRENT_VERSION: BashExpressionPerPipelineType = {
20
21
  ),
21
22
  };
22
23
 
23
- export const getBuildInfoVariables = (ctx: EnvironmentContext<any, any>) => {
24
+ export const getBuildInfoVariables = (ctx: EnvironmentContext) => {
24
25
  const { pipelineType } = ctx;
25
26
 
26
27
  return {
@@ -1,4 +1,4 @@
1
- import type { CreateComponentContextContext } from "..";
1
+ import type { BuildConfig, CreateComponentContextContext } from "..";
2
2
  import type { StringOrBashExpression } from "../bash/BashExpression";
3
3
  import { joinBashExpressions } from "../bash/BashExpression";
4
4
 
@@ -22,7 +22,7 @@ export const getEnvironmentContext = ({
22
22
  componentName,
23
23
  config,
24
24
  pipelineType,
25
- }: CreateComponentContextContext): EnvironmentContext<any, any> => {
25
+ }: CreateComponentContextContext): EnvironmentContext => {
26
26
  const envConfigRaw = getEnvConfig(config, componentName, env);
27
27
  const envType = getEnvType(env, envConfigRaw);
28
28
  const reviewSlug = getReviewSlug(envConfigRaw, env, pipelineType);
@@ -8,7 +8,8 @@ import type { DevLocalEnvConfig } from "../types/config";
8
8
 
9
9
  import type { CreateComponentContextContext, UnspecifiedEnvVars } from "..";
10
10
  import type { StringOrBashExpression } from "../bash/BashExpression";
11
- import { getBashVariable, joinBashExpressions } from "../bash/BashExpression";
11
+ import { joinBashExpressions } from "../bash/BashExpression";
12
+ import { isStandaloneBuildConfig } from "../build/types";
12
13
  import type { EnvironmentContext } from "../types/environmentContext";
13
14
  import { getBuildInfoVariables } from "./getBuildInfoVariables";
14
15
  import { getEnvironmentContext } from "./getEnvironmentContext";
@@ -29,7 +30,7 @@ export type SecretEnvVar = {
29
30
  hidden?: boolean;
30
31
  };
31
32
 
32
- const getBasePredefinedVariables = (ctx: EnvironmentContext<any, any>) => {
33
+ const getBasePredefinedVariables = (ctx: EnvironmentContext) => {
33
34
  return {
34
35
  ENV_SHORT: ctx.env,
35
36
  APP_DIR: ctx.envConfigRaw.dir,
@@ -78,7 +79,8 @@ export const getEnvironmentVariables = async (
78
79
  ENV_SHORT: "local",
79
80
  ROOT_URL: url,
80
81
  // Rails before 6.1 (mis)uses the `HOST` environment variable to specify the IP to bind to
81
- ...(config.components[componentName].build.type === "rails"
82
+ ...(isStandaloneBuildConfig(buildConfigRaw) &&
83
+ buildConfigRaw.type === "rails"
82
84
  ? {}
83
85
  : { HOST: host }),
84
86
  HOST_INTERNAL: host,
@@ -101,7 +103,8 @@ export const getEnvironmentVariables = async (
101
103
  predefinedVariables = {
102
104
  ...basePredefinedVariables,
103
105
  // Rails before 6.1 (mis)uses the `HOST` environment variable to specify the IP to bind to
104
- ...(config.components[componentName].build.type === "rails"
106
+ ...(isStandaloneBuildConfig(buildConfigRaw) &&
107
+ buildConfigRaw.type === "rails"
105
108
  ? {}
106
109
  : { HOST: host }),
107
110
  ROOT_URL: url,
@@ -169,7 +172,10 @@ export const getEnvironmentVariables = async (
169
172
  build: await transformJobOnlyVars(
170
173
  env,
171
174
  componentName,
172
- (buildConfigRaw && buildConfigRaw.jobVars) || null,
175
+ (buildConfigRaw &&
176
+ isStandaloneBuildConfig(buildConfigRaw) &&
177
+ buildConfigRaw.jobVars) ||
178
+ null,
173
179
  ),
174
180
  deploy: await transformJobOnlyVars(
175
181
  env,
@@ -201,4 +207,4 @@ const addIndexVar = <V extends Record<string, unknown>>(
201
207
  export const getSecretVarNameForContext = (
202
208
  context: ComponentContext,
203
209
  key: string,
204
- ) => getSecretVarName(context.env, context.componentName, key);
210
+ ) => getSecretVarName(context.env, context.name, key);
@@ -10,11 +10,11 @@ const sanitize = (value?: string) => {
10
10
  export const getLabels = (context: ComponentContext) => {
11
11
  const labels = {
12
12
  "customer-name": sanitize(context.fullConfig.customerName),
13
- "component-name": sanitize(context.componentName),
13
+ "component-name": sanitize(context.name),
14
14
  "app-name": sanitize(context.fullConfig.appName),
15
15
  "env-type": sanitize(context.environment.envType),
16
16
  "env-name": sanitize(context.env),
17
- "build-type": sanitize(context.build.config?.type),
17
+ "build-type": sanitize(context.build.buildType),
18
18
  ...(context.fullConfig.meta?.labels ?? {}),
19
19
  };
20
20
  return labels;
@@ -3,8 +3,11 @@ import {
3
3
  requiresDockerBuild,
4
4
  } from "../../build/docker";
5
5
  import { SBOM_BUILD_JOB_NAME } from "../../build/sbom";
6
- import type { ComponentContext } from "../../types/context";
7
- import type { CatladderJob } from "../../types/jobs";
6
+ import {
7
+ componentContextHasWorkspaceBuild,
8
+ type ComponentContext,
9
+ } from "../../types/context";
10
+ import type { BaseStage, CatladderJob } from "../../types/jobs";
8
11
  import { sbomDeactivated } from "../sbom";
9
12
  import { contextIsStoppable } from "../utils";
10
13
  import { STOP_JOB_NAME } from "./stop";
@@ -74,15 +77,38 @@ export const createDeployJob = (
74
77
  ],
75
78
  // we don't want to deploy when there is a broken test
76
79
  needsStages: [
77
- {
78
- stage: "build",
79
- artifacts: hasDocker ? false : true, // we asume that no-docker deployments need build artifacts,
80
- },
80
+ ...(componentContextHasWorkspaceBuild(context)
81
+ ? hasDocker // docker build is per component,
82
+ ? [
83
+ // we don't need artifacts, but have to wait for the component build
84
+ {
85
+ stage: "build" as BaseStage,
86
+ artifacts: false,
87
+ },
88
+ ]
89
+ : [
90
+ {
91
+ // pick build artifacts from workspace build
92
+ stage: "build" as BaseStage,
93
+ artifacts: true,
94
+ workspaceName: context.build.workspaceName,
95
+ },
96
+ ]
97
+ : [
98
+ {
99
+ stage: "build" as BaseStage,
100
+ artifacts: hasDocker ? false : true, // we asume that no-docker deployments need build artifacts,
101
+ },
102
+ ]),
81
103
  {
82
104
  stage: "test",
83
105
  artifacts: false,
106
+ // use test from workspace build
107
+ workspaceName: componentContextHasWorkspaceBuild(context)
108
+ ? context.build.workspaceName
109
+ : undefined,
84
110
  },
85
- ], // workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/220758
111
+ ],
86
112
  when: whenDeploy === "auto" ? "on_success" : "manual",
87
113
 
88
114
  allow_failure: whenDeploy === "manual" ? true : false,
@@ -44,8 +44,7 @@ export const getArtifactsRegistryImageName = (
44
44
  const gcloudImagePath = [
45
45
  dockerUrl,
46
46
  context.env,
47
- context.componentName,
48
-
47
+ context.name,
49
48
  ...(context.environment.reviewSlug && !lecacyReviewImageName
50
49
  ? [context.environment.reviewSlug]
51
50
  : []),
@@ -58,7 +57,7 @@ export const getArtifactsRegistryBuildCacheImage = (
58
57
  ) => {
59
58
  const dockerUrl = getArtifactsRegistryDockerUrl(context);
60
59
  // does not include env, so that after merge, you might get more cache hits (review-->dev)
61
- const gcloudImagePath = [dockerUrl, "caches", context.componentName];
60
+ const gcloudImagePath = [dockerUrl, "caches", context.name];
62
61
  return gcloudImagePath.join("/");
63
62
  };
64
63
 
@@ -1,4 +1,4 @@
1
- import type { Context } from "../../../types/context";
1
+ import type { ComponentContext } from "../../../types/context";
2
2
 
3
3
  import { isOfDeployType } from "../../types";
4
4
  import type { DeployConfigCloudRun } from "../../types/googleCloudRun";
@@ -29,7 +29,7 @@ export const makeLabelString = (obj: Record<string, unknown>) =>
29
29
  .map(([key, value]) => `${key}=${value}`)
30
30
  .join(",");
31
31
 
32
- export const getCloudRunDeployConfig = (context: Context) => {
32
+ export const getCloudRunDeployConfig = (context: ComponentContext) => {
33
33
  const deployConfig = context.deploy?.config;
34
34
  if (!isOfDeployType(deployConfig, "google-cloudrun")) {
35
35
  // should not happen
@@ -38,7 +38,7 @@ export const getCloudRunDeployConfig = (context: Context) => {
38
38
  return deployConfig;
39
39
  };
40
40
 
41
- export function getCommonCloudRunArgs(context: Context) {
41
+ export function getCommonCloudRunArgs(context: ComponentContext) {
42
42
  const deployConfig = getCloudRunDeployConfig(context);
43
43
  return {
44
44
  project: deployConfig.projectId,
@@ -46,7 +46,7 @@ export function getCommonCloudRunArgs(context: Context) {
46
46
  };
47
47
  }
48
48
 
49
- export function getCommonDeployArgs(context: Context) {
49
+ export function getCommonDeployArgs(context: ComponentContext) {
50
50
  const commonArgs = getCommonCloudRunArgs(context);
51
51
  const deployConfig = getCloudRunDeployConfig(context);
52
52
  return {