@pipelab/core-node 1.0.1-beta.24 → 1.0.1-beta.26
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/CHANGELOG.md +18 -0
- package/dist/index.d.mts +10 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +49 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
- package/src/handlers/build-history.ts +28 -7
- package/src/runner.ts +2 -1
- package/src/utils/fs-extras.ts +30 -1
- package/src/utils.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipelab/core-node",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.26",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Pipelab automation engine for Node.js",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"adm-zip": "0.5.16",
|
|
30
30
|
"archiver": "7.0.1",
|
|
31
|
+
"check-disk-space": "3.4.0",
|
|
31
32
|
"es-toolkit": "1.25.2",
|
|
32
33
|
"execa": "9.5.2",
|
|
33
34
|
"nanoid": "5.0.7",
|
|
@@ -38,8 +39,8 @@
|
|
|
38
39
|
"type-fest": "4.39.0",
|
|
39
40
|
"ws": "8.18.3",
|
|
40
41
|
"yauzl": "2.10.0",
|
|
41
|
-
"@pipelab/constants": "1.0.1-beta.
|
|
42
|
-
"@pipelab/shared": "2.0.1-beta.
|
|
42
|
+
"@pipelab/constants": "1.0.1-beta.22",
|
|
43
|
+
"@pipelab/shared": "2.0.1-beta.23"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@types/adm-zip": "0.5.7",
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"@types/yauzl": "2.10.3",
|
|
53
54
|
"tsdown": "0.21.2",
|
|
54
55
|
"typescript": "^5.0.0",
|
|
55
|
-
"@pipelab/tsconfig": "1.0.1-beta.
|
|
56
|
+
"@pipelab/tsconfig": "1.0.1-beta.22"
|
|
56
57
|
},
|
|
57
58
|
"scripts": {
|
|
58
59
|
"build": "tsdown",
|
|
@@ -2,9 +2,10 @@ import { PipelabContext } from "../context";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writeFile, readFile, unlink, mkdir, stat, readdir } from "node:fs/promises";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
|
-
import { BuildHistoryEntry, IBuildHistoryStorage, AppConfig } from "@pipelab/shared";
|
|
6
|
-
import { useLogger } from "@pipelab/shared";
|
|
5
|
+
import { useLogger, BuildHistoryEntry, IBuildHistoryStorage, AppConfig } from "@pipelab/shared";
|
|
7
6
|
import { setupConfigFile } from "../config";
|
|
7
|
+
import checkDiskSpace from "check-disk-space";
|
|
8
|
+
import { getFolderSize } from "../utils/fs-extras";
|
|
8
9
|
|
|
9
10
|
// Simplified storage - one file per pipeline containing array of build entries
|
|
10
11
|
|
|
@@ -128,6 +129,11 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
|
|
|
128
129
|
this.logger
|
|
129
130
|
.logger()
|
|
130
131
|
.info(`Saved build history entry: ${entry.id} for pipeline: ${entry.pipelineId}`);
|
|
132
|
+
|
|
133
|
+
// Apply retention policy after each save
|
|
134
|
+
this.applyRetentionPolicy().catch((err) => {
|
|
135
|
+
this.logger.logger().error("Failed to apply retention policy after save:", err);
|
|
136
|
+
});
|
|
131
137
|
} catch (error) {
|
|
132
138
|
this.logger.logger().error("Failed to save build history entry:", error);
|
|
133
139
|
throw new Error(`Failed to save build history entry: ${error}`);
|
|
@@ -280,24 +286,31 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
|
|
|
280
286
|
oldestEntry?: number;
|
|
281
287
|
newestEntry?: number;
|
|
282
288
|
numberOfPipelines: number;
|
|
283
|
-
cachePath: string;
|
|
284
289
|
userDataPath: string;
|
|
285
290
|
retentionPolicy: {
|
|
286
291
|
enabled: boolean;
|
|
287
292
|
maxEntries: number;
|
|
288
293
|
maxAge: number;
|
|
289
294
|
};
|
|
295
|
+
disk: {
|
|
296
|
+
total: number;
|
|
297
|
+
free: number;
|
|
298
|
+
pipelab: number;
|
|
299
|
+
};
|
|
290
300
|
}> {
|
|
291
301
|
try {
|
|
292
302
|
const allEntries = await this.getAll();
|
|
293
303
|
const files = await this.getAllPipelineFiles();
|
|
294
304
|
|
|
305
|
+
const diskSpace = await checkDiskSpace(this.context.userDataPath);
|
|
306
|
+
const pipelabSize = await getFolderSize(this.context.userDataPath);
|
|
307
|
+
|
|
295
308
|
const settings = await setupConfigFile<AppConfig>("settings", { context: this.context });
|
|
296
309
|
const config = await settings.getConfig();
|
|
297
310
|
const policy = config?.buildHistory?.retentionPolicy || {
|
|
298
311
|
enabled: false,
|
|
299
|
-
maxEntries:
|
|
300
|
-
maxAge:
|
|
312
|
+
maxEntries: 50,
|
|
313
|
+
maxAge: 30,
|
|
301
314
|
};
|
|
302
315
|
|
|
303
316
|
if (allEntries.length === 0) {
|
|
@@ -305,13 +318,17 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
|
|
|
305
318
|
totalEntries: 0,
|
|
306
319
|
totalSize: 0,
|
|
307
320
|
numberOfPipelines: files.length,
|
|
308
|
-
cachePath: config?.cacheFolder || tmpdir(),
|
|
309
321
|
userDataPath: this.context.userDataPath,
|
|
310
322
|
retentionPolicy: {
|
|
311
323
|
enabled: policy.enabled,
|
|
312
324
|
maxEntries: policy.maxEntries,
|
|
313
325
|
maxAge: policy.maxAge,
|
|
314
326
|
},
|
|
327
|
+
disk: {
|
|
328
|
+
total: diskSpace.size,
|
|
329
|
+
free: diskSpace.free,
|
|
330
|
+
pipelab: pipelabSize,
|
|
331
|
+
},
|
|
315
332
|
};
|
|
316
333
|
}
|
|
317
334
|
|
|
@@ -334,13 +351,17 @@ export class BuildHistoryStorage implements IBuildHistoryStorage {
|
|
|
334
351
|
oldestEntry: sortedEntries[0]?.createdAt,
|
|
335
352
|
newestEntry: sortedEntries[sortedEntries.length - 1]?.createdAt,
|
|
336
353
|
numberOfPipelines: files.length,
|
|
337
|
-
cachePath: config?.cacheFolder || tmpdir(),
|
|
338
354
|
userDataPath: this.context.userDataPath,
|
|
339
355
|
retentionPolicy: {
|
|
340
356
|
enabled: policy.enabled,
|
|
341
357
|
maxEntries: policy.maxEntries,
|
|
342
358
|
maxAge: policy.maxAge,
|
|
343
359
|
},
|
|
360
|
+
disk: {
|
|
361
|
+
total: diskSpace.size,
|
|
362
|
+
free: diskSpace.free,
|
|
363
|
+
pipelab: pipelabSize,
|
|
364
|
+
},
|
|
344
365
|
};
|
|
345
366
|
} catch (error) {
|
|
346
367
|
this.logger.logger().error("Failed to get storage info:", error);
|
package/src/runner.ts
CHANGED
|
@@ -69,7 +69,8 @@ export async function runPipelineCommand(file: string, options: RunOptions, vers
|
|
|
69
69
|
|
|
70
70
|
const settings = await setupConfigFile<AppConfig>("settings", { context });
|
|
71
71
|
const config = await settings.getConfig();
|
|
72
|
-
const cachePath =
|
|
72
|
+
const cachePath = join(context.userDataPath, "cache");
|
|
73
|
+
await mkdir(cachePath, { recursive: true });
|
|
73
74
|
|
|
74
75
|
const abortController = new AbortController();
|
|
75
76
|
|
package/src/utils/fs-extras.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, createWriteStream, createReadStream } from "node:fs";
|
|
2
2
|
import { execa, Options, Subprocess } from "execa";
|
|
3
|
-
import { mkdir as mkdirP, access, writeFile, realpath, mkdtemp, chmod } from "node:fs/promises";
|
|
3
|
+
import { mkdir as mkdirP, access, writeFile, realpath, mkdtemp, chmod, stat, readdir } from "node:fs/promises";
|
|
4
4
|
import { join, dirname } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import tar from "tar";
|
|
@@ -180,3 +180,32 @@ export const runWithLiveLogs = async (
|
|
|
180
180
|
throw new Error(`Command failed with exit code ${code}: ${error.message}`);
|
|
181
181
|
}
|
|
182
182
|
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Calculates the total size of a directory recursively.
|
|
186
|
+
*/
|
|
187
|
+
export async function getFolderSize(dirPath: string): Promise<number> {
|
|
188
|
+
try {
|
|
189
|
+
const files = await readdir(dirPath, { withFileTypes: true });
|
|
190
|
+
const ArrayOfPromises = files.map(async (file) => {
|
|
191
|
+
const path = join(dirPath, file.name);
|
|
192
|
+
if (file.isDirectory()) {
|
|
193
|
+
try {
|
|
194
|
+
return await getFolderSize(path);
|
|
195
|
+
} catch {
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const { size } = await stat(path);
|
|
201
|
+
return size;
|
|
202
|
+
} catch {
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
const results = await Promise.all(ArrayOfPromises);
|
|
207
|
+
return results.reduce((acc, size) => acc + size, 0);
|
|
208
|
+
} catch {
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -156,7 +156,7 @@ export const executeGraphWithHistory = async ({
|
|
|
156
156
|
logger().info(`[Sandbox] Execution sandbox created at: ${sandboxPath}`);
|
|
157
157
|
const settingsFile = await setupConfigFile<AppConfig>("settings", { context: ctx });
|
|
158
158
|
const config = await settingsFile.getConfig();
|
|
159
|
-
const shouldCleanup =
|
|
159
|
+
const shouldCleanup = true;
|
|
160
160
|
|
|
161
161
|
try {
|
|
162
162
|
const result = await processGraph({
|