@catladder/cli 0.0.0-refactor-untangle-gitlab-api-requests-from-vorpal-c65e5318 → 0.0.0-refactor-untangle-gitlab-api-requests-from-vorpal-57cf3cf2
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/bundles/catenv/index.js +30 -21
- package/dist/bundles/cli/index.js +49 -40
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.d.ts +3 -1
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.js +7 -7
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.d.ts +3 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.js +6 -6
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.d.ts +3 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.js +6 -6
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.js.map +1 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.d.ts +1 -0
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.js +16 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.js.map +1 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabVariables.js +2 -6
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabVariables.js.map +1 -1
- package/dist/cli/src/utils/gitlab.d.ts +6 -3
- package/dist/cli/src/utils/gitlab.js +9 -14
- package/dist/cli/src/utils/gitlab.js.map +1 -1
- package/dist/cli/src/utils/preferences/CatladderPreferences.d.ts +4 -0
- package/dist/cli/src/utils/preferences/CatladderPreferences.js +3 -0
- package/dist/cli/src/utils/preferences/CatladderPreferences.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/apps/cli/commands/project/commandGitlabCi.ts +16 -12
- package/src/apps/cli/commands/project/setup/setupAccessTokens.ts +12 -7
- package/src/apps/cli/commands/project/setup/setupKubernetes.ts +14 -9
- package/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.ts +18 -0
- package/src/utils/gitlab-without-vorpal/gitLabVariables.ts +5 -7
- package/src/utils/gitlab.ts +19 -22
- package/src/utils/preferences/CatladderPreferences.ts +4 -0
package/package.json
CHANGED
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
}
|
|
54
54
|
],
|
|
55
55
|
"license": "MIT",
|
|
56
|
-
"version": "0.0.0-refactor-untangle-gitlab-api-requests-from-vorpal-
|
|
56
|
+
"version": "0.0.0-refactor-untangle-gitlab-api-requests-from-vorpal-57cf3cf2",
|
|
57
57
|
"scripts": {
|
|
58
58
|
"lint": "eslint \"src/**/*.ts\"",
|
|
59
59
|
"lint:fix": "eslint \"src/**/*.ts\" --fix",
|
|
@@ -4,12 +4,11 @@ import open from "open";
|
|
|
4
4
|
import type { CommandInstance } from "vorpal";
|
|
5
5
|
import type Vorpal from "vorpal";
|
|
6
6
|
import type { GitLabApiDataOptional } from "../../../../utils/gitlab-without-vorpal";
|
|
7
|
-
import { getGitLabHostPathToken } from "../../../../utils/gitlab-without-vorpal";
|
|
8
7
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "../../../../utils/gitlab";
|
|
8
|
+
getGitLabHostPathToken,
|
|
9
|
+
getGitLabProjectId,
|
|
10
|
+
} from "../../../../utils/gitlab-without-vorpal";
|
|
11
|
+
import { doGitlabRequest, getGitlabToken } from "../../../../utils/gitlab";
|
|
13
12
|
|
|
14
13
|
const statusEmojiMap: any = {
|
|
15
14
|
failed: "🙀",
|
|
@@ -84,7 +83,10 @@ const promptJob = async (
|
|
|
84
83
|
|
|
85
84
|
const commandGitlabCi = async (
|
|
86
85
|
vorpal: Vorpal,
|
|
87
|
-
|
|
86
|
+
{
|
|
87
|
+
projectId,
|
|
88
|
+
...existing
|
|
89
|
+
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
88
90
|
) => {
|
|
89
91
|
vorpal.command("project-ci-job-open", "Open a Job").action(async function () {
|
|
90
92
|
const {
|
|
@@ -93,9 +95,10 @@ const commandGitlabCi = async (
|
|
|
93
95
|
token: inputToken,
|
|
94
96
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
95
97
|
const token = inputToken || (await getGitlabToken(this, host));
|
|
96
|
-
const
|
|
98
|
+
const id =
|
|
99
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
97
100
|
|
|
98
|
-
const job = await promptJob(this,
|
|
101
|
+
const job = await promptJob(this, id, this, { host, path, token });
|
|
99
102
|
open(job.web_url);
|
|
100
103
|
});
|
|
101
104
|
|
|
@@ -109,18 +112,19 @@ const commandGitlabCi = async (
|
|
|
109
112
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
110
113
|
const token = inputToken || (await getGitlabToken(this, host));
|
|
111
114
|
const apiData = { host, path, token };
|
|
112
|
-
const
|
|
115
|
+
const pId =
|
|
116
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
113
117
|
|
|
114
|
-
const { id } = await promptJob(this,
|
|
118
|
+
const { id } = await promptJob(this, pId, this, apiData);
|
|
115
119
|
|
|
116
120
|
let finished = false;
|
|
117
121
|
while (!finished) {
|
|
118
122
|
const trace = await exec(
|
|
119
|
-
`curl -s --header "PRIVATE-TOKEN: ${token}" "https://git.panter.ch/api/v4/projects/${
|
|
123
|
+
`curl -s --header "PRIVATE-TOKEN: ${token}" "https://git.panter.ch/api/v4/projects/${pId}/jobs/${id}/trace"`,
|
|
120
124
|
);
|
|
121
125
|
|
|
122
126
|
const job = await doGitlabRequest(this, {
|
|
123
|
-
path: `projects/${
|
|
127
|
+
path: `projects/${pId}/jobs/${id}`,
|
|
124
128
|
host,
|
|
125
129
|
token,
|
|
126
130
|
});
|
|
@@ -6,14 +6,18 @@ import {
|
|
|
6
6
|
type GitLabApiDataOptional,
|
|
7
7
|
gitLabVariable,
|
|
8
8
|
FetchGitLabError,
|
|
9
|
+
getGitLabProjectId,
|
|
9
10
|
} from "../../../../../utils/gitlab-without-vorpal";
|
|
10
|
-
import { getGitlabToken
|
|
11
|
+
import { getGitlabToken } from "../../../../../utils/gitlab";
|
|
11
12
|
|
|
12
13
|
const TOKEN_NAME = "semantic-release";
|
|
13
14
|
|
|
14
15
|
export const setupAccessTokens = async (
|
|
15
16
|
vorpal: CommandInstance,
|
|
16
|
-
|
|
17
|
+
{
|
|
18
|
+
projectId,
|
|
19
|
+
...existing
|
|
20
|
+
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
17
21
|
) => {
|
|
18
22
|
const {
|
|
19
23
|
host,
|
|
@@ -21,10 +25,11 @@ export const setupAccessTokens = async (
|
|
|
21
25
|
token: inputToken,
|
|
22
26
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
23
27
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
24
|
-
const
|
|
28
|
+
const id =
|
|
29
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
25
30
|
|
|
26
31
|
const projectTokens = await gitLabProjectAccessToken.getList(
|
|
27
|
-
{ projectId, token, host },
|
|
32
|
+
{ projectId: id, token, host },
|
|
28
33
|
vorpal,
|
|
29
34
|
);
|
|
30
35
|
const accessToken = projectTokens.find(
|
|
@@ -36,7 +41,7 @@ export const setupAccessTokens = async (
|
|
|
36
41
|
const newToken = accessToken
|
|
37
42
|
? await gitLabProjectAccessToken.rotate(
|
|
38
43
|
{
|
|
39
|
-
projectId,
|
|
44
|
+
projectId: id,
|
|
40
45
|
tokenId: accessToken.id,
|
|
41
46
|
token,
|
|
42
47
|
host,
|
|
@@ -46,7 +51,7 @@ export const setupAccessTokens = async (
|
|
|
46
51
|
)
|
|
47
52
|
: await gitLabProjectAccessToken.create(
|
|
48
53
|
{
|
|
49
|
-
projectId,
|
|
54
|
+
projectId: id,
|
|
50
55
|
token,
|
|
51
56
|
host,
|
|
52
57
|
data: {
|
|
@@ -59,7 +64,7 @@ export const setupAccessTokens = async (
|
|
|
59
64
|
vorpal,
|
|
60
65
|
);
|
|
61
66
|
|
|
62
|
-
const fetchCommon = { key: "GL_TOKEN", projectId, host, token };
|
|
67
|
+
const fetchCommon = { key: "GL_TOKEN", projectId: id, host, token };
|
|
63
68
|
try {
|
|
64
69
|
await gitLabVariable.get(fetchCommon, vorpal);
|
|
65
70
|
await gitLabVariable.update(
|
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
} from "@catladder/pipeline";
|
|
9
9
|
import ensureNamespace from "../utils/ensureNamespace";
|
|
10
10
|
import type { GitLabApiDataOptional } from "../../../../../utils/gitlab-without-vorpal";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
getGitLabHostPathToken,
|
|
13
|
+
getGitLabProjectId,
|
|
14
|
+
} from "../../../../../utils/gitlab-without-vorpal";
|
|
12
15
|
import {
|
|
13
16
|
doGitlabRequest,
|
|
14
17
|
getGitlabToken,
|
|
15
|
-
getProjectInfo,
|
|
16
18
|
upsertAllVariables,
|
|
17
19
|
} from "../../../../../utils/gitlab";
|
|
18
20
|
import { connectToCluster } from "../../../../../utils/cluster";
|
|
@@ -20,7 +22,10 @@ import { connectToCluster } from "../../../../../utils/cluster";
|
|
|
20
22
|
export const setupKubernetes = async (
|
|
21
23
|
vorpal: CommandInstance,
|
|
22
24
|
context: ComponentContext,
|
|
23
|
-
|
|
25
|
+
{
|
|
26
|
+
projectId,
|
|
27
|
+
...existing
|
|
28
|
+
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
24
29
|
) => {
|
|
25
30
|
const deployConfig = context.deploy?.config;
|
|
26
31
|
if (!isOfDeployType(deployConfig, "kubernetes")) {
|
|
@@ -32,11 +37,11 @@ export const setupKubernetes = async (
|
|
|
32
37
|
token: inputToken,
|
|
33
38
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
34
39
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
const {
|
|
40
|
+
const id =
|
|
41
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
42
|
+
const requestInfo = { host, path, token, projectId: id };
|
|
38
43
|
const deploy_tokens = await doGitlabRequest(vorpal, {
|
|
39
|
-
path: `projects/${
|
|
44
|
+
path: `projects/${id}/deploy_tokens`,
|
|
40
45
|
host,
|
|
41
46
|
token,
|
|
42
47
|
});
|
|
@@ -51,9 +56,9 @@ export const setupKubernetes = async (
|
|
|
51
56
|
);
|
|
52
57
|
|
|
53
58
|
await doGitlabRequest(vorpal, {
|
|
54
|
-
path: `projects/${
|
|
59
|
+
path: `projects/${id}/deploy_tokens`,
|
|
55
60
|
data: {
|
|
56
|
-
id
|
|
61
|
+
id,
|
|
57
62
|
name: "gitlab-deploy-token",
|
|
58
63
|
scopes: ["read_registry"],
|
|
59
64
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LoggerCmdInstance } from "../log";
|
|
2
|
+
import { getPreferences, upsertPreferences } from "../preferences";
|
|
2
3
|
import { fetchGitLabApi } from "./fetchGitLabApi";
|
|
3
4
|
import { getGitLabHostPathToken } from "./getGitlabHostPathToken";
|
|
4
5
|
import type { GitLabApiDataOptional } from "./GitLabApiDataOptional";
|
|
@@ -37,3 +38,20 @@ export const gitLabProjectByGitPath = async (
|
|
|
37
38
|
logger,
|
|
38
39
|
);
|
|
39
40
|
};
|
|
41
|
+
|
|
42
|
+
export const getGitLabProjectId = async (
|
|
43
|
+
existing: GitLabApiDataOptional = {},
|
|
44
|
+
logger: LoggerCmdInstance = console,
|
|
45
|
+
) => {
|
|
46
|
+
const [preferences, { host, path, token }] = await Promise.all([
|
|
47
|
+
getPreferences(logger),
|
|
48
|
+
getGitLabHostPathToken(existing, logger),
|
|
49
|
+
]);
|
|
50
|
+
const hostPathKey = `${host}/${path}`;
|
|
51
|
+
if (preferences.gitLabProjectIds[hostPathKey]) {
|
|
52
|
+
return preferences.gitLabProjectIds[hostPathKey];
|
|
53
|
+
}
|
|
54
|
+
const project = await gitLabProjectByGitPath({ token, host, path }, logger);
|
|
55
|
+
await upsertPreferences({ gitLabProjectIds: { [hostPathKey]: project.id } });
|
|
56
|
+
return project.id;
|
|
57
|
+
};
|
|
@@ -5,7 +5,7 @@ import type { LoggerCmdInstance } from "../log";
|
|
|
5
5
|
import { fetchGitLabApi } from "./fetchGitLabApi";
|
|
6
6
|
import type { GitLabApiDataOptional } from "./GitLabApiDataOptional";
|
|
7
7
|
import { getGitLabHostPathToken } from "./getGitlabHostPathToken";
|
|
8
|
-
import {
|
|
8
|
+
import { getGitLabProjectId } from "./gitLabProjectByGitPath";
|
|
9
9
|
import { GitLabTokenMissingError } from "./GitLabTokenMissingError";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -191,9 +191,8 @@ const getAllVariables = memoizee(
|
|
|
191
191
|
if (!token?.length) {
|
|
192
192
|
throw new GitLabTokenMissingError();
|
|
193
193
|
}
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
: await gitLabProjectByGitPath({ host, path, token }, logger);
|
|
194
|
+
const id =
|
|
195
|
+
projectId || (await getGitLabProjectId({ host, path, token }, logger));
|
|
197
196
|
|
|
198
197
|
let all: GitlabVariable[] = [];
|
|
199
198
|
let result: GitlabVariable[][] = [];
|
|
@@ -234,9 +233,8 @@ const getAllCatladderEnvVars = async ({
|
|
|
234
233
|
if (!token?.length) {
|
|
235
234
|
throw new GitLabTokenMissingError();
|
|
236
235
|
}
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
: await gitLabProjectByGitPath({ host, path, token }, logger);
|
|
236
|
+
const id =
|
|
237
|
+
projectId || (await getGitLabProjectId({ host, path, token }, logger));
|
|
240
238
|
|
|
241
239
|
const fetchResults = await gitLabVariable.getAll({
|
|
242
240
|
projectId: id,
|
package/src/utils/gitlab.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { CommandInstance } from "vorpal";
|
|
|
4
4
|
|
|
5
5
|
import { getSecretVarName } from "@catladder/pipeline";
|
|
6
6
|
import { getGitRemoteHost } from "../git/gitProjectInformation";
|
|
7
|
-
import { logError, logNotice, logLines
|
|
7
|
+
import { logError, logNotice, logLines } from "./log";
|
|
8
8
|
import {
|
|
9
9
|
type FetchMethod,
|
|
10
10
|
type GitLabApiDataOptional,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
storeGitLabToken,
|
|
15
15
|
gitLabVariable,
|
|
16
16
|
getGitLabHostPathToken,
|
|
17
|
-
|
|
17
|
+
getGitLabProjectId,
|
|
18
18
|
} from "./gitlab-without-vorpal";
|
|
19
19
|
|
|
20
20
|
export const setupGitlabToken = async (
|
|
@@ -99,23 +99,13 @@ export const doGitlabRequest = async <T = any>(
|
|
|
99
99
|
},
|
|
100
100
|
): Promise<T> => fetchGitLabApi<T>({ resourcePath, ...args }, vorpal);
|
|
101
101
|
|
|
102
|
-
export const getProjectInfo = async (
|
|
103
|
-
vorpal: CommandInstance | null,
|
|
104
|
-
existing: GitLabApiDataOptional = {},
|
|
105
|
-
) => {
|
|
106
|
-
const {
|
|
107
|
-
host,
|
|
108
|
-
path,
|
|
109
|
-
token: inputToken,
|
|
110
|
-
} = await getGitLabHostPathToken(existing, vorpal);
|
|
111
|
-
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
112
|
-
return gitLabProjectByGitPath({ host, path, token }, vorpal);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
102
|
export const getVariableValueByRawName = async (
|
|
116
103
|
vorpal: CommandInstance,
|
|
117
104
|
rawName: string,
|
|
118
|
-
|
|
105
|
+
{
|
|
106
|
+
projectId,
|
|
107
|
+
...existing
|
|
108
|
+
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
119
109
|
) => {
|
|
120
110
|
const {
|
|
121
111
|
host,
|
|
@@ -123,13 +113,14 @@ export const getVariableValueByRawName = async (
|
|
|
123
113
|
token: inputToken,
|
|
124
114
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
125
115
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
126
|
-
const
|
|
116
|
+
const id =
|
|
117
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
127
118
|
const allVariables = await gitLabVariable.getAll({
|
|
128
119
|
logger: vorpal,
|
|
129
120
|
host,
|
|
130
121
|
path,
|
|
131
122
|
token,
|
|
132
|
-
projectId,
|
|
123
|
+
projectId: id,
|
|
133
124
|
});
|
|
134
125
|
return allVariables.find((v) => v.key === rawName)?.value;
|
|
135
126
|
};
|
|
@@ -147,12 +138,14 @@ const getAllCatladderEnvVarsInGitlab = async (
|
|
|
147
138
|
token: inputToken,
|
|
148
139
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
149
140
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
141
|
+
const id =
|
|
142
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
150
143
|
return gitLabVariable.getAllCatladder({
|
|
151
144
|
logger: vorpal,
|
|
152
145
|
host,
|
|
153
146
|
path,
|
|
154
147
|
token,
|
|
155
|
-
projectId,
|
|
148
|
+
projectId: id,
|
|
156
149
|
});
|
|
157
150
|
};
|
|
158
151
|
|
|
@@ -170,7 +163,7 @@ export const clearBackups = async (
|
|
|
170
163
|
token: inputToken,
|
|
171
164
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
172
165
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
173
|
-
const
|
|
166
|
+
const id = await getGitLabProjectId({ host, path, token }, vorpal);
|
|
174
167
|
|
|
175
168
|
const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal, {
|
|
176
169
|
projectId: id,
|
|
@@ -199,7 +192,10 @@ export const upsertAllVariables = async (
|
|
|
199
192
|
componentName: string,
|
|
200
193
|
backup = true,
|
|
201
194
|
masked = true, // FIXME: would be better to have this per variable
|
|
202
|
-
|
|
195
|
+
{
|
|
196
|
+
projectId,
|
|
197
|
+
...existing
|
|
198
|
+
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
203
199
|
): Promise<void> => {
|
|
204
200
|
const {
|
|
205
201
|
host,
|
|
@@ -207,7 +203,8 @@ export const upsertAllVariables = async (
|
|
|
207
203
|
token: inputToken,
|
|
208
204
|
} = await getGitLabHostPathToken(existing, vorpal);
|
|
209
205
|
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
210
|
-
const
|
|
206
|
+
const id =
|
|
207
|
+
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
211
208
|
|
|
212
209
|
// we list all existing variables. We also gather backup versions, but its currently unused
|
|
213
210
|
const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal, {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const gitlabPersonalAccessToken = "gitlab-personal-access-token";
|
|
2
2
|
const googleAuthUserNumber = "googleAuthUserNumber";
|
|
3
3
|
const gitlabTokens = "gitlabTokens";
|
|
4
|
+
const gitLabProjectIds = "gitLabProjectIds";
|
|
4
5
|
|
|
5
6
|
const preferenceKeys = [
|
|
6
7
|
gitlabPersonalAccessToken,
|
|
7
8
|
googleAuthUserNumber,
|
|
8
9
|
gitlabTokens,
|
|
10
|
+
gitLabProjectIds,
|
|
9
11
|
] as const;
|
|
10
12
|
|
|
11
13
|
export type CatladderPreferences = {
|
|
@@ -18,12 +20,14 @@ export type CatladderPreferences = {
|
|
|
18
20
|
* GitLab tokens by GitLab instance hostname.
|
|
19
21
|
*/
|
|
20
22
|
[gitlabTokens]: { [instanceHostname in string]: string };
|
|
23
|
+
[gitLabProjectIds]: { [hostnameProjectPath in string]: number };
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
const perfFallback: CatladderPreferences = {
|
|
24
27
|
[gitlabPersonalAccessToken]: undefined,
|
|
25
28
|
[googleAuthUserNumber]: undefined,
|
|
26
29
|
[gitlabTokens]: {},
|
|
30
|
+
[gitLabProjectIds]: {},
|
|
27
31
|
};
|
|
28
32
|
|
|
29
33
|
/**
|