@catladder/pipeline 1.110.1 → 1.110.3
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.
- package/dist/build/base/__tests__/createArtifactsConfig.test.d.ts +1 -0
- package/dist/build/base/__tests__/createArtifactsConfig.test.js +40 -0
- package/dist/build/base/createArtifactsConfig.d.ts +4 -0
- package/dist/build/base/createArtifactsConfig.js +63 -0
- package/dist/build/custom/__tests__/testJob.test.d.ts +1 -0
- package/dist/build/custom/__tests__/testJob.test.js +37 -0
- package/dist/build/custom/buildJob.js +4 -2
- package/dist/build/custom/testJob.d.ts +5 -1
- package/dist/build/custom/testJob.js +10 -23
- package/dist/build/node/buildJob.js +4 -2
- package/dist/build/node/testJob.js +12 -11
- package/dist/build/rails/build.js +13 -2
- package/dist/build/sbom.d.ts +5 -0
- package/dist/build/sbom.js +29 -0
- package/dist/build/types.d.ts +39 -40
- package/dist/bundles/catladder-gitlab/index.js +3 -3
- package/dist/constants.js +1 -1
- package/dist/deploy/base.js +38 -2
- package/dist/deploy/cloudRun/deployJob.js +5 -4
- package/dist/deploy/custom/deployJob.js +3 -2
- package/dist/deploy/kubernetes/deployJob.js +3 -2
- package/dist/deploy/sbom.d.ts +4 -0
- package/dist/deploy/sbom.js +17 -0
- package/dist/pipeline/createJobsForComponent.js +1 -3
- package/dist/pipeline/gitlab/createGitlabJobs.js +5 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/gitlab-types.d.ts +13 -22
- package/examples/__snapshots__/cloud-run-memory-limit.ts.snap +40 -96
- package/examples/__snapshots__/cloud-run-no-cpu-throttling.ts.snap +40 -96
- package/examples/__snapshots__/cloud-run-non-public.ts.snap +40 -96
- package/examples/__snapshots__/cloud-run-with-sql-reuse-db.ts.snap +80 -192
- package/examples/__snapshots__/cloud-run-with-sql.ts.snap +80 -192
- package/examples/__snapshots__/custom-build-job-with-tests.ts.snap +40 -96
- package/examples/__snapshots__/custom-build-job.ts.snap +40 -96
- package/examples/__snapshots__/custom-deploy.ts.snap +40 -96
- package/examples/__snapshots__/custom-envs.ts.snap +6 -126
- package/examples/__snapshots__/custom-sbom-java.ts.snap +40 -96
- package/examples/__snapshots__/kubernetes-application-customization.ts.snap +40 -96
- package/examples/__snapshots__/kubernetes-with-cloud-sql-legacy.ts.snap +40 -96
- package/examples/__snapshots__/kubernetes-with-cloud-sql.ts.snap +40 -96
- package/examples/__snapshots__/kubernetes-with-jobs.ts.snap +80 -192
- package/examples/__snapshots__/kubernetes-with-mongodb.ts.snap +40 -96
- package/examples/__snapshots__/native-app.ts.snap +72 -192
- package/examples/__snapshots__/node-build-with-custom-image.ts.snap +40 -96
- package/examples/__snapshots__/rails-k8s-with-worker.ts.snap +40 -96
- package/examples/__snapshots__/wait-for-other-deploy.ts.snap +64 -192
- package/package.json +1 -1
- package/src/build/base/__tests__/__snapshots__/createArtifactsConfig.test.ts.snap +49 -0
- package/src/build/base/__tests__/createArtifactsConfig.test.ts +41 -0
- package/src/build/base/createArtifactsConfig.ts +34 -0
- package/src/build/custom/__tests__/testJob.test.ts +32 -0
- package/src/build/custom/buildJob.ts +3 -0
- package/src/build/custom/testJob.ts +8 -21
- package/src/build/node/buildJob.ts +3 -0
- package/src/build/node/testJob.ts +16 -0
- package/src/build/rails/build.ts +3 -0
- package/src/build/sbom.ts +43 -0
- package/src/build/types.ts +45 -46
- package/src/deploy/base.ts +14 -7
- package/src/deploy/cloudRun/deployJob.ts +6 -0
- package/src/deploy/custom/deployJob.ts +9 -1
- package/src/deploy/kubernetes/deployJob.ts +10 -1
- package/src/deploy/sbom.ts +24 -0
- package/src/pipeline/createJobsForComponent.ts +1 -3
- package/src/pipeline/gitlab/createGitlabJobs.ts +6 -2
- package/src/types/gitlab-types.ts +12 -12
- package/dist/verify/reporting.d.ts +0 -3
- package/dist/verify/reporting.js +0 -48
- package/src/verify/reporting.ts +0 -69
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { join } from "path";
|
|
2
1
|
import type { Context } from "../../types/context";
|
|
3
2
|
import type { CatladderJob } from "../../types/jobs";
|
|
4
3
|
import { ensureArray, notNil } from "../../utils";
|
|
5
4
|
import { isOfBuildType } from "../types";
|
|
6
|
-
import type { BuildConfigArtifactsReports } from "../types";
|
|
7
5
|
import type { Artifacts } from "../../types";
|
|
6
|
+
import { createArtifactsConfig } from "../base/createArtifactsConfig";
|
|
8
7
|
|
|
9
8
|
const RUNNER_CUSTOM_TEST_VARIABLES = {
|
|
10
9
|
KUBERNETES_CPU_REQUEST: "0.5",
|
|
@@ -48,7 +47,8 @@ export const createCustomTestJobs = (context: Context): CatladderJob[] => {
|
|
|
48
47
|
allow_failure: true,
|
|
49
48
|
...createArtifactsConfig(
|
|
50
49
|
context.componentConfig.dir,
|
|
51
|
-
buildConfig.audit?.artifactsReports
|
|
50
|
+
buildConfig.audit?.artifactsReports,
|
|
51
|
+
buildConfig.audit?.artifacts
|
|
52
52
|
),
|
|
53
53
|
}
|
|
54
54
|
: null;
|
|
@@ -62,7 +62,8 @@ export const createCustomTestJobs = (context: Context): CatladderJob[] => {
|
|
|
62
62
|
script: [...(ensureArray(buildConfig.lint?.command) ?? [])],
|
|
63
63
|
...createArtifactsConfig(
|
|
64
64
|
context.componentConfig.dir,
|
|
65
|
-
buildConfig.lint?.artifactsReports
|
|
65
|
+
buildConfig.lint?.artifactsReports,
|
|
66
|
+
buildConfig.lint?.artifacts
|
|
66
67
|
),
|
|
67
68
|
}
|
|
68
69
|
: null;
|
|
@@ -75,30 +76,16 @@ export const createCustomTestJobs = (context: Context): CatladderJob[] => {
|
|
|
75
76
|
script: [...(ensureArray(buildConfig.test?.command) ?? [])],
|
|
76
77
|
...createArtifactsConfig(
|
|
77
78
|
context.componentConfig.dir,
|
|
78
|
-
buildConfig.test?.artifactsReports
|
|
79
|
+
buildConfig.test?.artifactsReports,
|
|
80
|
+
buildConfig.test?.artifacts
|
|
79
81
|
),
|
|
80
82
|
}
|
|
81
83
|
: null;
|
|
82
84
|
return [auditJob, lintJob, testJob].filter(notNil);
|
|
83
85
|
};
|
|
84
86
|
|
|
85
|
-
type OptionalArtifacts =
|
|
87
|
+
export type OptionalArtifacts =
|
|
86
88
|
| {
|
|
87
89
|
artifacts: Artifacts;
|
|
88
90
|
}
|
|
89
91
|
| undefined;
|
|
90
|
-
|
|
91
|
-
const createArtifactsConfig = (
|
|
92
|
-
rootPath: string,
|
|
93
|
-
artifactsReports?: BuildConfigArtifactsReports
|
|
94
|
-
): OptionalArtifacts =>
|
|
95
|
-
artifactsReports
|
|
96
|
-
? {
|
|
97
|
-
artifacts: {
|
|
98
|
-
paths: [],
|
|
99
|
-
reports: {
|
|
100
|
-
junit: artifactsReports?.junit?.map((p) => join(rootPath, p)) ?? [],
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
}
|
|
104
|
-
: undefined;
|
|
@@ -10,6 +10,8 @@ import { NODE_RUNNER_BUILD_VARIABLES } from "./constants";
|
|
|
10
10
|
import { getDockerAppCopyAndBuildScript, getYarnInstall } from "./yarn";
|
|
11
11
|
import type { CatladderJob } from "../../types/jobs";
|
|
12
12
|
import { getRunnerImage } from "../../runner";
|
|
13
|
+
import { createSbomBuildJob } from "../sbom";
|
|
14
|
+
import { sbomDeactivated } from "../../deploy/sbom";
|
|
13
15
|
|
|
14
16
|
export const createNodeBuildJobs = (context: Context): CatladderJob[] => {
|
|
15
17
|
const buildConfig = context.componentConfig.build;
|
|
@@ -76,5 +78,6 @@ export const createNodeBuildJobs = (context: Context): CatladderJob[] => {
|
|
|
76
78
|
}),
|
|
77
79
|
]
|
|
78
80
|
: []),
|
|
81
|
+
...(sbomDeactivated(context) ? [] : [createSbomBuildJob(context)]),
|
|
79
82
|
];
|
|
80
83
|
};
|
|
@@ -5,6 +5,7 @@ import { ensureArray, notNil } from "../../utils";
|
|
|
5
5
|
import { getNodeCache } from "./cache";
|
|
6
6
|
import { NODE_RUNNER_BUILD_VARIABLES } from "./constants";
|
|
7
7
|
import { getYarnInstall } from "./yarn";
|
|
8
|
+
import { createArtifactsConfig } from "../base/createArtifactsConfig";
|
|
8
9
|
|
|
9
10
|
export const createNodeTestJobs = (context: Context): CatladderJob[] => {
|
|
10
11
|
// don't run tests after release
|
|
@@ -42,6 +43,11 @@ export const createNodeTestJobs = (context: Context): CatladderJob[] => {
|
|
|
42
43
|
]),
|
|
43
44
|
],
|
|
44
45
|
allow_failure: true,
|
|
46
|
+
...createArtifactsConfig(
|
|
47
|
+
context.componentConfig.dir,
|
|
48
|
+
buildConfig.audit?.artifactsReports,
|
|
49
|
+
buildConfig.audit?.artifacts
|
|
50
|
+
),
|
|
45
51
|
}
|
|
46
52
|
: null;
|
|
47
53
|
|
|
@@ -57,6 +63,11 @@ export const createNodeTestJobs = (context: Context): CatladderJob[] => {
|
|
|
57
63
|
...yarnInstall,
|
|
58
64
|
...(ensureArray(buildConfig.lint?.command) ?? ["yarn lint"]),
|
|
59
65
|
],
|
|
66
|
+
...createArtifactsConfig(
|
|
67
|
+
context.componentConfig.dir,
|
|
68
|
+
buildConfig.lint?.artifactsReports,
|
|
69
|
+
buildConfig.lint?.artifacts
|
|
70
|
+
),
|
|
60
71
|
}
|
|
61
72
|
: null;
|
|
62
73
|
const testJob: CatladderJob | null =
|
|
@@ -73,6 +84,11 @@ export const createNodeTestJobs = (context: Context): CatladderJob[] => {
|
|
|
73
84
|
...yarnInstall,
|
|
74
85
|
...(ensureArray(buildConfig.test?.command) ?? ["yarn test"]),
|
|
75
86
|
],
|
|
87
|
+
...createArtifactsConfig(
|
|
88
|
+
context.componentConfig.dir,
|
|
89
|
+
buildConfig.test?.artifactsReports,
|
|
90
|
+
buildConfig.test?.artifacts
|
|
91
|
+
),
|
|
76
92
|
}
|
|
77
93
|
: null;
|
|
78
94
|
return [auditJob, lintJob, testJob].filter(notNil);
|
package/src/build/rails/build.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { Context } from "../..";
|
|
|
2
2
|
import { isOfBuildType } from "../types";
|
|
3
3
|
import type { CatladderJob } from "../../types/jobs";
|
|
4
4
|
import { createDockerBuildJobBase, gitlabDockerLogin } from "../docker";
|
|
5
|
+
import { sbomDeactivated } from "../../deploy/sbom";
|
|
6
|
+
import { createSbomBuildJob } from "../sbom";
|
|
5
7
|
|
|
6
8
|
export const createRailsBuildJobs = (context: Context): CatladderJob[] => {
|
|
7
9
|
const buildConfig = context.componentConfig.build;
|
|
@@ -37,5 +39,6 @@ export const createRailsBuildJobs = (context: Context): CatladderJob[] => {
|
|
|
37
39
|
}`,
|
|
38
40
|
],
|
|
39
41
|
}),
|
|
42
|
+
...(sbomDeactivated(context) ? [] : [createSbomBuildJob(context)]),
|
|
40
43
|
];
|
|
41
44
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Context } from "../types/context";
|
|
2
|
+
import type { CatladderJob } from "../types/jobs";
|
|
3
|
+
import { ensureArray } from "../utils";
|
|
4
|
+
|
|
5
|
+
export const SBOM_BUILD_JOB_NAME = "🧾 sbom";
|
|
6
|
+
export const SBOM_FILE = "__sbom.json";
|
|
7
|
+
|
|
8
|
+
export const createSbomBuildJob = (context: Context): CatladderJob => {
|
|
9
|
+
const buildConfig = context.componentConfig.build;
|
|
10
|
+
|
|
11
|
+
const defaultImage = "aquasec/trivy:0.38.3";
|
|
12
|
+
const defaultScript = [
|
|
13
|
+
`trivy fs --quiet --format cyclonedx --output "${SBOM_FILE}" ${
|
|
14
|
+
context.packageManagerInfo?.componentIsInWorkspace
|
|
15
|
+
? "."
|
|
16
|
+
: context.componentConfig.dir
|
|
17
|
+
}`,
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const image =
|
|
21
|
+
buildConfig.type === "custom" && buildConfig.sbom !== false
|
|
22
|
+
? buildConfig.sbom?.jobImage ?? defaultImage
|
|
23
|
+
: defaultImage;
|
|
24
|
+
|
|
25
|
+
const script =
|
|
26
|
+
buildConfig.type === "custom" && buildConfig.sbom !== false
|
|
27
|
+
? ensureArray(buildConfig.sbom?.command) ?? defaultScript
|
|
28
|
+
: defaultScript;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
name: SBOM_BUILD_JOB_NAME,
|
|
32
|
+
stage: "build",
|
|
33
|
+
envMode: "jobPerEnv",
|
|
34
|
+
variables: {},
|
|
35
|
+
cache: undefined,
|
|
36
|
+
image,
|
|
37
|
+
script,
|
|
38
|
+
allow_failure: true,
|
|
39
|
+
artifacts: {
|
|
40
|
+
paths: [SBOM_FILE],
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
package/src/build/types.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Artifacts,
|
|
3
|
+
EnvVars,
|
|
4
|
+
GitlabJobImage,
|
|
5
|
+
GitlabJobService,
|
|
6
|
+
} from "../types";
|
|
2
7
|
|
|
3
8
|
import type { CatladderJob } from "../types/jobs";
|
|
4
9
|
|
|
@@ -12,6 +17,22 @@ export type BuildConfigArtifactsReports = {
|
|
|
12
17
|
junit?: string[];
|
|
13
18
|
};
|
|
14
19
|
|
|
20
|
+
export type TestJobCustom = {
|
|
21
|
+
command?: string | string[];
|
|
22
|
+
jobImage?: GitlabJobImage;
|
|
23
|
+
/**
|
|
24
|
+
* additional CI/CD artifacts reports,
|
|
25
|
+
* use to display information in merge requests, pipeline views and security dashboards.
|
|
26
|
+
*/
|
|
27
|
+
artifactsReports?: BuildConfigArtifactsReports;
|
|
28
|
+
/**
|
|
29
|
+
* GitLab {@link Artifacts} configuration.
|
|
30
|
+
*
|
|
31
|
+
* {@link TestJobCustom.artifacts}.reports.junit is merged with {@link TestJobCustom.artifactsReports} in case both given.
|
|
32
|
+
*/
|
|
33
|
+
artifacts?: Artifacts;
|
|
34
|
+
};
|
|
35
|
+
|
|
15
36
|
export type BuildConfigBase = {
|
|
16
37
|
/**
|
|
17
38
|
* command to run on the image to start the app (e.g. yarn start)
|
|
@@ -38,39 +59,38 @@ export type BuildConfigBase = {
|
|
|
38
59
|
* customize docker build
|
|
39
60
|
*/
|
|
40
61
|
docker?: {
|
|
62
|
+
/**
|
|
63
|
+
* Custom Dockerfile lines integrated in the generated Dockerfile before the standard build steps.
|
|
64
|
+
*
|
|
65
|
+
* - [runner-images/docker-build/scripts/ensureNodeDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureNodeDockerfile)
|
|
66
|
+
* - [runner-images/docker-build/scripts/ensureNginxDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureNginxDockerfile)
|
|
67
|
+
* - [runner-images/docker-build/scripts/ensureMeteorDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureMeteorDockerfile)
|
|
68
|
+
*/
|
|
41
69
|
additionsBegin?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Custom Dockerfile lines integrated in the generated Dockerfile after the standard build steps.
|
|
72
|
+
*
|
|
73
|
+
* - [runner-images/docker-build/scripts/ensureNodeDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureNodeDockerfile)
|
|
74
|
+
* - [runner-images/docker-build/scripts/ensureNginxDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureNginxDockerfile)
|
|
75
|
+
* - [runner-images/docker-build/scripts/ensureMeteorDockerfile](https://git.panter.ch/catladder/catladder/-/tree/main/runner-images/docker-build/scripts/ensureMeteorDockerfile)
|
|
76
|
+
*/
|
|
42
77
|
additionsEnd?: string[];
|
|
43
78
|
};
|
|
44
79
|
|
|
45
80
|
/**
|
|
46
81
|
* customize lint, set false to disable
|
|
47
82
|
*/
|
|
48
|
-
lint?:
|
|
49
|
-
| false
|
|
50
|
-
| {
|
|
51
|
-
command?: string | string[];
|
|
52
|
-
jobImage?: GitlabJobImage;
|
|
53
|
-
};
|
|
83
|
+
lint?: false | TestJobCustom;
|
|
54
84
|
|
|
55
85
|
/**
|
|
56
86
|
* customize test, set false to disable
|
|
57
87
|
*/
|
|
58
|
-
test?:
|
|
59
|
-
| false
|
|
60
|
-
| {
|
|
61
|
-
command?: string | string[];
|
|
62
|
-
jobImage?: GitlabJobImage;
|
|
63
|
-
};
|
|
88
|
+
test?: false | TestJobCustom;
|
|
64
89
|
|
|
65
90
|
/**
|
|
66
91
|
* customize audit, set false to disable
|
|
67
92
|
*/
|
|
68
|
-
audit?:
|
|
69
|
-
| false
|
|
70
|
-
| {
|
|
71
|
-
command?: string | string[];
|
|
72
|
-
jobImage?: GitlabJobImage;
|
|
73
|
-
};
|
|
93
|
+
audit?: false | TestJobCustom;
|
|
74
94
|
|
|
75
95
|
/**
|
|
76
96
|
* additional paths for artifacts,
|
|
@@ -147,6 +167,9 @@ export type BuildConfigCustom = Omit<
|
|
|
147
167
|
> & {
|
|
148
168
|
type: "custom";
|
|
149
169
|
jobImage: GitlabJobImage;
|
|
170
|
+
/**
|
|
171
|
+
* {@link GitlabJobService}s used in lint, test, audit, and build jobs.
|
|
172
|
+
*/
|
|
150
173
|
jobServices?: GitlabJobService[];
|
|
151
174
|
|
|
152
175
|
docker: BuildConfigCustomDocker;
|
|
@@ -154,41 +177,17 @@ export type BuildConfigCustom = Omit<
|
|
|
154
177
|
/**
|
|
155
178
|
* custom lint, disabled when not set
|
|
156
179
|
*/
|
|
157
|
-
lint?:
|
|
158
|
-
command?: string | string[];
|
|
159
|
-
jobImage?: GitlabJobImage;
|
|
160
|
-
/**
|
|
161
|
-
* additional CI/CD artifacts reports,
|
|
162
|
-
* use to display information in merge requests, pipeline views and security dashboards.
|
|
163
|
-
*/
|
|
164
|
-
artifactsReports?: BuildConfigArtifactsReports;
|
|
165
|
-
};
|
|
180
|
+
lint?: TestJobCustom;
|
|
166
181
|
|
|
167
182
|
/**
|
|
168
183
|
* custom test, disabled when not set
|
|
169
184
|
*/
|
|
170
|
-
test?:
|
|
171
|
-
command?: string | string[];
|
|
172
|
-
jobImage?: GitlabJobImage;
|
|
173
|
-
/**
|
|
174
|
-
* additional CI/CD artifacts reports,
|
|
175
|
-
* use to display information in merge requests, pipeline views and security dashboards.
|
|
176
|
-
*/
|
|
177
|
-
artifactsReports?: BuildConfigArtifactsReports;
|
|
178
|
-
};
|
|
185
|
+
test?: TestJobCustom;
|
|
179
186
|
|
|
180
187
|
/**
|
|
181
188
|
* custom audit, disabled when not set
|
|
182
189
|
*/
|
|
183
|
-
audit?:
|
|
184
|
-
command?: string | string[];
|
|
185
|
-
jobImage?: GitlabJobImage;
|
|
186
|
-
/**
|
|
187
|
-
* additional CI/CD artifacts reports,
|
|
188
|
-
* use to display information in merge requests, pipeline views and security dashboards.
|
|
189
|
-
*/
|
|
190
|
-
artifactsReports?: BuildConfigArtifactsReports;
|
|
191
|
-
};
|
|
190
|
+
audit?: TestJobCustom;
|
|
192
191
|
|
|
193
192
|
/**
|
|
194
193
|
* custom sbom (software bill of materials), set false to disable
|
package/src/deploy/base.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getDockerImageVariables, requiresDockerBuild } from "../build/docker";
|
|
2
|
+
import { SBOM_BUILD_JOB_NAME } from "../build/sbom";
|
|
2
3
|
import type { Context } from "../types";
|
|
3
4
|
import type { CatladderJob } from "../types/jobs";
|
|
5
|
+
import { sbomDeactivated } from "./sbom";
|
|
4
6
|
import { contextIsStoppable } from "./utils";
|
|
5
7
|
|
|
6
8
|
export const DEPLOY_JOB_NAME = "🚀 Deploy";
|
|
@@ -43,13 +45,18 @@ export const getBaseDeploymentJob = (context: Context): JobWithoutScript => {
|
|
|
43
45
|
name: DEPLOY_JOB_NAME,
|
|
44
46
|
envMode: "stagePerEnv", // makes it easier to run manual tasks er env
|
|
45
47
|
|
|
46
|
-
needs:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
needs: [
|
|
49
|
+
...(sbomDeactivated(context)
|
|
50
|
+
? []
|
|
51
|
+
: [{ job: SBOM_BUILD_JOB_NAME, artifacts: true }]),
|
|
52
|
+
...(context.componentConfig.deploy
|
|
53
|
+
? context.componentConfig.deploy.waitFor?.map((c) => ({
|
|
54
|
+
componentName: c,
|
|
55
|
+
job: DEPLOY_JOB_NAME,
|
|
56
|
+
artifacts: false,
|
|
57
|
+
})) ?? []
|
|
58
|
+
: []),
|
|
59
|
+
],
|
|
53
60
|
// we don't want to deploy when there is a broken test
|
|
54
61
|
needsStages: [
|
|
55
62
|
{
|
|
@@ -22,6 +22,10 @@ import {
|
|
|
22
22
|
import { allowFailureInScripts } from "../../utils/gitlab";
|
|
23
23
|
import { getCloudRunJobName } from "./utils/jobName";
|
|
24
24
|
import { createArgsString } from "./utils/createArgsString";
|
|
25
|
+
import {
|
|
26
|
+
getDependencyTrackDeleteScript,
|
|
27
|
+
getDependencyTrackUploadScript,
|
|
28
|
+
} from "../sbom";
|
|
25
29
|
|
|
26
30
|
const setExtraVarsScripts = (deployConfig: DeployConfigCloudRun) => [
|
|
27
31
|
`export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe ${deployConfig.projectId} --format="value(projectNumber)")`,
|
|
@@ -234,6 +238,7 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
234
238
|
...getJobRunScripts("postDeploy"),
|
|
235
239
|
|
|
236
240
|
`docker image rm ${gcloudImageName}`,
|
|
241
|
+
...getDependencyTrackUploadScript(context),
|
|
237
242
|
];
|
|
238
243
|
|
|
239
244
|
const stopScripts = [
|
|
@@ -250,6 +255,7 @@ export const createGoogleCloudRunDeployJobs = (
|
|
|
250
255
|
...(deployConfig.cloudSql && deployConfig.cloudSql.deleteDatabaseOnStop
|
|
251
256
|
? getDatabaseDeleteScript(context, deployConfig)
|
|
252
257
|
: []),
|
|
258
|
+
...getDependencyTrackDeleteScript(context),
|
|
253
259
|
];
|
|
254
260
|
return [
|
|
255
261
|
merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
|
|
@@ -6,6 +6,10 @@ import type { Context } from "../../types/context";
|
|
|
6
6
|
import type { CatladderJob } from "../../types/jobs";
|
|
7
7
|
import { getBaseDeploymentJob, getBaseDeploymentStopJob } from "../base";
|
|
8
8
|
import { isOfDeployType } from "../types";
|
|
9
|
+
import {
|
|
10
|
+
getDependencyTrackDeleteScript,
|
|
11
|
+
getDependencyTrackUploadScript,
|
|
12
|
+
} from "../sbom";
|
|
9
13
|
|
|
10
14
|
export const createCustomDeployJobs = (context: Context): CatladderJob[] => {
|
|
11
15
|
const deployConfig = context.componentConfig.deploy;
|
|
@@ -27,13 +31,17 @@ export const createCustomDeployJobs = (context: Context): CatladderJob[] => {
|
|
|
27
31
|
`cd ${context.componentConfig.dir}`,
|
|
28
32
|
...(deployConfig.requiresYarnInstall ? yarnInstall : []),
|
|
29
33
|
...deployConfig.script,
|
|
34
|
+
...getDependencyTrackUploadScript(context),
|
|
30
35
|
],
|
|
31
36
|
}),
|
|
32
37
|
...(deployConfig.stopScript
|
|
33
38
|
? [
|
|
34
39
|
merge({}, getBaseDeploymentStopJob(context), {
|
|
35
40
|
image: deployConfig.jobImage ?? getRunnerImage("jobs-default"),
|
|
36
|
-
script:
|
|
41
|
+
script: [
|
|
42
|
+
...deployConfig.stopScript,
|
|
43
|
+
...getDependencyTrackDeleteScript(context),
|
|
44
|
+
],
|
|
37
45
|
}),
|
|
38
46
|
]
|
|
39
47
|
: []),
|
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
} from "../base";
|
|
12
12
|
import { isOfDeployType } from "../types";
|
|
13
13
|
import { createKubeValues } from "./kubeValues";
|
|
14
|
+
import {
|
|
15
|
+
getDependencyTrackDeleteScript,
|
|
16
|
+
getDependencyTrackUploadScript,
|
|
17
|
+
} from "../sbom";
|
|
14
18
|
|
|
15
19
|
export const createKubernetesDeployJobs = (
|
|
16
20
|
context: Context
|
|
@@ -76,6 +80,7 @@ export const createKubernetesDeployJobs = (
|
|
|
76
80
|
...connectContext,
|
|
77
81
|
"kubernetesCreateSecret",
|
|
78
82
|
"kubernetesDeploy",
|
|
83
|
+
...getDependencyTrackUploadScript(context),
|
|
79
84
|
"echo deployment successful 😻",
|
|
80
85
|
],
|
|
81
86
|
environment: {
|
|
@@ -83,7 +88,11 @@ export const createKubernetesDeployJobs = (
|
|
|
83
88
|
},
|
|
84
89
|
}),
|
|
85
90
|
merge({}, baseStopJob, shared, {
|
|
86
|
-
script: [
|
|
91
|
+
script: [
|
|
92
|
+
...connectContext,
|
|
93
|
+
"kubernetesDelete",
|
|
94
|
+
...getDependencyTrackDeleteScript(context),
|
|
95
|
+
],
|
|
87
96
|
environment: {
|
|
88
97
|
kubernetes: kubernetesEnvironment,
|
|
89
98
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Context } from "../types/context";
|
|
2
|
+
import { SBOM_FILE } from "../build/sbom";
|
|
3
|
+
|
|
4
|
+
export const sbomDeactivated = (context: Context) =>
|
|
5
|
+
context.componentConfig.build.type === "custom" &&
|
|
6
|
+
context.componentConfig.build.sbom === false;
|
|
7
|
+
|
|
8
|
+
export const getDependencyTrackUploadScript = (context: Context): string[] => {
|
|
9
|
+
return sbomDeactivated(context)
|
|
10
|
+
? []
|
|
11
|
+
: [
|
|
12
|
+
"echo Uploading SBOM to Dependency Track",
|
|
13
|
+
`/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`,
|
|
14
|
+
];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const getDependencyTrackDeleteScript = (context: Context): string[] => {
|
|
18
|
+
return sbomDeactivated(context)
|
|
19
|
+
? []
|
|
20
|
+
: [
|
|
21
|
+
"echo Disabling component in Dependency Track",
|
|
22
|
+
`/dtrackuploader https://dep.panter.swiss/ "$DT_KEY_PROD" disable "${context.fullConfig.customerName}-${context.fullConfig.appName}/${context.componentName}" "${context.environment.url}" || true`,
|
|
23
|
+
];
|
|
24
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isFunction } from "lodash";
|
|
2
2
|
import { BUILD_TYPES } from "../build";
|
|
3
|
-
import { createReportingJobs } from "../verify/reporting";
|
|
4
3
|
import { createContext } from "../context";
|
|
5
4
|
import { DEPLOY_TYPES } from "../deploy";
|
|
6
5
|
import type { Config, PipelineTrigger } from "../types/config";
|
|
@@ -36,10 +35,9 @@ const createRawJobs = (context: Context): CatladderJob[] => {
|
|
|
36
35
|
context.componentConfig.deploy !== false
|
|
37
36
|
? DEPLOY_TYPES[context.componentConfig.deploy.type].jobs(context)
|
|
38
37
|
: [];
|
|
39
|
-
const reportingJobs = createReportingJobs(context);
|
|
40
38
|
|
|
41
39
|
const customJobs = getCustomJobs(context);
|
|
42
|
-
return [...buildJobs, ...deployJobs, ...
|
|
40
|
+
return [...buildJobs, ...deployJobs, ...customJobs];
|
|
43
41
|
};
|
|
44
42
|
export const createJobsForComponent = async (
|
|
45
43
|
config: Config,
|
|
@@ -72,10 +72,10 @@ export const makeGitlabJob = (
|
|
|
72
72
|
}));
|
|
73
73
|
});
|
|
74
74
|
const cleanedNeeds: CatladderJob["needs"] = [
|
|
75
|
+
...(needsFromStages ?? []),
|
|
75
76
|
...(needs ?? []),
|
|
76
77
|
// pull in legacy needs from other component, which is now identical to needs
|
|
77
78
|
...(needsOtherComponent ?? []),
|
|
78
|
-
...(needsFromStages ?? []),
|
|
79
79
|
];
|
|
80
80
|
|
|
81
81
|
const gitlabNeeds: GitlabJobDef["needs"] = cleanedNeeds
|
|
@@ -94,6 +94,10 @@ export const makeGitlabJob = (
|
|
|
94
94
|
) // sort in a predictable manner for snapshot tests
|
|
95
95
|
.sort((a, b) => getJobName(a).localeCompare(getJobName(b)));
|
|
96
96
|
|
|
97
|
+
const deduplicatedGitlabNeeds: GitlabJobDef["needs"] = [
|
|
98
|
+
...new Map(gitlabNeeds.map((n) => [isObject(n) ? n.job : n, n])).values(),
|
|
99
|
+
];
|
|
100
|
+
|
|
97
101
|
const fullJobName = getFullJobName(
|
|
98
102
|
name,
|
|
99
103
|
componentName,
|
|
@@ -116,7 +120,7 @@ export const makeGitlabJob = (
|
|
|
116
120
|
}
|
|
117
121
|
: job.environment,
|
|
118
122
|
// sort in a predictable manner for snapshot tests
|
|
119
|
-
needs:
|
|
123
|
+
needs: deduplicatedGitlabNeeds,
|
|
120
124
|
retry: BASE_RETRY,
|
|
121
125
|
interruptible: true,
|
|
122
126
|
});
|
|
@@ -2,19 +2,19 @@ export type Artifacts = {
|
|
|
2
2
|
paths: string[];
|
|
3
3
|
expire_in?: string;
|
|
4
4
|
when?: "always" | "on_success" | "on_failure";
|
|
5
|
-
|
|
5
|
+
// Reports won't show up on MRs until https://gitlab.com/groups/gitlab-org/-/epics/8205
|
|
6
|
+
reports?: {
|
|
7
|
+
accessibility?: string | string[];
|
|
8
|
+
coverage_report?: { coverage_format: string; path: string };
|
|
9
|
+
codequality?: string | string[];
|
|
10
|
+
cyclonedx?: string | string[];
|
|
11
|
+
dotenv?: string | string[];
|
|
12
|
+
junit?: string | string[];
|
|
13
|
+
sast?: string;
|
|
14
|
+
secret_detection?: string;
|
|
15
|
+
terraform?: string;
|
|
16
|
+
};
|
|
6
17
|
};
|
|
7
|
-
// Reports won't show up on MRs until https://gitlab.com/groups/gitlab-org/-/epics/8205
|
|
8
|
-
export type ArtifactReports =
|
|
9
|
-
| { accessibility: string | string[] }
|
|
10
|
-
| { coverage_report: { coverage_format: string; path: string } }
|
|
11
|
-
| { codequality: string | string[] }
|
|
12
|
-
| { cyclonedx: string | string[] }
|
|
13
|
-
| { dotenv: string | string[] }
|
|
14
|
-
| { junit: string | string[] }
|
|
15
|
-
| { sast: string }
|
|
16
|
-
| { secret_detection: string }
|
|
17
|
-
| { terraform: string };
|
|
18
18
|
export type GitlabJobCache = {
|
|
19
19
|
key: GitlabJobCacheKey;
|
|
20
20
|
policy?: string;
|
package/dist/verify/reporting.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.createReportingJobs = void 0;
|
|
5
|
-
var base_1 = require("../deploy/base");
|
|
6
|
-
var utils_1 = require("../utils");
|
|
7
|
-
var STAGE = "verify";
|
|
8
|
-
var SBOM_GENERATE_JOB_NAME = "🧾 sbom";
|
|
9
|
-
var SBOM_FILE = "__sbom.json";
|
|
10
|
-
var createSbomGenerateJob = function (context) {
|
|
11
|
-
var _a, _b, _c, _d, _e;
|
|
12
|
-
var buildConfig = context.componentConfig.build;
|
|
13
|
-
var defaultImage = "aquasec/trivy:0.38.3";
|
|
14
|
-
var defaultScript = ["trivy fs --quiet --format cyclonedx --output \"".concat(SBOM_FILE, "\" ").concat(((_a = context.packageManagerInfo) === null || _a === void 0 ? void 0 : _a.componentIsInWorkspace) ? "." : context.componentConfig.dir)];
|
|
15
|
-
var image = buildConfig.type === "custom" && buildConfig.sbom !== false ? (_c = (_b = buildConfig.sbom) === null || _b === void 0 ? void 0 : _b.jobImage) !== null && _c !== void 0 ? _c : defaultImage : defaultImage;
|
|
16
|
-
var script = buildConfig.type === "custom" && buildConfig.sbom !== false ? (_e = (0, utils_1.ensureArray)((_d = buildConfig.sbom) === null || _d === void 0 ? void 0 : _d.command)) !== null && _e !== void 0 ? _e : defaultScript : defaultScript;
|
|
17
|
-
return {
|
|
18
|
-
name: SBOM_GENERATE_JOB_NAME,
|
|
19
|
-
stage: STAGE,
|
|
20
|
-
needs: context.componentConfig.deploy !== false ? [base_1.DEPLOY_JOB_NAME] : [],
|
|
21
|
-
envMode: "jobPerEnv",
|
|
22
|
-
variables: {},
|
|
23
|
-
cache: undefined,
|
|
24
|
-
image: image,
|
|
25
|
-
script: script,
|
|
26
|
-
allow_failure: true,
|
|
27
|
-
artifacts: {
|
|
28
|
-
paths: [SBOM_FILE]
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
var createSbomUploadJob = function (context) {
|
|
33
|
-
return {
|
|
34
|
-
name: "🧾 sbom upload",
|
|
35
|
-
stage: STAGE,
|
|
36
|
-
needs: [SBOM_GENERATE_JOB_NAME],
|
|
37
|
-
envMode: "jobPerEnv",
|
|
38
|
-
variables: {},
|
|
39
|
-
cache: undefined,
|
|
40
|
-
image: "git.panter.ch:5001/open-source/dependency-track-uploader:dtrackuploader-v0.2.1",
|
|
41
|
-
script: ["/dtrackuploader https://dep.panter.swiss/ \"$DT_KEY_PROD\" upload \"".concat(context.fullConfig.customerName, "-").concat(context.fullConfig.appName, "/").concat(context.componentName, "\" \"").concat(context.environment.shortName, "\" \"").concat(SBOM_FILE, "\" vex.json")],
|
|
42
|
-
allow_failure: true
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
var createReportingJobs = function (context) {
|
|
46
|
-
return context.componentConfig.build.type === "custom" && context.componentConfig.build.sbom === false ? [] : [createSbomGenerateJob(context), createSbomUploadJob(context)];
|
|
47
|
-
};
|
|
48
|
-
exports.createReportingJobs = createReportingJobs;
|