@pipelab/core-node 1.0.1-beta.25 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipelab/core-node",
3
- "version": "1.0.1-beta.25",
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.21",
42
- "@pipelab/shared": "2.0.1-beta.22"
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.21"
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: 0,
300
- maxAge: 0,
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 = config?.cacheFolder || tmpdir();
72
+ const cachePath = join(context.userDataPath, "cache");
73
+ await mkdir(cachePath, { recursive: true });
73
74
 
74
75
  const abortController = new AbortController();
75
76
 
@@ -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 = config?.clearTemporaryFoldersOnPipelineEnd ?? true;
159
+ const shouldCleanup = true;
160
160
 
161
161
  try {
162
162
  const result = await processGraph({