@oneuptime/common 8.0.5469 → 8.0.5479
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/Server/Services/DatabaseService.ts +70 -0
- package/Server/Services/ProjectService.ts +24 -0
- package/Server/Types/Database/FindAllBy.ts +25 -0
- package/Server/Utils/CodeRepository/CodeRepository.ts +145 -84
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +20 -9
- package/Server/Utils/Execute.ts +25 -4
- package/Server/Utils/Monitor/MonitorResource.ts +246 -256
- package/build/dist/Server/Services/DatabaseService.js +59 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +19 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Types/Database/FindAllBy.js +2 -0
- package/build/dist/Server/Types/Database/FindAllBy.js.map +1 -0
- package/build/dist/Server/Utils/CodeRepository/CodeRepository.js +107 -56
- package/build/dist/Server/Utils/CodeRepository/CodeRepository.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +15 -6
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +10 -4
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +220 -206
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import { EncryptionSecret, WorkflowHostname } from "../EnvironmentConfig";
|
|
|
2
2
|
import PostgresAppInstance from "../Infrastructure/PostgresDatabase";
|
|
3
3
|
import ClusterKeyAuthorization from "../Middleware/ClusterKeyAuthorization";
|
|
4
4
|
import CountBy from "../Types/Database/CountBy";
|
|
5
|
+
import FindAllBy from "../Types/Database/FindAllBy";
|
|
5
6
|
import CreateBy from "../Types/Database/CreateBy";
|
|
6
7
|
import DeleteBy from "../Types/Database/DeleteBy";
|
|
7
8
|
import DeleteById from "../Types/Database/DeleteById";
|
|
@@ -1168,6 +1169,75 @@ class DatabaseService<TBaseModel extends BaseModel> extends BaseService {
|
|
|
1168
1169
|
}
|
|
1169
1170
|
}
|
|
1170
1171
|
|
|
1172
|
+
@CaptureSpan()
|
|
1173
|
+
public async findAllBy(
|
|
1174
|
+
findAllBy: FindAllBy<TBaseModel>,
|
|
1175
|
+
): Promise<Array<TBaseModel>> {
|
|
1176
|
+
const { limit, skip, ...rest } = findAllBy;
|
|
1177
|
+
|
|
1178
|
+
let remaining: number | undefined = this.normalizePositiveNumber(limit);
|
|
1179
|
+
let currentSkip: number = this.normalizePositiveNumber(skip) || 0;
|
|
1180
|
+
|
|
1181
|
+
const results: Array<TBaseModel> = [];
|
|
1182
|
+
|
|
1183
|
+
while (true) {
|
|
1184
|
+
const currentBatchSize: number =
|
|
1185
|
+
remaining !== undefined
|
|
1186
|
+
? Math.min(LIMIT_MAX, Math.max(remaining, 0))
|
|
1187
|
+
: LIMIT_MAX;
|
|
1188
|
+
|
|
1189
|
+
if (currentBatchSize <= 0) {
|
|
1190
|
+
break;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
const page: Array<TBaseModel> = await this.findBy({
|
|
1194
|
+
...rest,
|
|
1195
|
+
skip: currentSkip,
|
|
1196
|
+
limit: currentBatchSize,
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
if (page.length === 0) {
|
|
1200
|
+
break;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
results.push(...page);
|
|
1204
|
+
|
|
1205
|
+
currentSkip += page.length;
|
|
1206
|
+
|
|
1207
|
+
if (remaining !== undefined) {
|
|
1208
|
+
remaining -= page.length;
|
|
1209
|
+
|
|
1210
|
+
if (remaining <= 0) {
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
if (page.length < currentBatchSize) {
|
|
1216
|
+
break;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
return results;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
private normalizePositiveNumber(
|
|
1224
|
+
value?: PositiveNumber | number,
|
|
1225
|
+
): number | undefined {
|
|
1226
|
+
if (value === undefined || value === null) {
|
|
1227
|
+
return undefined;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
if (value instanceof PositiveNumber) {
|
|
1231
|
+
return value.toNumber();
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
if (typeof value === "number") {
|
|
1235
|
+
return value;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
return undefined;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1171
1241
|
@CaptureSpan()
|
|
1172
1242
|
public async findBy(findBy: FindBy<TBaseModel>): Promise<Array<TBaseModel>> {
|
|
1173
1243
|
return await this._findBy(findBy);
|
|
@@ -71,6 +71,8 @@ import URL from "../../Types/API/URL";
|
|
|
71
71
|
import Exception from "../../Types/Exception/Exception";
|
|
72
72
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
73
73
|
import DatabaseConfig from "../DatabaseConfig";
|
|
74
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
75
|
+
import PositiveNumber from "../../Types/PositiveNumber";
|
|
74
76
|
|
|
75
77
|
export interface CurrentPlan {
|
|
76
78
|
plan: PlanType | null;
|
|
@@ -1435,6 +1437,28 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
1435
1437
|
};
|
|
1436
1438
|
}
|
|
1437
1439
|
|
|
1440
|
+
@CaptureSpan()
|
|
1441
|
+
public async getAllActiveProjects(params?: {
|
|
1442
|
+
select?: Select<Model>;
|
|
1443
|
+
props?: DatabaseCommonInteractionProps;
|
|
1444
|
+
skip?: PositiveNumber | number;
|
|
1445
|
+
limit?: PositiveNumber | number;
|
|
1446
|
+
}): Promise<Array<Model>> {
|
|
1447
|
+
const select: Select<Model> | undefined =
|
|
1448
|
+
params?.select || ({ _id: true } as Select<Model>);
|
|
1449
|
+
const props: DatabaseCommonInteractionProps = params?.props || {
|
|
1450
|
+
isRoot: true,
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
return await this.findAllBy({
|
|
1454
|
+
query: this.getActiveProjectStatusQuery(),
|
|
1455
|
+
select,
|
|
1456
|
+
props,
|
|
1457
|
+
skip: params?.skip,
|
|
1458
|
+
limit: params?.limit,
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1438
1462
|
@CaptureSpan()
|
|
1439
1463
|
public async getProjectLinkInDashboard(projectId: ObjectID): Promise<URL> {
|
|
1440
1464
|
const dashboardUrl: URL = await DatabaseConfig.getDashboardUrl();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
2
|
+
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
3
|
+
import GroupBy from "./GroupBy";
|
|
4
|
+
import Query from "./Query";
|
|
5
|
+
import Select from "./Select";
|
|
6
|
+
import Sort from "./Sort";
|
|
7
|
+
import PositiveNumber from "../../../Types/PositiveNumber";
|
|
8
|
+
|
|
9
|
+
export default interface FindAllBy<TBaseModel extends BaseModel> {
|
|
10
|
+
query: Query<TBaseModel>;
|
|
11
|
+
select?: Select<TBaseModel> | undefined;
|
|
12
|
+
sort?: Sort<TBaseModel> | undefined;
|
|
13
|
+
groupBy?: GroupBy<TBaseModel> | undefined;
|
|
14
|
+
props: DatabaseCommonInteractionProps;
|
|
15
|
+
/**
|
|
16
|
+
* Optional number of documents to skip before fetching results.
|
|
17
|
+
* Acts the same way as `skip` in `findBy` but defaults to 0 when omitted.
|
|
18
|
+
*/
|
|
19
|
+
skip?: PositiveNumber | number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Optional total number of documents to return across all batches.
|
|
22
|
+
* When omitted, the method keeps fetching until no more data is returned.
|
|
23
|
+
*/
|
|
24
|
+
limit?: PositiveNumber | number | undefined;
|
|
25
|
+
}
|
|
@@ -13,24 +13,14 @@ export default class CodeRepositoryUtil {
|
|
|
13
13
|
public static getCurrentCommitHash(data: {
|
|
14
14
|
repoPath: string;
|
|
15
15
|
}): Promise<string> {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
logger.debug("Executing command: " + command);
|
|
19
|
-
|
|
20
|
-
return Execute.executeCommand(command);
|
|
16
|
+
return this.runGitCommand(data.repoPath, ["rev-parse", "HEAD"]);
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
@CaptureSpan()
|
|
24
20
|
public static async addAllChangedFilesToGit(data: {
|
|
25
21
|
repoPath: string;
|
|
26
22
|
}): Promise<void> {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
logger.debug("Executing command: " + command);
|
|
30
|
-
|
|
31
|
-
const stdout: string = await Execute.executeCommand(command);
|
|
32
|
-
|
|
33
|
-
logger.debug(stdout);
|
|
23
|
+
await this.runGitCommand(data.repoPath, ["add", "-A"]);
|
|
34
24
|
}
|
|
35
25
|
|
|
36
26
|
@CaptureSpan()
|
|
@@ -39,26 +29,26 @@ export default class CodeRepositoryUtil {
|
|
|
39
29
|
authorName: string;
|
|
40
30
|
authorEmail: string;
|
|
41
31
|
}): Promise<void> {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
await this.runGitCommand(data.repoPath, [
|
|
33
|
+
"config",
|
|
34
|
+
"--global",
|
|
35
|
+
"user.name",
|
|
36
|
+
data.authorName,
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
await this.runGitCommand(data.repoPath, [
|
|
40
|
+
"config",
|
|
41
|
+
"--global",
|
|
42
|
+
"user.email",
|
|
43
|
+
data.authorEmail,
|
|
44
|
+
]);
|
|
49
45
|
}
|
|
50
46
|
|
|
51
47
|
@CaptureSpan()
|
|
52
48
|
public static async discardAllChangesOnCurrentBranch(data: {
|
|
53
49
|
repoPath: string;
|
|
54
50
|
}): Promise<void> {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
logger.debug("Executing command: " + command);
|
|
58
|
-
|
|
59
|
-
const stdout: string = await Execute.executeCommand(command);
|
|
60
|
-
|
|
61
|
-
logger.debug(stdout);
|
|
51
|
+
await this.runGitCommand(data.repoPath, ["checkout", "."]);
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
// returns the folder name of the cloned repository
|
|
@@ -67,33 +57,25 @@ export default class CodeRepositoryUtil {
|
|
|
67
57
|
repoPath: string;
|
|
68
58
|
repoUrl: string;
|
|
69
59
|
}): Promise<string> {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
logger.debug("Executing command: " + command);
|
|
73
|
-
|
|
74
|
-
const stdout: string = await Execute.executeCommand(command);
|
|
60
|
+
await this.runGitCommand(data.repoPath, ["clone", data.repoUrl]);
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
62
|
+
const normalizedUrl: string = data.repoUrl.trim().replace(/\/+$/g, "");
|
|
63
|
+
const lastSegment: string =
|
|
64
|
+
normalizedUrl.split("/").pop() || normalizedUrl.split(":").pop() || "";
|
|
65
|
+
const folderName: string = lastSegment.replace(/\.git$/i, "");
|
|
79
66
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
67
|
+
if (!folderName) {
|
|
68
|
+
throw new BadDataException(
|
|
69
|
+
"Unable to determine repository folder name after cloning.",
|
|
70
|
+
);
|
|
71
|
+
}
|
|
84
72
|
|
|
85
73
|
return folderName.trim();
|
|
86
74
|
}
|
|
87
75
|
|
|
88
76
|
@CaptureSpan()
|
|
89
77
|
public static async pullChanges(data: { repoPath: string }): Promise<void> {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
logger.debug("Executing command: " + command);
|
|
93
|
-
|
|
94
|
-
const stdout: string = await Execute.executeCommand(command);
|
|
95
|
-
|
|
96
|
-
logger.debug(stdout);
|
|
78
|
+
await this.runGitCommand(data.repoPath, ["pull"]);
|
|
97
79
|
}
|
|
98
80
|
|
|
99
81
|
@CaptureSpan()
|
|
@@ -101,13 +83,26 @@ export default class CodeRepositoryUtil {
|
|
|
101
83
|
repoPath: string;
|
|
102
84
|
branchName: string;
|
|
103
85
|
}): Promise<void> {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
86
|
+
try {
|
|
87
|
+
await this.runGitCommand(data.repoPath, [
|
|
88
|
+
"rev-parse",
|
|
89
|
+
"--verify",
|
|
90
|
+
data.branchName,
|
|
91
|
+
]);
|
|
92
|
+
await this.runGitCommand(data.repoPath, ["checkout", data.branchName]);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
logger.debug(
|
|
95
|
+
`Branch ${data.branchName} not found. Creating a new branch instead.`,
|
|
96
|
+
);
|
|
107
97
|
|
|
108
|
-
|
|
98
|
+
logger.debug(error);
|
|
109
99
|
|
|
110
|
-
|
|
100
|
+
await this.runGitCommand(data.repoPath, [
|
|
101
|
+
"checkout",
|
|
102
|
+
"-b",
|
|
103
|
+
data.branchName,
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
111
106
|
}
|
|
112
107
|
|
|
113
108
|
@CaptureSpan()
|
|
@@ -128,13 +123,7 @@ export default class CodeRepositoryUtil {
|
|
|
128
123
|
public static async discardChanges(data: {
|
|
129
124
|
repoPath: string;
|
|
130
125
|
}): Promise<void> {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
logger.debug("Executing command: " + command);
|
|
134
|
-
|
|
135
|
-
const stdout: string = await Execute.executeCommand(command);
|
|
136
|
-
|
|
137
|
-
logger.debug(stdout);
|
|
126
|
+
await this.runGitCommand(data.repoPath, ["checkout", "."]);
|
|
138
127
|
}
|
|
139
128
|
|
|
140
129
|
@CaptureSpan()
|
|
@@ -193,11 +182,15 @@ export default class CodeRepositoryUtil {
|
|
|
193
182
|
repoPath: string;
|
|
194
183
|
branchName: string;
|
|
195
184
|
}): Promise<void> {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
185
|
+
logger.debug(
|
|
186
|
+
`Creating git branch '${data.branchName}' in ${path.resolve(data.repoPath)}`,
|
|
187
|
+
);
|
|
199
188
|
|
|
200
|
-
const stdout: string = await
|
|
189
|
+
const stdout: string = await this.runGitCommand(data.repoPath, [
|
|
190
|
+
"checkout",
|
|
191
|
+
"-b",
|
|
192
|
+
data.branchName,
|
|
193
|
+
]);
|
|
201
194
|
|
|
202
195
|
logger.debug(stdout);
|
|
203
196
|
}
|
|
@@ -207,11 +200,14 @@ export default class CodeRepositoryUtil {
|
|
|
207
200
|
repoPath: string;
|
|
208
201
|
branchName: string;
|
|
209
202
|
}): Promise<void> {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
203
|
+
logger.debug(
|
|
204
|
+
`Checking out git branch '${data.branchName}' in ${path.resolve(data.repoPath)}`,
|
|
205
|
+
);
|
|
213
206
|
|
|
214
|
-
const stdout: string = await
|
|
207
|
+
const stdout: string = await this.runGitCommand(data.repoPath, [
|
|
208
|
+
"checkout",
|
|
209
|
+
data.branchName,
|
|
210
|
+
]);
|
|
215
211
|
|
|
216
212
|
logger.debug(stdout);
|
|
217
213
|
}
|
|
@@ -221,22 +217,51 @@ export default class CodeRepositoryUtil {
|
|
|
221
217
|
repoPath: string;
|
|
222
218
|
filePaths: Array<string>;
|
|
223
219
|
}): Promise<void> {
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
220
|
+
const repoRoot: string = path.resolve(data.repoPath);
|
|
221
|
+
|
|
222
|
+
const sanitizedRelativeFilePaths: Array<string> = [];
|
|
223
|
+
|
|
224
|
+
for (const inputFilePath of data.filePaths) {
|
|
225
|
+
const normalizedPath: string = inputFilePath.startsWith("/")
|
|
226
|
+
? inputFilePath.substring(1)
|
|
227
|
+
: inputFilePath;
|
|
228
|
+
|
|
229
|
+
if (normalizedPath.trim() === "") {
|
|
230
|
+
continue;
|
|
228
231
|
}
|
|
229
232
|
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
const absoluteFilePath: string = this.resolvePathWithinRepo(
|
|
234
|
+
data.repoPath,
|
|
235
|
+
normalizedPath,
|
|
236
|
+
);
|
|
232
237
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
238
|
+
const relativeFilePath: string = path.relative(
|
|
239
|
+
repoRoot,
|
|
240
|
+
absoluteFilePath,
|
|
241
|
+
);
|
|
236
242
|
|
|
237
|
-
|
|
243
|
+
if (relativeFilePath.trim() === "") {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
238
246
|
|
|
239
|
-
|
|
247
|
+
sanitizedRelativeFilePaths.push(
|
|
248
|
+
LocalFile.sanitizeFilePath(relativeFilePath),
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (sanitizedRelativeFilePaths.length === 0) {
|
|
253
|
+
logger.debug("git add skipped because no file paths were provided");
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
logger.debug(
|
|
258
|
+
`Adding ${sanitizedRelativeFilePaths.length} file(s) to git in ${path.resolve(data.repoPath)}`,
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const stdout: string = await this.runGitCommand(data.repoPath, [
|
|
262
|
+
"add",
|
|
263
|
+
...sanitizedRelativeFilePaths,
|
|
264
|
+
]);
|
|
240
265
|
|
|
241
266
|
logger.debug(stdout);
|
|
242
267
|
}
|
|
@@ -246,11 +271,13 @@ export default class CodeRepositoryUtil {
|
|
|
246
271
|
repoPath: string;
|
|
247
272
|
username: string;
|
|
248
273
|
}): Promise<void> {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
logger.debug("Executing command: " + command);
|
|
274
|
+
logger.debug(`Setting git user.name in ${path.resolve(data.repoPath)}`);
|
|
252
275
|
|
|
253
|
-
const stdout: string = await
|
|
276
|
+
const stdout: string = await this.runGitCommand(data.repoPath, [
|
|
277
|
+
"config",
|
|
278
|
+
"user.name",
|
|
279
|
+
data.username,
|
|
280
|
+
]);
|
|
254
281
|
|
|
255
282
|
logger.debug(stdout);
|
|
256
283
|
}
|
|
@@ -286,15 +313,28 @@ export default class CodeRepositoryUtil {
|
|
|
286
313
|
|
|
287
314
|
const { repoPath, filePath } = data;
|
|
288
315
|
|
|
289
|
-
const
|
|
316
|
+
const repoRoot: string = path.resolve(repoPath);
|
|
317
|
+
const absoluteTarget: string = this.resolvePathWithinRepo(
|
|
318
|
+
repoPath,
|
|
319
|
+
filePath,
|
|
320
|
+
);
|
|
321
|
+
const relativeTarget: string = path.relative(repoRoot, absoluteTarget);
|
|
322
|
+
const gitArgument: string = LocalFile.sanitizeFilePath(
|
|
323
|
+
`./${relativeTarget}`,
|
|
324
|
+
);
|
|
290
325
|
|
|
291
|
-
logger.debug(
|
|
326
|
+
logger.debug(`Getting last commit hash for ${gitArgument} in ${repoRoot}`);
|
|
292
327
|
|
|
293
|
-
const hash: string = await
|
|
328
|
+
const hash: string = await this.runGitCommand(repoRoot, [
|
|
329
|
+
"log",
|
|
330
|
+
"-1",
|
|
331
|
+
"--pretty=format:%H",
|
|
332
|
+
gitArgument,
|
|
333
|
+
]);
|
|
294
334
|
|
|
295
335
|
logger.debug(hash);
|
|
296
336
|
|
|
297
|
-
return hash;
|
|
337
|
+
return hash.trim();
|
|
298
338
|
}
|
|
299
339
|
|
|
300
340
|
@CaptureSpan()
|
|
@@ -438,6 +478,27 @@ export default class CodeRepositoryUtil {
|
|
|
438
478
|
return files;
|
|
439
479
|
}
|
|
440
480
|
|
|
481
|
+
private static runGitCommand(
|
|
482
|
+
repoPath: string,
|
|
483
|
+
args: Array<string>,
|
|
484
|
+
): Promise<string> {
|
|
485
|
+
const cwd: string = path.resolve(repoPath);
|
|
486
|
+
|
|
487
|
+
logger.debug(
|
|
488
|
+
`Executing git command in ${cwd}: git ${args
|
|
489
|
+
.map((arg: string) => {
|
|
490
|
+
return arg.includes(" ") ? `"${arg}"` : arg;
|
|
491
|
+
})
|
|
492
|
+
.join(" ")}`,
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
return Execute.executeCommandFile({
|
|
496
|
+
command: "git",
|
|
497
|
+
args,
|
|
498
|
+
cwd,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
441
502
|
private static resolvePathWithinRepo(
|
|
442
503
|
repoPath: string,
|
|
443
504
|
targetPath: string,
|
|
@@ -170,13 +170,15 @@ export default class GitHubUtil extends HostedCodeRepository {
|
|
|
170
170
|
`https://github.com/${data.organizationName}/${data.repositoryName}.git`,
|
|
171
171
|
);
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
data.remoteName
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
logger.debug("Executing command: " + command);
|
|
173
|
+
logger.debug(
|
|
174
|
+
`Adding remote '${data.remoteName}' for ${data.organizationName}/${data.repositoryName}`,
|
|
175
|
+
);
|
|
178
176
|
|
|
179
|
-
const result: string = await Execute.
|
|
177
|
+
const result: string = await Execute.executeCommandFile({
|
|
178
|
+
command: "git",
|
|
179
|
+
args: ["remote", "add", data.remoteName, url.toString()],
|
|
180
|
+
cwd: process.cwd(),
|
|
181
|
+
});
|
|
180
182
|
|
|
181
183
|
logger.debug(result);
|
|
182
184
|
}
|
|
@@ -197,10 +199,19 @@ export default class GitHubUtil extends HostedCodeRepository {
|
|
|
197
199
|
"Pushing changes to remote repository with username: " + username,
|
|
198
200
|
);
|
|
199
201
|
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
+
const encodedUsername: string = encodeURIComponent(username);
|
|
203
|
+
const encodedPassword: string = encodeURIComponent(password);
|
|
204
|
+
const remoteUrl: string = `https://${encodedUsername}:${encodedPassword}@github.com/${data.organizationName}/${data.repositoryName}.git`;
|
|
202
205
|
|
|
203
|
-
|
|
206
|
+
logger.debug(
|
|
207
|
+
`Pushing branch '${branchName}' to ${data.organizationName}/${data.repositoryName}`,
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const result: string = await Execute.executeCommandFile({
|
|
211
|
+
command: "git",
|
|
212
|
+
args: ["push", "-u", remoteUrl, branchName],
|
|
213
|
+
cwd: data.repoPath,
|
|
214
|
+
});
|
|
204
215
|
|
|
205
216
|
logger.debug(result);
|
|
206
217
|
}
|
package/Server/Utils/Execute.ts
CHANGED
|
@@ -1,26 +1,47 @@
|
|
|
1
1
|
import { PromiseRejectErrorFunction } from "../../Types/FunctionTypes";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ExecException,
|
|
4
|
+
ExecOptions,
|
|
5
|
+
exec,
|
|
6
|
+
execFile,
|
|
7
|
+
} from "node:child_process";
|
|
3
8
|
import logger from "./Logger";
|
|
4
9
|
import CaptureSpan from "./Telemetry/CaptureSpan";
|
|
5
10
|
|
|
6
11
|
export default class Execute {
|
|
7
12
|
@CaptureSpan()
|
|
8
|
-
public static executeCommand(
|
|
13
|
+
public static executeCommand(
|
|
14
|
+
command: string,
|
|
15
|
+
options?: ExecOptions,
|
|
16
|
+
): Promise<string> {
|
|
9
17
|
return new Promise(
|
|
10
18
|
(
|
|
11
19
|
resolve: (output: string) => void,
|
|
12
20
|
reject: PromiseRejectErrorFunction,
|
|
13
21
|
) => {
|
|
14
|
-
exec(
|
|
22
|
+
exec(
|
|
23
|
+
`${command}`,
|
|
24
|
+
{
|
|
25
|
+
...options,
|
|
26
|
+
},
|
|
27
|
+
(err: ExecException | null, stdout: string, stderr: string) => {
|
|
15
28
|
if (err) {
|
|
16
29
|
logger.error(`Error executing command: ${command}`);
|
|
17
30
|
logger.error(err);
|
|
18
31
|
logger.error(stdout);
|
|
32
|
+
if (stderr) {
|
|
33
|
+
logger.error(stderr);
|
|
34
|
+
}
|
|
19
35
|
return reject(err);
|
|
20
36
|
}
|
|
21
37
|
|
|
38
|
+
if (stderr) {
|
|
39
|
+
logger.debug(stderr);
|
|
40
|
+
}
|
|
41
|
+
|
|
22
42
|
return resolve(stdout);
|
|
23
|
-
|
|
43
|
+
},
|
|
44
|
+
);
|
|
24
45
|
},
|
|
25
46
|
);
|
|
26
47
|
}
|