@pipelab/core-node 1.0.0-beta.16 → 1.0.0-beta.18
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 +12 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +127 -150
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/config.test.ts +23 -15
- package/src/config.ts +18 -21
- package/src/context.ts +19 -2
- package/src/handlers/build-history.ts +47 -90
- package/src/handlers/config.ts +2 -21
- package/src/handlers/engine.ts +26 -22
- package/src/handlers/history.ts +0 -40
- package/src/plugins-registry.ts +4 -3
- package/src/runner.ts +2 -4
- package/src/server.ts +1 -0
- package/src/utils/github.test.ts +3 -5
- package/src/utils/github.ts +3 -0
- package/src/utils/remote.test.ts +15 -6
- package/src/utils/remote.ts +8 -5
- package/src/utils/storage.ts +2 -1
- package/src/utils.ts +6 -6
package/src/runner.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { executeGraphWithHistory } from "./utils";
|
|
2
2
|
import { setupConfigFile } from "./config";
|
|
3
|
-
import { isDev, PipelabContext } from "./context";
|
|
3
|
+
import { isDev, PipelabContext, CacheFolder } from "./context";
|
|
4
4
|
import { readFile, access, writeFile, mkdir } from "node:fs/promises";
|
|
5
5
|
import { resolve, isAbsolute, join, dirname } from "node:path";
|
|
6
6
|
import { savedFileMigrator } from "@pipelab/shared";
|
|
@@ -67,9 +67,7 @@ export async function runPipelineCommand(file: string, options: RunOptions, vers
|
|
|
67
67
|
await registerAllHandlers({ version, context });
|
|
68
68
|
registerMigrationHandlers(context);
|
|
69
69
|
|
|
70
|
-
const
|
|
71
|
-
const config = await settings.getConfig();
|
|
72
|
-
const cachePath = join(context.userDataPath, "cache");
|
|
70
|
+
const cachePath = context.getCachePath(CacheFolder.Pipelines, effectivePipelineId);
|
|
73
71
|
await mkdir(cachePath, { recursive: true });
|
|
74
72
|
|
|
75
73
|
const abortController = new AbortController();
|
package/src/server.ts
CHANGED
package/src/utils/github.test.ts
CHANGED
|
@@ -29,7 +29,7 @@ describe("GitHub Release Updates API", () => {
|
|
|
29
29
|
expect(releases).toEqual([]);
|
|
30
30
|
expect(fetchSpy).toHaveBeenCalledWith(
|
|
31
31
|
expect.stringContaining("matching-refs/tags/%40pipelab%2Fapp"),
|
|
32
|
-
expect.any(Object)
|
|
32
|
+
expect.any(Object),
|
|
33
33
|
);
|
|
34
34
|
});
|
|
35
35
|
|
|
@@ -153,7 +153,7 @@ describe("GitHub Release Updates API", () => {
|
|
|
153
153
|
expect(releases[0].tag_name).toBe("@pipelab/app@1.2.3");
|
|
154
154
|
expect(fetchSpy).toHaveBeenCalledWith(
|
|
155
155
|
expect.stringContaining("releases/tags/%40pipelab%2Fapp%401.2.3"),
|
|
156
|
-
expect.any(Object)
|
|
156
|
+
expect.any(Object),
|
|
157
157
|
);
|
|
158
158
|
});
|
|
159
159
|
|
|
@@ -189,9 +189,7 @@ describe("GitHub Release Updates API", () => {
|
|
|
189
189
|
// Mock matching refs
|
|
190
190
|
fetchSpy.mockResolvedValueOnce({
|
|
191
191
|
ok: true,
|
|
192
|
-
json: async () => [
|
|
193
|
-
{ ref: "refs/tags/@pipelab/app@3.0.0" },
|
|
194
|
-
],
|
|
192
|
+
json: async () => [{ ref: "refs/tags/@pipelab/app@3.0.0" }],
|
|
195
193
|
} as any);
|
|
196
194
|
|
|
197
195
|
// Mock release lookup
|
package/src/utils/github.ts
CHANGED
|
@@ -38,6 +38,7 @@ export async function fetchPackageReleases(
|
|
|
38
38
|
"User-Agent": "Pipelab-Desktop-Updater",
|
|
39
39
|
Accept: "application/vnd.github.v3+json",
|
|
40
40
|
},
|
|
41
|
+
signal: AbortSignal.timeout(10000),
|
|
41
42
|
},
|
|
42
43
|
);
|
|
43
44
|
if (response.ok) {
|
|
@@ -55,6 +56,7 @@ export async function fetchPackageReleases(
|
|
|
55
56
|
"User-Agent": "Pipelab-Desktop-Updater",
|
|
56
57
|
Accept: "application/vnd.github.v3+json",
|
|
57
58
|
},
|
|
59
|
+
signal: AbortSignal.timeout(10000),
|
|
58
60
|
});
|
|
59
61
|
|
|
60
62
|
if (!response.ok) {
|
|
@@ -104,6 +106,7 @@ export async function fetchPackageReleases(
|
|
|
104
106
|
"User-Agent": "Pipelab-Desktop-Updater",
|
|
105
107
|
Accept: "application/vnd.github.v3+json",
|
|
106
108
|
},
|
|
109
|
+
signal: AbortSignal.timeout(10000),
|
|
107
110
|
},
|
|
108
111
|
);
|
|
109
112
|
|
package/src/utils/remote.test.ts
CHANGED
|
@@ -93,13 +93,16 @@ describe("remote utilities & offline mode", () => {
|
|
|
93
93
|
|
|
94
94
|
test("fetchPipelabPlugin maps latest to releaseTag for official plugins", async () => {
|
|
95
95
|
vi.advanceTimersByTime(30000); // Bypass 10s caching
|
|
96
|
-
const context = new PipelabContext({
|
|
96
|
+
const context = new PipelabContext({
|
|
97
|
+
userDataPath: "/tmp/pipelab-test-remote",
|
|
98
|
+
releaseTag: "beta",
|
|
99
|
+
});
|
|
97
100
|
const pluginName = "@pipelab/plugin-poki";
|
|
98
101
|
const packageBaseDir = context.getPackagesPath(pluginName);
|
|
99
102
|
const cachedVersionDir = path.join(packageBaseDir, "1.0.0-beta.15");
|
|
100
103
|
|
|
101
104
|
vi.spyOn(dns, "lookup").mockResolvedValue({ address: "1.2.3.4", family: 4 } as any);
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
vi.mocked(pacote.packument).mockResolvedValue({
|
|
104
107
|
name: pluginName,
|
|
105
108
|
versions: {
|
|
@@ -128,13 +131,16 @@ describe("remote utilities & offline mode", () => {
|
|
|
128
131
|
|
|
129
132
|
test("fetchPipelabPlugin maps latest to releaseTag for custom plugins and falls back to latest if tag is missing", async () => {
|
|
130
133
|
vi.advanceTimersByTime(40000); // Bypass 10s caching
|
|
131
|
-
const context = new PipelabContext({
|
|
134
|
+
const context = new PipelabContext({
|
|
135
|
+
userDataPath: "/tmp/pipelab-test-remote-custom",
|
|
136
|
+
releaseTag: "beta",
|
|
137
|
+
});
|
|
132
138
|
const pluginName = "custom-cool-plugin";
|
|
133
139
|
const packageBaseDir = context.getPackagesPath(pluginName);
|
|
134
140
|
const cachedVersionDir = path.join(packageBaseDir, "2.0.0");
|
|
135
141
|
|
|
136
142
|
vi.spyOn(dns, "lookup").mockResolvedValue({ address: "1.2.3.4", family: 4 } as any);
|
|
137
|
-
|
|
143
|
+
|
|
138
144
|
vi.mocked(pacote.packument).mockResolvedValue({
|
|
139
145
|
name: pluginName,
|
|
140
146
|
versions: {
|
|
@@ -163,13 +169,16 @@ describe("remote utilities & offline mode", () => {
|
|
|
163
169
|
|
|
164
170
|
test("fetchPipelabPlugin maps latest to releaseTag for custom plugins and falls back to latest if beta is stale", async () => {
|
|
165
171
|
vi.advanceTimersByTime(50000); // Bypass 10s caching
|
|
166
|
-
const context = new PipelabContext({
|
|
172
|
+
const context = new PipelabContext({
|
|
173
|
+
userDataPath: "/tmp/pipelab-test-remote-stale",
|
|
174
|
+
releaseTag: "beta",
|
|
175
|
+
});
|
|
167
176
|
const pluginName = "stale-beta-plugin";
|
|
168
177
|
const packageBaseDir = context.getPackagesPath(pluginName);
|
|
169
178
|
const cachedVersionDir = path.join(packageBaseDir, "2.0.0");
|
|
170
179
|
|
|
171
180
|
vi.spyOn(dns, "lookup").mockResolvedValue({ address: "1.2.3.4", family: 4 } as any);
|
|
172
|
-
|
|
181
|
+
|
|
173
182
|
vi.mocked(pacote.packument).mockResolvedValue({
|
|
174
183
|
name: pluginName,
|
|
175
184
|
versions: {
|
package/src/utils/remote.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { existsSync, constants, statSync, readdirSync } from "node:fs";
|
|
|
14
14
|
import dns from "node:dns/promises";
|
|
15
15
|
import pacote from "pacote";
|
|
16
16
|
import semver from "semver";
|
|
17
|
-
import { isDev, projectRoot, PipelabContext } from "../context";
|
|
17
|
+
import { isDev, projectRoot, PipelabContext, CacheFolder } from "../context";
|
|
18
18
|
import { execa } from "execa";
|
|
19
19
|
import { sendStartupProgress } from "../server";
|
|
20
20
|
import { downloadFile, extractZip, extractTarGz } from "./fs-extras";
|
|
@@ -163,7 +163,7 @@ export async function fetchPackage(
|
|
|
163
163
|
} else {
|
|
164
164
|
try {
|
|
165
165
|
// 1. Resolve version/range using npm with session-wide memoization and disk cache
|
|
166
|
-
const cachePath =
|
|
166
|
+
const cachePath = ctx.getCachePath(CacheFolder.Pacote);
|
|
167
167
|
let packumentPromise = packumentRequests.get(packageName);
|
|
168
168
|
if (!packumentPromise) {
|
|
169
169
|
packumentPromise = pacote.packument(packageName, { cache: cachePath });
|
|
@@ -183,7 +183,10 @@ export async function fetchPackage(
|
|
|
183
183
|
if (range === "latest" && ctx.releaseTag && ctx.releaseTag !== "latest") {
|
|
184
184
|
const releaseTagVersion = packument["dist-tags"]?.[ctx.releaseTag];
|
|
185
185
|
if (releaseTagVersion && semver.valid(releaseTagVersion)) {
|
|
186
|
-
if (
|
|
186
|
+
if (
|
|
187
|
+
!foundVersion ||
|
|
188
|
+
(semver.valid(foundVersion) && semver.gte(releaseTagVersion, foundVersion))
|
|
189
|
+
) {
|
|
187
190
|
console.log(
|
|
188
191
|
`[Fetcher] Using release tag "${ctx.releaseTag}" (${releaseTagVersion}) instead of "latest" (${foundVersion || "none"}) for ${packageName}`,
|
|
189
192
|
);
|
|
@@ -227,7 +230,7 @@ export async function fetchPackage(
|
|
|
227
230
|
}
|
|
228
231
|
}
|
|
229
232
|
|
|
230
|
-
const cachePath =
|
|
233
|
+
const cachePath = ctx.getCachePath(CacheFolder.Pacote);
|
|
231
234
|
const packageDir = join(baseDir, resolvedVersion);
|
|
232
235
|
|
|
233
236
|
const checkStart = Date.now();
|
|
@@ -351,7 +354,7 @@ export async function runPnpm(
|
|
|
351
354
|
...process.env,
|
|
352
355
|
NODE_ENV: "production",
|
|
353
356
|
PATH: nodePath ? `${dirname(nodePath)}${delimiter}${process.env.PATH}` : process.env.PATH,
|
|
354
|
-
PNPM_HOME:
|
|
357
|
+
PNPM_HOME: ctx.getPnpmPath(),
|
|
355
358
|
PNPM_ONLY_ALLOW_TRUSTED_DEPENDENCIES: "false",
|
|
356
359
|
...extraEnv,
|
|
357
360
|
},
|
package/src/utils/storage.ts
CHANGED
|
@@ -12,7 +12,8 @@ export class JsonFileStorage {
|
|
|
12
12
|
private logger = useLogger().logger;
|
|
13
13
|
|
|
14
14
|
constructor(fileName: string, context: PipelabContext) {
|
|
15
|
-
this.filePath =
|
|
15
|
+
this.filePath = context.getConfigPath(fileName);
|
|
16
|
+
|
|
16
17
|
const dir = path.dirname(this.filePath);
|
|
17
18
|
if (!fs.existsSync(dir)) {
|
|
18
19
|
try {
|
package/src/utils.ts
CHANGED
|
@@ -102,6 +102,7 @@ export const executeGraphWithHistory = async ({
|
|
|
102
102
|
projectName,
|
|
103
103
|
projectPath,
|
|
104
104
|
pipelineId,
|
|
105
|
+
cachePath,
|
|
105
106
|
startTime,
|
|
106
107
|
status: "running",
|
|
107
108
|
logs: [],
|
|
@@ -247,18 +248,17 @@ export const executeGraphWithHistory = async ({
|
|
|
247
248
|
|
|
248
249
|
throw error;
|
|
249
250
|
} finally {
|
|
250
|
-
// Apply retention policy regardless of outcome
|
|
251
|
-
if (!shouldDisableHistory) {
|
|
252
|
-
// Don't await, let it run in the background
|
|
253
|
-
buildHistoryStorage.applyRetentionPolicy();
|
|
254
|
-
}
|
|
255
|
-
|
|
256
251
|
if (shouldCleanup) {
|
|
257
252
|
try {
|
|
258
253
|
await rm(sandboxPath, { recursive: true, force: true });
|
|
259
254
|
} catch (e) {
|
|
260
255
|
console.warn(`Failed to cleanup sandbox at ${sandboxPath}:`, e);
|
|
261
256
|
}
|
|
257
|
+
try {
|
|
258
|
+
await rm(cachePath, { recursive: true, force: true });
|
|
259
|
+
} catch (e) {
|
|
260
|
+
console.warn(`Failed to cleanup cache at ${cachePath}:`, e);
|
|
261
|
+
}
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
};
|