@catladder/pipeline 1.11.0 → 1.12.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.
- package/dist/build/base/createBuildJob.d.ts +1 -0
- package/dist/build/base/createBuildJob.js +4 -3
- package/dist/build/docker.d.ts +5 -3
- package/dist/build/docker.js +45 -28
- package/dist/build/node/buildJob.js +26 -13
- package/dist/build/node/cache.d.ts +3 -1
- package/dist/build/node/cache.js +33 -5
- package/dist/build/node/meteor.js +4 -23
- package/dist/build/node/yarn.d.ts +4 -0
- package/dist/build/node/yarn.js +10 -3
- package/dist/build/types.d.ts +6 -0
- package/dist/constants.js +1 -1
- package/dist/context/index.d.ts +2 -2
- package/dist/context/index.js +2 -2
- package/dist/pipeline/createJobs.js +5 -5
- package/dist/pipeline/packageManager.d.ts +2 -0
- package/dist/pipeline/{yarnInfo.js → packageManager.js} +24 -12
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/context.d.ts +15 -11
- package/package.json +1 -1
- package/src/build/base/createBuildJob.ts +4 -2
- package/src/build/docker.ts +51 -45
- package/src/build/node/buildJob.ts +32 -22
- package/src/build/node/cache.ts +30 -5
- package/src/build/node/meteor.ts +5 -11
- package/src/build/node/yarn.ts +20 -3
- package/src/build/types.ts +6 -0
- package/src/context/index.ts +8 -4
- package/src/pipeline/createJobs.ts +3 -3
- package/src/pipeline/packageManager.ts +99 -0
- package/src/types/context.ts +14 -7
- package/dist/pipeline/yarnInfo.d.ts +0 -2
- package/src/pipeline/yarnInfo.ts +0 -73
package/src/build/node/yarn.ts
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import { Context } from "../../types";
|
|
2
2
|
|
|
3
|
+
export const getYarnInstallCommand = (
|
|
4
|
+
context: Context,
|
|
5
|
+
options?: {
|
|
6
|
+
prodOnly?: boolean;
|
|
7
|
+
noScripts?: boolean;
|
|
8
|
+
}
|
|
9
|
+
) =>
|
|
10
|
+
context.packageManagerInfo?.isClassic
|
|
11
|
+
? `yarn install --frozen-lockfile ${
|
|
12
|
+
options?.prodOnly ? "--production" : ""
|
|
13
|
+
} ${options?.noScripts ? "--ignore-scripts" : ""}`
|
|
14
|
+
: options?.prodOnly
|
|
15
|
+
? `${
|
|
16
|
+
options?.noScripts ? "YARN_ENABLE_SCRIPTS=false " : ""
|
|
17
|
+
}yarn plugin import workspace-tools && yarn workspaces focus --production` // needs yarn plugin import workspace-tools
|
|
18
|
+
: `${
|
|
19
|
+
options?.noScripts ? "YARN_ENABLE_SCRIPTS=false " : ""
|
|
20
|
+
}yarn install --immutable`;
|
|
21
|
+
|
|
3
22
|
export const getYarnInstall = (context: Context) => [
|
|
4
23
|
"if [ -f ./.nvmrc ]; then source /root/.nvm/nvm.sh && nvm install <<< .nvmrc; fi",
|
|
5
|
-
context
|
|
6
|
-
? "yarn install --frozen-lockfile"
|
|
7
|
-
: "yarn install --immutable",
|
|
24
|
+
getYarnInstallCommand(context),
|
|
8
25
|
];
|
package/src/build/types.ts
CHANGED
|
@@ -46,6 +46,12 @@ export type BuildConfigBase = {
|
|
|
46
46
|
| {
|
|
47
47
|
command?: string | string[];
|
|
48
48
|
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* additional paths for artifacts,
|
|
52
|
+
* by default "dist" and ".next" are allways included
|
|
53
|
+
*/
|
|
54
|
+
artifactsPaths?: [];
|
|
49
55
|
};
|
|
50
56
|
|
|
51
57
|
export type BuildConfigNodeBase = BuildConfigBase;
|
package/src/context/index.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { merge, mergeWith } from "lodash";
|
|
2
1
|
import slugify from "slugify";
|
|
3
2
|
import { BUILD_TYPES } from "../build";
|
|
4
3
|
import { BuildConfig } from "../build/types";
|
|
5
4
|
import { DEPLOY_TYPES, getKubernetesNamespace } from "../deploy";
|
|
6
5
|
import { DeployConfig } from "../deploy/types";
|
|
7
6
|
import { Config, isKnowEnvType, DevLocalEnvConfig } from "../types/config";
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
CommitInfo,
|
|
9
|
+
Context,
|
|
10
|
+
Environment,
|
|
11
|
+
PackageManagerInfo,
|
|
12
|
+
} from "../types/context";
|
|
9
13
|
import { mergeWithMergingArrays } from "../utils";
|
|
10
14
|
|
|
11
15
|
const sanitizeForEnVar = (s: string) => s.replace(/-/g, "_");
|
|
@@ -164,7 +168,7 @@ export const createContext = (
|
|
|
164
168
|
componentName: string,
|
|
165
169
|
env: string,
|
|
166
170
|
commitInfo?: CommitInfo,
|
|
167
|
-
|
|
171
|
+
packageManagerInfo?: PackageManagerInfo
|
|
168
172
|
): Context => {
|
|
169
173
|
if (!/^[a-z0-9-]+$/.test(componentName)) {
|
|
170
174
|
throw new Error(
|
|
@@ -208,6 +212,6 @@ export const createContext = (
|
|
|
208
212
|
componentName,
|
|
209
213
|
environment: getEnvironment(config, componentName, env, commitInfo),
|
|
210
214
|
commitInfo,
|
|
211
|
-
|
|
215
|
+
packageManagerInfo,
|
|
212
216
|
};
|
|
213
217
|
};
|
|
@@ -7,7 +7,7 @@ import { Config, PipelineTrigger } from "../types/config";
|
|
|
7
7
|
import { Context, CommitInfo } from "../types/context";
|
|
8
8
|
import { GitlabJob, GitlabJobDef, GitlabJobs } from "../types/gitlab-types";
|
|
9
9
|
import { notNil } from "../utils";
|
|
10
|
-
import {
|
|
10
|
+
import { getPackageManagerInfo } from "./packageManager";
|
|
11
11
|
|
|
12
12
|
const createRawJobs = (context: Context): GitlabJobs => {
|
|
13
13
|
if (context.componentConfig.deploy === false) {
|
|
@@ -134,7 +134,7 @@ export const createJobs = async (
|
|
|
134
134
|
trigger,
|
|
135
135
|
};
|
|
136
136
|
|
|
137
|
-
const
|
|
137
|
+
const packageManagerInfo = await getPackageManagerInfo(config, componentName);
|
|
138
138
|
|
|
139
139
|
return envs.reduce((acc, env) => {
|
|
140
140
|
const context = createContext(
|
|
@@ -142,7 +142,7 @@ export const createJobs = async (
|
|
|
142
142
|
componentName,
|
|
143
143
|
env,
|
|
144
144
|
commitInfo,
|
|
145
|
-
|
|
145
|
+
packageManagerInfo
|
|
146
146
|
);
|
|
147
147
|
const jobs = addStageNeeds(createRawJobs(context));
|
|
148
148
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { exec } from "child-process-promise";
|
|
2
|
+
import { Config, PackageManagerInfo } from "../types";
|
|
3
|
+
import { pathEqual } from "path-equal";
|
|
4
|
+
import memoizee from "memoizee";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { existsSync } from "fs";
|
|
7
|
+
|
|
8
|
+
const execOrFail = async (cmd: string, onFail: string): Promise<string> => {
|
|
9
|
+
try {
|
|
10
|
+
return await exec(cmd).then((r) => r.stdout);
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return onFail ?? null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const getYarnVersion = memoizee(
|
|
17
|
+
async () => {
|
|
18
|
+
return await execOrFail("yarn --version", "");
|
|
19
|
+
},
|
|
20
|
+
{ promise: true }
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const getWorkspaces = memoizee(
|
|
24
|
+
async (isClassic: boolean): Promise<PackageManagerInfo["workspaces"]> => {
|
|
25
|
+
return isClassic
|
|
26
|
+
? Object.values(
|
|
27
|
+
JSON.parse(
|
|
28
|
+
JSON.parse(await execOrFail("yarn workspaces --json info", "{}"))
|
|
29
|
+
?.data ?? "{}"
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
: JSON.parse(
|
|
33
|
+
`[${(await execOrFail("yarn workspaces list --json --verbose", ""))
|
|
34
|
+
.trim()
|
|
35
|
+
.split("\n")
|
|
36
|
+
.join(",")}]`
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
{ promise: true }
|
|
40
|
+
);
|
|
41
|
+
export const getPackageManagerInfo = async (
|
|
42
|
+
config: Config,
|
|
43
|
+
componentName: string
|
|
44
|
+
): Promise<PackageManagerInfo> => {
|
|
45
|
+
// currently only supports yarn
|
|
46
|
+
const version = await getYarnVersion();
|
|
47
|
+
if (!version) throw new Error("could not get yarn version");
|
|
48
|
+
const isClassic = version.startsWith("1");
|
|
49
|
+
|
|
50
|
+
const component = config.components[componentName];
|
|
51
|
+
const workspaces = await getWorkspaces(isClassic);
|
|
52
|
+
const currentWorkspace = workspaces.find((w) =>
|
|
53
|
+
pathEqual(component.dir, w.location)
|
|
54
|
+
);
|
|
55
|
+
const componentIsInWorkspace = Boolean(currentWorkspace);
|
|
56
|
+
const workspaceRoot = "."; // currently we assume the root folder, later on we might support nested workspaces
|
|
57
|
+
const packageJson = join(component.dir, "package.json");
|
|
58
|
+
const workspacePackageJson = componentIsInWorkspace
|
|
59
|
+
? join(workspaceRoot, "package.json")
|
|
60
|
+
: null;
|
|
61
|
+
|
|
62
|
+
const lockFile = componentIsInWorkspace
|
|
63
|
+
? join(workspaceRoot, "yarn.lock")
|
|
64
|
+
: join(component.dir, "yarn.lock");
|
|
65
|
+
const configFiles = [".yarnrc", ".yarnrc.yml", ".npmrc", ".yarn"]; // ".yarn" is yarn 2 folder
|
|
66
|
+
const rcFiles = (
|
|
67
|
+
componentIsInWorkspace
|
|
68
|
+
? configFiles
|
|
69
|
+
: configFiles.map((f) => join(component.dir, f))
|
|
70
|
+
).filter((f) => existsSync(f));
|
|
71
|
+
|
|
72
|
+
// get all folders that this workspace depend on
|
|
73
|
+
// we will later copy them into the docker build
|
|
74
|
+
const workspaceDependencies = currentWorkspace
|
|
75
|
+
? ([
|
|
76
|
+
...currentWorkspace.workspaceDependencies,
|
|
77
|
+
...currentWorkspace.mismatchedWorkspaceDependencies,
|
|
78
|
+
]
|
|
79
|
+
.map((name) => workspaces.find((w) => w.name === name)?.location)
|
|
80
|
+
.filter(Boolean) as string[])
|
|
81
|
+
: [];
|
|
82
|
+
|
|
83
|
+
const pathsToCopyInDocker = [
|
|
84
|
+
packageJson,
|
|
85
|
+
...(workspacePackageJson ? [workspacePackageJson] : []),
|
|
86
|
+
lockFile,
|
|
87
|
+
...rcFiles,
|
|
88
|
+
...workspaceDependencies,
|
|
89
|
+
];
|
|
90
|
+
return {
|
|
91
|
+
type: "yarn",
|
|
92
|
+
workspaces,
|
|
93
|
+
version,
|
|
94
|
+
isClassic,
|
|
95
|
+
currentWorkspace,
|
|
96
|
+
componentIsInWorkspace,
|
|
97
|
+
pathsToCopyInDocker,
|
|
98
|
+
};
|
|
99
|
+
};
|
package/src/types/context.ts
CHANGED
|
@@ -22,21 +22,28 @@ export type CommitInfo = {
|
|
|
22
22
|
trigger: PipelineTrigger;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
type Workspace = {
|
|
26
|
+
name: string;
|
|
27
|
+
location: string;
|
|
28
|
+
workspaceDependencies: string[];
|
|
29
|
+
mismatchedWorkspaceDependencies: string[];
|
|
30
|
+
};
|
|
31
|
+
export type YarnPackageManagerInfo = {
|
|
32
|
+
type: "yarn";
|
|
26
33
|
version: string;
|
|
27
|
-
workspaces:
|
|
34
|
+
workspaces: Workspace[];
|
|
35
|
+
currentWorkspace?: Workspace;
|
|
28
36
|
isClassic: boolean;
|
|
29
37
|
componentIsInWorkspace: boolean;
|
|
30
|
-
|
|
31
|
-
* files relevant for the package manager
|
|
32
|
-
*/
|
|
33
|
-
files: string[];
|
|
38
|
+
pathsToCopyInDocker: string[];
|
|
34
39
|
};
|
|
40
|
+
|
|
41
|
+
export type PackageManagerInfo = YarnPackageManagerInfo;
|
|
35
42
|
export type Context = {
|
|
36
43
|
componentName: string;
|
|
37
44
|
componentConfig: ComponentConfig;
|
|
38
45
|
fullConfig: Config;
|
|
39
46
|
environment: Environment;
|
|
40
47
|
commitInfo?: CommitInfo;
|
|
41
|
-
|
|
48
|
+
packageManagerInfo?: PackageManagerInfo;
|
|
42
49
|
};
|
package/src/pipeline/yarnInfo.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { exec } from "child-process-promise";
|
|
2
|
-
import { Config, YarnInfo } from "../types";
|
|
3
|
-
import { pathEqual } from "path-equal";
|
|
4
|
-
import memoizee from "memoizee";
|
|
5
|
-
import { join } from "path";
|
|
6
|
-
import { existsSync } from "fs";
|
|
7
|
-
|
|
8
|
-
const execOrFail = async (cmd: string, onFail: string): Promise<string> => {
|
|
9
|
-
try {
|
|
10
|
-
return await exec(cmd).then((r) => r.stdout);
|
|
11
|
-
} catch (e) {
|
|
12
|
-
return onFail ?? null;
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const getYarnVersion = memoizee(
|
|
17
|
-
async () => {
|
|
18
|
-
return await execOrFail("yarn --version", "");
|
|
19
|
-
},
|
|
20
|
-
{ promise: true }
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
const getWorkspaces = memoizee(
|
|
24
|
-
async (isClassic: boolean): Promise<YarnInfo["workspaces"]> => {
|
|
25
|
-
return isClassic
|
|
26
|
-
? Object.values(
|
|
27
|
-
JSON.parse(
|
|
28
|
-
JSON.parse(await execOrFail("yarn workspaces --json info", "{}"))
|
|
29
|
-
?.data ?? "{}"
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
: JSON.parse(
|
|
33
|
-
`[${(await execOrFail("yarn workspaces list --json", ""))
|
|
34
|
-
.trim()
|
|
35
|
-
.split("\n")
|
|
36
|
-
.join(",")}]`
|
|
37
|
-
);
|
|
38
|
-
},
|
|
39
|
-
{ promise: true }
|
|
40
|
-
);
|
|
41
|
-
export const getYarnInfo = async (
|
|
42
|
-
config: Config,
|
|
43
|
-
componentName: string
|
|
44
|
-
): Promise<YarnInfo> => {
|
|
45
|
-
const version = await getYarnVersion();
|
|
46
|
-
if (!version) throw new Error("could not get yarn version");
|
|
47
|
-
const isClassic = version.startsWith("1");
|
|
48
|
-
|
|
49
|
-
const component = config.components[componentName];
|
|
50
|
-
const workspaces = await getWorkspaces(isClassic);
|
|
51
|
-
const componentIsInWorkspace = workspaces.some((w) =>
|
|
52
|
-
pathEqual(component.dir, w.location)
|
|
53
|
-
);
|
|
54
|
-
const packageJson = join(component.dir, "package.json");
|
|
55
|
-
const lockFile = componentIsInWorkspace
|
|
56
|
-
? "yarn.lock"
|
|
57
|
-
: join(component.dir, "yarn.lock");
|
|
58
|
-
const RC_FILES = [".yarnrc", ".npmrc"];
|
|
59
|
-
const possibleRcFiles = componentIsInWorkspace
|
|
60
|
-
? RC_FILES
|
|
61
|
-
: RC_FILES.map((f) => join(component.dir, f));
|
|
62
|
-
const files = [packageJson, lockFile, ...possibleRcFiles].filter((f) =>
|
|
63
|
-
existsSync(f)
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
workspaces,
|
|
68
|
-
version,
|
|
69
|
-
isClassic,
|
|
70
|
-
componentIsInWorkspace,
|
|
71
|
-
files,
|
|
72
|
-
};
|
|
73
|
-
};
|