@catladder/pipeline 2.0.5 → 2.2.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 (93) hide show
  1. package/dist/build/base/writeDotEnv.js +0 -1
  2. package/dist/build/docker.js +0 -1
  3. package/dist/build/node/meteor.js +0 -1
  4. package/dist/build/rails/test.js +0 -1
  5. package/dist/build/types.d.ts +1 -1
  6. package/dist/catladder-gitlab.js +2 -3
  7. package/dist/config/readConfig.js +0 -1
  8. package/dist/constants.js +1 -1
  9. package/dist/context/getEnvironmentVariables.d.ts +1 -1
  10. package/dist/context/getEnvironmentVariables.js +0 -1
  11. package/dist/context/getReviewSlug.js +0 -1
  12. package/dist/deploy/cloudRun/createJobs/index.js +0 -1
  13. package/dist/deploy/kubernetes/deployJob.js +0 -1
  14. package/dist/deploy/types/index.d.ts +3 -3
  15. package/dist/pipeline/createMainPipeline.js +20 -6
  16. package/dist/pipeline/generatePipelineFiles.d.ts +7 -40
  17. package/dist/pipeline/generatePipelineFiles.js +113 -49
  18. package/dist/pipeline/gitlab/createGitlabJobs.d.ts +6 -4
  19. package/dist/pipeline/gitlab/gitlabReleaseJobs.d.ts +0 -2
  20. package/dist/pipeline/gitlab/gitlabReleaseJobs.js +2 -4
  21. package/dist/pipeline/index.d.ts +0 -1
  22. package/dist/pipeline/index.js +0 -1
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/dist/types/config.d.ts +3 -3
  25. package/dist/types/gitlab-types.d.ts +2 -1
  26. package/dist/types/pipeline.d.ts +0 -1
  27. package/dist/utils/writeFiles.js +0 -2
  28. package/dist/variables/__tests__/resolveAllReferences.test.js +0 -1
  29. package/dist/variables/__tests__/resolveReferencesOnce.test.js +0 -3
  30. package/examples/__snapshots__/cloud-run-http2.test.ts.snap +0 -2
  31. package/examples/__snapshots__/cloud-run-memory-limit.test.ts.snap +0 -2
  32. package/examples/__snapshots__/cloud-run-meteor-with-worker.test.ts.snap +0 -2
  33. package/examples/__snapshots__/cloud-run-nextjs.test.ts.snap +0 -2
  34. package/examples/__snapshots__/cloud-run-no-cpu-throttling.test.ts.snap +0 -2
  35. package/examples/__snapshots__/cloud-run-no-service.test.ts.snap +0 -2
  36. package/examples/__snapshots__/cloud-run-non-public.test.ts.snap +0 -2
  37. package/examples/__snapshots__/cloud-run-post-stop-job.test.ts.snap +0 -2
  38. package/examples/__snapshots__/cloud-run-service-custom-vpc-connector.test.ts.snap +0 -2
  39. package/examples/__snapshots__/cloud-run-service-custom-vpc.test.ts.snap +0 -2
  40. package/examples/__snapshots__/cloud-run-service-gen2.test.ts.snap +0 -2
  41. package/examples/__snapshots__/cloud-run-service-increase-timout.test.ts.snap +0 -2
  42. package/examples/__snapshots__/cloud-run-service-with-volumes.test.ts.snap +0 -2
  43. package/examples/__snapshots__/cloud-run-storybook.test.ts.snap +0 -2
  44. package/examples/__snapshots__/cloud-run-with-ngnix.test.ts.snap +0 -2
  45. package/examples/__snapshots__/cloud-run-with-sql-reuse-db.test.ts.snap +0 -2
  46. package/examples/__snapshots__/cloud-run-with-sql.test.ts.snap +0 -2
  47. package/examples/__snapshots__/cloud-run-with-worker.test.ts.snap +0 -2
  48. package/examples/__snapshots__/custom-build-job-with-tests.test.ts.snap +0 -2
  49. package/examples/__snapshots__/custom-build-job.test.ts.snap +0 -2
  50. package/examples/__snapshots__/custom-deploy.test.ts.snap +0 -2
  51. package/examples/__snapshots__/custom-envs.test.ts.snap +0 -2
  52. package/examples/__snapshots__/custom-sbom-java.test.ts.snap +0 -2
  53. package/examples/__snapshots__/git-submodule.test.ts.snap +0 -2
  54. package/examples/__snapshots__/kubernetes-application-customization.test.ts.snap +0 -2
  55. package/examples/__snapshots__/kubernetes-with-cloud-sql.test.ts.snap +0 -2
  56. package/examples/__snapshots__/kubernetes-with-jobs.test.ts.snap +0 -2
  57. package/examples/__snapshots__/kubernetes-with-mongodb.test.ts.snap +0 -2
  58. package/examples/__snapshots__/local-dot-env.test.ts.snap +0 -2
  59. package/examples/__snapshots__/meteor-kubernetes.test.ts.snap +0 -2
  60. package/examples/__snapshots__/multiline-var.test.ts.snap +0 -2
  61. package/examples/__snapshots__/native-app.test.ts.snap +0 -2
  62. package/examples/__snapshots__/node-build-with-custom-image.test.ts.snap +0 -2
  63. package/examples/__snapshots__/node-build-with-docker-additions.test.ts.snap +0 -2
  64. package/examples/__snapshots__/rails-k8s-with-worker-dockerfile.test.ts.snap +0 -2
  65. package/examples/__snapshots__/rails-k8s-with-worker.test.ts.snap +0 -2
  66. package/examples/__snapshots__/referencing-other-vars.test.ts.snap +0 -2
  67. package/examples/__snapshots__/wait-for-other-deploy.test.ts.snap +0 -2
  68. package/examples/__snapshots__/workspace-api-www-turbo-cache.test.ts.snap +0 -2
  69. package/examples/__snapshots__/workspace-api-www.test.ts.snap +0 -2
  70. package/examples/__utils__/helpers.ts +2 -18
  71. package/examples/rails-k8s-with-worker-dockerfile.test.ts +11 -4
  72. package/package.json +16 -17
  73. package/src/build/cache/createJobCache.ts +2 -2
  74. package/src/build/sbom.ts +2 -2
  75. package/src/catladder-gitlab.ts +2 -9
  76. package/src/config/readConfig.ts +0 -1
  77. package/src/context/createComponentContext.ts +1 -1
  78. package/src/context/getEnvironmentVariables.ts +1 -1
  79. package/src/deploy/base/deploy.ts +3 -3
  80. package/src/deploy/cloudRun/createJobs/cloudRunServices.ts +1 -1
  81. package/src/pipeline/createMainPipeline.ts +17 -9
  82. package/src/pipeline/generatePipelineFiles.ts +82 -58
  83. package/src/pipeline/gitlab/createGitlabJobs.ts +4 -4
  84. package/src/pipeline/gitlab/gitlabReleaseJobs.ts +2 -4
  85. package/src/pipeline/index.ts +0 -1
  86. package/src/types/gitlab-types.ts +2 -1
  87. package/src/types/pipeline.ts +0 -4
  88. package/dist/pipeline/createChildPipeline.d.ts +0 -3
  89. package/dist/pipeline/createChildPipeline.js +0 -163
  90. package/dist/pipeline/gitlab/getPipelineTriggerForGitlabChildPipeline.d.ts +0 -1
  91. package/dist/pipeline/gitlab/getPipelineTriggerForGitlabChildPipeline.js +0 -29
  92. package/src/pipeline/createChildPipeline.ts +0 -37
  93. package/src/pipeline/gitlab/getPipelineTriggerForGitlabChildPipeline.ts +0 -46
@@ -1,27 +1,11 @@
1
1
  import { stringify } from "yaml";
2
2
 
3
3
  import type { Config } from "../../src";
4
- import {
5
- createChildPipeline,
6
- generateLocalPipelineContent,
7
- yamlStringifyOptions,
8
- } from "../../src";
9
-
10
- const ALL_TRIGGERS = ["mainBranch", "taggedRelease", "mr"] as const;
11
-
12
- export const createAllPipelines = async (config: Config) =>
13
- Object.fromEntries(
14
- await Promise.all(
15
- ALL_TRIGGERS.map(async (trigger) => [
16
- trigger,
17
- await createChildPipeline("gitlab", trigger, config),
18
- ]),
19
- ),
20
- );
4
+ import { getGitlabCompletePipeline, yamlStringifyOptions } from "../../src";
21
5
 
22
6
  export const createYamlLocalPipeline = async (
23
7
  config: Config,
24
8
  ): Promise<string> => {
25
- const pipelineContent = await generateLocalPipelineContent(config, "gitlab");
9
+ const pipelineContent = await getGitlabCompletePipeline(config);
26
10
  return stringify(pipelineContent, yamlStringifyOptions);
27
11
  };
@@ -1,4 +1,4 @@
1
- import { mkdirSync, rmSync, writeFileSync } from "fs";
1
+ import { mkdir, rm, writeFile } from "fs/promises";
2
2
  import { createYamlLocalPipeline } from "./__utils__/helpers";
3
3
  import config from "./rails-k8s-with-worker";
4
4
  import { merge } from "lodash";
@@ -6,8 +6,15 @@ import { join } from "path";
6
6
 
7
7
  it("matches snapshot with a Dockerfile", async () => {
8
8
  const appDir = ".temp-with-dockerfile";
9
- mkdirSync(appDir);
10
- writeFileSync(join(appDir, "Dockerfile"), "");
9
+ try {
10
+ await rm(appDir, {
11
+ recursive: true,
12
+ });
13
+ } catch (e) {
14
+ // ignore
15
+ }
16
+ await mkdir(appDir);
17
+ await writeFile(join(appDir, "Dockerfile"), "");
11
18
  expect(
12
19
  await createYamlLocalPipeline(
13
20
  merge(config, {
@@ -20,7 +27,7 @@ it("matches snapshot with a Dockerfile", async () => {
20
27
  ),
21
28
  ).toMatchSnapshot();
22
29
 
23
- rmSync(appDir, {
30
+ await rm(appDir, {
24
31
  recursive: true,
25
32
  });
26
33
  });
package/package.json CHANGED
@@ -53,7 +53,7 @@
53
53
  }
54
54
  ],
55
55
  "license": "MIT",
56
- "version": "2.0.5",
56
+ "version": "2.2.0",
57
57
  "scripts": {
58
58
  "build:tsc": "yarn tsc",
59
59
  "build": "yarn build:compile && yarn build:inline-variables",
@@ -69,28 +69,27 @@
69
69
  "main": "dist/index.js",
70
70
  "sideEffects": false,
71
71
  "devDependencies": {
72
- "@babel/cli": "^7.16.0",
73
- "@babel/core": "^7.0.0-0",
74
- "@babel/plugin-syntax-typescript": "^7.16.7",
75
- "@babel/preset-typescript": "^7.16.5",
76
- "@jest/globals": "^29.3.1",
77
- "@types/child-process-promise": "^2.2.2",
78
- "@types/jest": "^27.4.0",
79
- "@types/lodash": "^4.14.185",
80
- "@types/node": "^20.14.2",
72
+ "@babel/cli": "^7.24.8",
73
+ "@babel/core": "^7.25.2",
74
+ "@babel/plugin-syntax-typescript": "^7.25.4",
75
+ "@babel/preset-typescript": "^7.24.7",
76
+ "@jest/globals": "^29.7.0",
77
+ "@types/child-process-promise": "^2.2.6",
78
+ "@types/jest": "^29.5.12",
79
+ "@types/lodash": "^4.17.7",
80
+ "@types/node": "^22.5.1",
81
81
  "babel-plugin-transform-inline-environment-variables": "^0.4.3",
82
82
  "child-process-promise": "^2.2.1",
83
- "glob": "^10.4.2",
83
+ "glob": "^11.0.0",
84
84
  "json-schema-to-typescript": "^13.0.2",
85
85
  "lodash": "^4.17.21",
86
- "memoizee": "^0.4.15",
87
- "path-equal": "1.1.3",
88
- "slugify": "^1.6.3",
89
- "tsx": "^4.16.2",
86
+ "memoizee": "^0.4.17",
87
+ "path-equal": "1.2.5",
88
+ "slugify": "^1.6.6",
90
89
  "typescript": "^5.4.5",
91
- "yaml": "^2.4.5"
90
+ "yaml": "^2.5.0"
92
91
  },
93
92
  "dependencies": {
94
- "tsx": "^4.16.2"
93
+ "tsx": "^4.19.0"
95
94
  }
96
95
  }
@@ -30,7 +30,7 @@ export const createJobCacheFromCacheConfigs = (
30
30
  const baseDir =
31
31
  c.pathMode === "absolute"
32
32
  ? ""
33
- : c.baseDir ?? context.build.dir;
33
+ : (c.baseDir ?? context.build.dir);
34
34
  return join(baseDir, p);
35
35
  }),
36
36
  ),
@@ -41,7 +41,7 @@ export const createJobCacheFromCacheConfigs = (
41
41
  const advancedCaches = advancedCacheDefs.map(
42
42
  ({ key, paths, policy, scope, pathMode, buildDir, ...rest }) => {
43
43
  const baseDir =
44
- pathMode === "absolute" ? "" : buildDir ?? context.build.dir;
44
+ pathMode === "absolute" ? "" : (buildDir ?? context.build.dir);
45
45
  const transformedKey =
46
46
  scope === "global"
47
47
  ? key
package/src/build/sbom.ts CHANGED
@@ -22,14 +22,14 @@ export const createSbomBuildJob = (context: ComponentContext): CatladderJob => {
22
22
  isStandaloneBuildConfig(buildConfig) &&
23
23
  buildConfig.type === "custom" &&
24
24
  buildConfig.sbom !== false
25
- ? buildConfig.sbom?.jobImage ?? defaultImage
25
+ ? (buildConfig.sbom?.jobImage ?? defaultImage)
26
26
  : defaultImage;
27
27
 
28
28
  const script =
29
29
  isStandaloneBuildConfig(buildConfig) &&
30
30
  buildConfig.type === "custom" &&
31
31
  buildConfig.sbom !== false
32
- ? ensureArrayOrNull(buildConfig.sbom?.command) ?? defaultScript
32
+ ? (ensureArrayOrNull(buildConfig.sbom?.command) ?? defaultScript)
33
33
  : defaultScript;
34
34
 
35
35
  return {
@@ -1,17 +1,10 @@
1
1
  import { readConfig } from "./config";
2
2
  import { generatePipelineFiles } from "./pipeline/generatePipelineFiles";
3
- import type { PipelineMode } from "./types";
4
3
 
5
- const mode = process.argv[2] || "local";
6
-
7
- const config = readConfig().then(async (result) => {
4
+ readConfig().then(async (result) => {
8
5
  if (!result?.config) {
9
6
  throw new Error("no catladder config found");
10
7
  }
11
8
 
12
- await generatePipelineFiles(
13
- result.config,
14
- "gitlab",
15
- mode as PipelineMode<"gitlab">,
16
- );
9
+ await generatePipelineFiles(result.config, "gitlab");
17
10
  });
@@ -1,6 +1,5 @@
1
1
  import { existsSync, readFileSync } from "fs";
2
2
 
3
- // eslint-disable-next-line @typescript-eslint/no-var-requires
4
3
  const tsx = require("tsx/cjs/api");
5
4
 
6
5
  import { parse } from "yaml";
@@ -76,7 +76,7 @@ export const createComponentContext = async (
76
76
  dir,
77
77
  // also copy workspace dependencies in monorepo if packages are shared and they create build artifacts
78
78
  ...(mode === "all"
79
- ? packageManagerInfo.currentWorkspaceDependencies ?? []
79
+ ? (packageManagerInfo.currentWorkspaceDependencies ?? [])
80
80
  : []),
81
81
  ];
82
82
  const _getBuildContext = (): BuildContextComponent => {
@@ -134,7 +134,7 @@ export const getEnvironmentVariables = async (
134
134
  );
135
135
 
136
136
  const publicEnvVars =
137
- options.shouldResolveReferences ?? true
137
+ (options.shouldResolveReferences ?? true)
138
138
  ? await resolveAllReferences(
139
139
  publicEnvVarsUnresolved,
140
140
  async (otherComponentName) => {
@@ -62,11 +62,11 @@ export const createDeployJob = (
62
62
  ? []
63
63
  : [{ job: SBOM_BUILD_JOB_NAME, artifacts: true }]),
64
64
  ...(deployConfig
65
- ? deployConfig.waitFor?.map((c) => ({
65
+ ? (deployConfig.waitFor?.map((c) => ({
66
66
  componentName: c,
67
67
  job: DEPLOY_JOB_NAME,
68
68
  artifacts: false,
69
- })) ?? []
69
+ })) ?? [])
70
70
  : []),
71
71
  ],
72
72
  // we don't want to deploy when there is a broken test
@@ -117,7 +117,7 @@ export const createDeployJob = (
117
117
  runnerVariables: {
118
118
  ...DEPLOY_RUNNER_VARIABLES,
119
119
  ...(jobDefinition.runnerVariables ?? {}),
120
- ...(deployConfig ? deployConfig.runnerVariables ?? {} : {}),
120
+ ...(deployConfig ? (deployConfig.runnerVariables ?? {}) : {}),
121
121
  },
122
122
  environment: isStoppable
123
123
  ? {
@@ -25,7 +25,7 @@ export const getServiceDeployScript = (
25
25
  const customConfig = service !== true ? service : undefined;
26
26
  const command =
27
27
  service !== true
28
- ? service?.command ?? context.build.config.startCommand
28
+ ? (service?.command ?? context.build.config.startCommand)
29
29
  : undefined;
30
30
 
31
31
  const commandArray = command
@@ -6,7 +6,6 @@ import {
6
6
  } from "../rules";
7
7
  import type {
8
8
  ComponentContext,
9
- GitlabJobDef,
10
9
  GitlabRule,
11
10
  Pipeline,
12
11
  PipelineTrigger,
@@ -16,6 +15,7 @@ import type {
16
15
  import { ALL_PIPELINE_TRIGGERS, type Config } from "../types/config";
17
16
  import { createAllJobs } from "./createAllJobs";
18
17
  import { getPipelineStages } from "./getPipelineStages";
18
+ import type { GitlabJobWithContext } from "./gitlab/createGitlabJobs";
19
19
  import { createGitlabJobs } from "./gitlab/createGitlabJobs";
20
20
  import { createGitlabPipelineWithDefaults } from "./gitlab/createGitlabPipeline";
21
21
  import { getGitlabReleaseJobs } from "./gitlab/gitlabReleaseJobs";
@@ -40,7 +40,7 @@ export const createMainPipeline = async <T extends PipelineType>(
40
40
  ).then((j) => j.flat());
41
41
 
42
42
  const allWorkspaceJobs = allJobsPerTrigger
43
- .filter((j) => j.context.type === "workspace") // sort by componentName in the same order as they appear in the config
43
+ .filter((j) => j.context?.type === "workspace") // sort by componentName in the same order as they appear in the config
44
44
  // this is purely for better readability in git diffs when you add new components
45
45
  .sort((a, b) => {
46
46
  const workspaceNames = Object.keys(config.builds ?? {});
@@ -54,7 +54,7 @@ export const createMainPipeline = async <T extends PipelineType>(
54
54
  });
55
55
 
56
56
  const allComponentJobs = allJobsPerTrigger
57
- .filter((j) => j.context.type === "component")
57
+ .filter((j) => j.context?.type === "component")
58
58
  // sort by componentName in the same order as they appear in the config
59
59
  // this is purely for better readability in git diffs when you add new components
60
60
  .sort((a, b) => {
@@ -68,28 +68,36 @@ export const createMainPipeline = async <T extends PipelineType>(
68
68
  return aIndex - bIndex;
69
69
  });
70
70
  const allJobs = [...allWorkspaceJobs, ...allComponentJobs].reduce(
71
- (acc, { gitlabJob, name }) => {
71
+ (acc, { gitlabJob, name, context }) => {
72
72
  // merge jobs, if a job is already there, merge the rules
73
73
  // this is currently needed because of envMode: "none", which creates the same job for all triggers, so it can appear multiple times
74
74
  if (acc[name]) {
75
- acc[name].rules = [
76
- ...(acc[name].rules ?? []),
75
+ acc[name].gitlabJob.rules = [
76
+ ...(acc[name].gitlabJob.rules ?? []),
77
77
  ...(gitlabJob.rules ?? []),
78
78
  ];
79
79
  } else {
80
- acc[name] = gitlabJob;
80
+ acc[name] = { context, gitlabJob };
81
81
  }
82
82
 
83
83
  return acc;
84
84
  },
85
- {} as { [key: string]: GitlabJobDef },
85
+ {} as { [key: string]: GitlabJobWithContext },
86
86
  );
87
87
 
88
88
  return createGitlabPipelineWithDefaults({
89
89
  stages: [...stages, "release"],
90
90
  jobs: {
91
91
  ...allJobs,
92
- ...getGitlabReleaseJobs(),
92
+ ...Object.fromEntries(
93
+ Object.entries(getGitlabReleaseJobs()).map(([name, gitlabJob]) => [
94
+ name,
95
+ {
96
+ gitlabJob,
97
+ context: null,
98
+ },
99
+ ]),
100
+ ),
93
101
  },
94
102
  variables: config.runnerVariables,
95
103
  }) as Pipeline<T>;
@@ -1,76 +1,100 @@
1
- import type { Config, PipelineMode, PipelineType } from "../types";
1
+ import { mkdir, rm } from "fs/promises";
2
+ import { dirname } from "path";
3
+ import type { Config, GitlabJobDef, PipelineType } from "../types";
2
4
  import { writeYamlfile } from "../utils/writeFiles";
3
- import { createChildPipeline } from "./createChildPipeline";
4
5
  import { createMainPipeline } from "./createMainPipeline";
5
- import { getPipelineTriggerForGitlabChildPipeline } from "./gitlab/getPipelineTriggerForGitlabChildPipeline";
6
6
  import { sortGitLabJobDefProps } from "./gitlab/sortGitLabJobDefProps";
7
7
 
8
- export async function generateChildPipelineContent<T extends PipelineType>(
8
+ const CATLADDER_GENERATED_FOLDER = ".catladder-generated";
9
+
10
+ const GITLAB_GENERATED_FOLDER = CATLADDER_GENERATED_FOLDER + "/gitlab";
11
+
12
+ type YamlFile = {
13
+ path: string;
14
+ content: Record<string, unknown>;
15
+ };
16
+ export async function generatePipelineFiles<T extends PipelineType>(
9
17
  config: Config,
10
18
  pipelineType: T,
11
19
  ) {
12
- const trigger = getPipelineTriggerForGitlabChildPipeline();
13
- const { jobs, image, stages, variables, workflow, ...pipelineRest } =
14
- await createChildPipeline(pipelineType, trigger, config);
15
-
16
- const jobsWithSortedProps = Object.fromEntries(
17
- Object.entries(jobs).map(([jobName, job]) => [
18
- jobName,
19
- sortGitLabJobDefProps(job),
20
- ]),
21
- );
20
+ if (pipelineType !== "gitlab") {
21
+ throw new Error("Pipeline type not supported");
22
+ }
23
+ const includes = await getGitlabPipelineIncludes(config);
22
24
 
23
- return {
24
- image,
25
- stages,
26
- variables,
27
- workflow,
28
- ...pipelineRest,
29
- // jobs need to be spread into main YAML, because GitLab pipeline YAML has no jobs key - jobs are top level with their key as their name
30
- ...jobsWithSortedProps,
25
+ const mainFile: YamlFile = {
26
+ path: ".gitlab-ci.yml",
27
+ content: {
28
+ include: includes.map((i) => i.path),
29
+ },
31
30
  };
32
- }
33
31
 
34
- export async function generateLocalPipelineContent<T extends PipelineType>(
35
- config: Config,
36
- pipelineType: T,
37
- ) {
32
+ const files = [mainFile, ...includes];
33
+
34
+ // first clean up the folder
35
+ await rm(GITLAB_GENERATED_FOLDER, { recursive: true });
36
+ // write files
37
+ await Promise.all(
38
+ files.map(async ({ path, content }) => {
39
+ await mkdir(dirname(path), { recursive: true });
40
+ await writeYamlfile(path, content);
41
+ }),
42
+ );
43
+ }
44
+ async function getGitlabPipelineIncludes(config: Config) {
38
45
  const { jobs, image, stages, variables, workflow, ...pipelineRest } =
39
- await createMainPipeline(pipelineType, config);
46
+ await createMainPipeline("gitlab", config);
47
+ // we will create 1 include per component or workspace
48
+ // this is for better readability in git diffs and to avoid problems with yaml files beeing too large
49
+ // group by context
50
+ const groups = Object.entries(jobs).reduce(
51
+ (acc, [jobName, { gitlabJob, context }]) => {
52
+ const group = !context
53
+ ? "global-jobs"
54
+ : context?.type + "/" + context.name;
55
+ if (!acc[group]) {
56
+ acc[group] = {};
57
+ }
40
58
 
41
- const jobsWithSortedProps = Object.fromEntries(
42
- Object.entries(jobs).map(([jobName, job]) => [
43
- jobName,
44
- sortGitLabJobDefProps(job),
45
- ]),
59
+ acc[group][jobName] = sortGitLabJobDefProps(gitlabJob); // also sort properties for more consistent diffing
60
+ return acc;
61
+ },
62
+ {} as Record<string, Record<string, GitlabJobDef>>,
46
63
  );
47
64
 
48
- return {
49
- image,
50
- stages,
51
- variables,
52
- workflow,
53
- ...pipelineRest,
54
- // jobs need to be spread into main YAML, because GitLab pipeline YAML has no jobs key - jobs are top level with their key as their name
55
- ...jobsWithSortedProps,
65
+ const componentIncludes = Object.entries(groups).map(([group, jobs]) => {
66
+ return {
67
+ path: GITLAB_GENERATED_FOLDER + "/" + group + ".yaml",
68
+ content: jobs,
69
+ };
70
+ });
71
+
72
+ const mainInclude: YamlFile = {
73
+ path: GITLAB_GENERATED_FOLDER + "/main.yaml",
74
+ content: {
75
+ image,
76
+ stages,
77
+ variables,
78
+ workflow,
79
+ ...pipelineRest,
80
+ },
56
81
  };
82
+
83
+ const includes = [mainInclude, ...componentIncludes];
84
+ return includes;
57
85
  }
58
86
 
59
- export async function generatePipelineFiles<T extends PipelineType>(
60
- config: Config,
61
- pipelineType: T,
62
- mode: PipelineMode<T>,
63
- ) {
64
- if (mode === "childpipeline") {
65
- const pipelineContent = await generateChildPipelineContent(
66
- config,
67
- pipelineType,
68
- );
69
- return writeYamlfile(`__pipeline.yml`, pipelineContent);
70
- }
71
- const pipelineContent = await generateLocalPipelineContent(
72
- config,
73
- pipelineType,
74
- );
75
- return writeYamlfile(`.gitlab-ci.yml`, pipelineContent);
87
+ /**
88
+ *
89
+ * for testing purposes
90
+ */
91
+ export async function getGitlabCompletePipeline(config: Config) {
92
+ const includes = await getGitlabPipelineIncludes(config);
93
+
94
+ return includes.reduce((acc, { content }) => {
95
+ return {
96
+ ...acc,
97
+ ...content, // merge all includes into one object
98
+ };
99
+ }, {});
76
100
  }
@@ -14,11 +14,11 @@ import { collapseableSection } from "../../utils/gitlab";
14
14
  import { removeUndefined } from "../../utils/removeUndefined";
15
15
  import type { AllCatladderJobs } from "../createAllJobs";
16
16
 
17
- export type AllGitlabJobs = {
18
- name: string;
17
+ export type GitlabJobWithContext = {
19
18
  gitlabJob: GitlabJobDef;
20
- context: Context;
21
- }[];
19
+ context: Context | null;
20
+ };
21
+ export type AllGitlabJobs = (GitlabJobWithContext & { name: string })[];
22
22
 
23
23
  export const GITLAB_ENVIRONMENT_URL_VARIABLE = "CL_GITLAB_ENVIRONMENT_URL";
24
24
  const getFullJobName = ({
@@ -9,15 +9,13 @@ export const getGitlabReleaseJobs = () => {
9
9
  ["create release"]: {
10
10
  stage: "release",
11
11
  image: getRunnerImage("semantic-release"),
12
- script: ["semanticRelease"],
13
- after_script: [EXPIRED_TOKEN_HELP],
12
+ script: ["semanticRelease", EXPIRED_TOKEN_HELP],
14
13
  rules: RULES_RELEASE,
15
14
  },
16
15
  ["⚠️ force create release"]: {
17
16
  stage: "release",
18
17
  image: getRunnerImage("semantic-release"),
19
- script: ["semanticRelease"],
20
- after_script: [EXPIRED_TOKEN_HELP],
18
+ script: ["semanticRelease", EXPIRED_TOKEN_HELP],
21
19
  needs: [],
22
20
  rules: RULES_MANUAL_RELEASE,
23
21
  },
@@ -1,4 +1,3 @@
1
- export * from "./createChildPipeline";
2
1
  export * from "./createJobsForComponent";
3
2
  export * from "./generatePipelineFiles";
4
3
  export * from "./gitlab/gitlabReleaseJobs";
@@ -1,3 +1,4 @@
1
+ import type { GitlabJobWithContext } from "../pipeline/gitlab/createGitlabJobs";
1
2
  import type {
2
3
  Artifacts as GitlabCiArtifacts,
3
4
  JobTemplate,
@@ -65,6 +66,6 @@ export interface GitlabPipeline extends Pick<JobTemplate, "variables"> {
65
66
  rules: GitlabRule[];
66
67
  };
67
68
  stages: string[];
68
- jobs: Record<string, GitlabJobDef>;
69
+ jobs: Record<string, GitlabJobWithContext>;
69
70
  before_script?: string[];
70
71
  }
@@ -2,10 +2,6 @@ import type { GitlabJobDef, GitlabPipeline } from "./gitlab-types";
2
2
 
3
3
  export type PipelineType = "gitlab";
4
4
 
5
- export type PipelineMode<T extends PipelineType> = T extends "gitlab"
6
- ? "childpipeline" | "local"
7
- : "local";
8
-
9
5
  export type PipelineJob<T extends PipelineType> = T extends "gitlab"
10
6
  ? GitlabJobDef
11
7
  : never;
@@ -1,3 +0,0 @@
1
- import type { Pipeline } from "../types";
2
- import type { Config, PipelineTrigger } from "../types/config";
3
- export declare const createChildPipeline: <T extends "gitlab">(pipelineType: T, trigger: PipelineTrigger, config: Config) => Promise<Pipeline<T>>;