@treeseed/sdk 0.12.15 → 0.12.16
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/hosting/graph.js
CHANGED
|
@@ -60,7 +60,7 @@ function resolvePublicTreeDxRoot(input) {
|
|
|
60
60
|
].filter((candidate) => Boolean(candidate));
|
|
61
61
|
return candidates.find((candidate) => existsSync(resolve(candidate, "treeseed.package.yaml")) || existsSync(resolve(candidate, ".git"))) ?? candidates[0];
|
|
62
62
|
}
|
|
63
|
-
function publicTreeDxSourcePolicy(input, config) {
|
|
63
|
+
function publicTreeDxSourcePolicy(input, config, launchEnv) {
|
|
64
64
|
const railway = config.publicTreeDxFederation?.railway ?? {};
|
|
65
65
|
const configuredSource = railway.source && typeof railway.source === "object" && !Array.isArray(railway.source) ? railway.source : {};
|
|
66
66
|
const configuredMode = typeof railway.sourceMode === "string" ? railway.sourceMode : null;
|
|
@@ -68,6 +68,7 @@ function publicTreeDxSourcePolicy(input, config) {
|
|
|
68
68
|
const repository = typeof railway.sourceRepo === "string" ? railway.sourceRepo : typeof configuredSource.repository === "string" ? configuredSource.repository : typeof configuredSource.repo === "string" ? configuredSource.repo : readPackageRepository(treeDxRoot) ?? "treeseed-ai/treedx";
|
|
69
69
|
const sourceMode = configuredMode === "git" || configuredMode === "image" ? configuredMode : input.environment === "staging" ? "git" : "image";
|
|
70
70
|
if (sourceMode !== "git") {
|
|
71
|
+
const imageRef = typeof launchEnv.TREESEED_PUBLIC_TREEDX_IMAGE_REF === "string" && launchEnv.TREESEED_PUBLIC_TREEDX_IMAGE_REF.trim() ? launchEnv.TREESEED_PUBLIC_TREEDX_IMAGE_REF.trim() : null;
|
|
71
72
|
return {
|
|
72
73
|
sourceMode: "image",
|
|
73
74
|
sourceRepo: null,
|
|
@@ -75,6 +76,7 @@ function publicTreeDxSourcePolicy(input, config) {
|
|
|
75
76
|
sourceCommit: null,
|
|
76
77
|
sourceRootDirectory: null,
|
|
77
78
|
image: "treeseed/treedx",
|
|
79
|
+
imageRef,
|
|
78
80
|
imageTagRef: "TREESEED_PUBLIC_TREEDX_IMAGE_REF"
|
|
79
81
|
};
|
|
80
82
|
}
|
|
@@ -110,6 +112,7 @@ function railwayImageRefEnvForService(serviceKey) {
|
|
|
110
112
|
if (serviceKey === "operationsRunner") return "TREESEED_OPERATIONS_RUNNER_IMAGE_REF";
|
|
111
113
|
if (serviceKey === "capacityProviderManager") return "TREESEED_AGENT_MANAGER_IMAGE_REF";
|
|
112
114
|
if (serviceKey === "capacityProviderRunner") return "TREESEED_AGENT_RUNNER_IMAGE_REF";
|
|
115
|
+
if (String(serviceKey).startsWith("public-treedx-node-")) return "TREESEED_PUBLIC_TREEDX_IMAGE_REF";
|
|
113
116
|
return null;
|
|
114
117
|
}
|
|
115
118
|
function defaultRailwayImageRefForService(serviceKey, environment) {
|
|
@@ -295,14 +298,17 @@ function buildProfileFromDeployConfig(input) {
|
|
|
295
298
|
publicTreeDxProjectGroup(environment, config),
|
|
296
299
|
privateTreeDxProjectGroup()
|
|
297
300
|
];
|
|
298
|
-
const railwayImageRefEnvKeys = [
|
|
301
|
+
const railwayImageRefEnvKeys = [.../* @__PURE__ */ new Set([
|
|
302
|
+
...Object.keys(config.services ?? {}).map((serviceKey) => railwayImageRefEnvForService(serviceKey)).filter((value) => Boolean(value)),
|
|
303
|
+
...config.hosting?.kind === "treeseed_control_plane" ? ["TREESEED_PUBLIC_TREEDX_IMAGE_REF"] : []
|
|
304
|
+
])];
|
|
299
305
|
let railwayImageRefEnv = {};
|
|
300
306
|
try {
|
|
301
307
|
railwayImageRefEnv = resolveTreeseedMachineEnvironmentValues(input.configRoot ?? input.tenantRoot, environment, railwayImageRefEnvKeys);
|
|
302
308
|
} catch {
|
|
303
309
|
railwayImageRefEnv = {};
|
|
304
310
|
}
|
|
305
|
-
const launchEnv = mergeRecord(process.env,
|
|
311
|
+
const launchEnv = mergeRecord(railwayImageRefEnv, process.env, input.env);
|
|
306
312
|
if (config.surfaces?.web && config.surfaces.web.enabled !== false) {
|
|
307
313
|
services.push({
|
|
308
314
|
id: "web",
|
|
@@ -419,7 +425,7 @@ function buildProfileFromDeployConfig(input) {
|
|
|
419
425
|
}
|
|
420
426
|
if (config.hosting?.kind === "treeseed_control_plane") {
|
|
421
427
|
const treeDxNodePool = publicTreeDxNodePool(config);
|
|
422
|
-
const treeDxSourcePolicy = publicTreeDxSourcePolicy(input, config);
|
|
428
|
+
const treeDxSourcePolicy = publicTreeDxSourcePolicy(input, config, launchEnv);
|
|
423
429
|
const treeDxNodeUnits = Array.from({ length: treeDxNodePool.bootstrapCount }, (_, offset) => {
|
|
424
430
|
const nodeIndex = offset + 1;
|
|
425
431
|
const serviceName = indexedName("public-treedx-node", nodeIndex);
|
|
@@ -431,6 +437,7 @@ function buildProfileFromDeployConfig(input) {
|
|
|
431
437
|
projectGroupId: "public-treedx-federation",
|
|
432
438
|
config: {
|
|
433
439
|
...treeDxSourcePolicy.image ? { image: treeDxSourcePolicy.image } : {},
|
|
440
|
+
...treeDxSourcePolicy.imageRef ? { imageRef: treeDxSourcePolicy.imageRef } : {},
|
|
434
441
|
...treeDxSourcePolicy.imageTagRef ? { imageTagRef: treeDxSourcePolicy.imageTagRef } : {},
|
|
435
442
|
sourceMode: treeDxSourcePolicy.sourceMode,
|
|
436
443
|
...treeDxSourcePolicy.sourceRepo ? { sourceRepo: treeDxSourcePolicy.sourceRepo } : {},
|
|
@@ -629,7 +629,7 @@ function configuredRailwayServicesForConfig(tenantRoot, scope, deployConfig, app
|
|
|
629
629
|
} catch {
|
|
630
630
|
machineEnv = {};
|
|
631
631
|
}
|
|
632
|
-
const imageRefEnv = { ...process.env, ...
|
|
632
|
+
const imageRefEnv = { ...machineEnv, ...process.env, ...envOverlay };
|
|
633
633
|
let identity;
|
|
634
634
|
try {
|
|
635
635
|
identity = resolveTreeseedResourceIdentity(deployConfig, createPersistentDeployTarget(normalizedScope));
|
|
@@ -1708,7 +1708,7 @@ function prepareFreshReleaseRun(root, branch, rootRepo, packageReports) {
|
|
|
1708
1708
|
]);
|
|
1709
1709
|
const archived = [];
|
|
1710
1710
|
const blockers = [];
|
|
1711
|
-
for (const journal of listInterruptedWorkflowRuns(root).filter((entry) => entry.command === "release")) {
|
|
1711
|
+
for (const journal of listInterruptedWorkflowRuns(root, { recentLimit: 50 }).filter((entry) => entry.command === "release")) {
|
|
1712
1712
|
const classification = classifyWorkflowRunJournal(journal, {
|
|
1713
1713
|
currentBranch: branch,
|
|
1714
1714
|
currentHeads
|
|
@@ -1741,7 +1741,7 @@ function findAutoResumableReleaseRun(root, branch, rootRepo, packageReports, opt
|
|
|
1741
1741
|
[rootRepo.name, rootRepo.commitSha ?? null],
|
|
1742
1742
|
...packageReports.map((report) => [report.name, report.commitSha ?? null])
|
|
1743
1743
|
]);
|
|
1744
|
-
return listInterruptedWorkflowRuns(root).find((journal) => {
|
|
1744
|
+
return listInterruptedWorkflowRuns(root, { recentLimit: 50 }).find((journal) => {
|
|
1745
1745
|
if (journal.command !== "release" || !journal.resumable || journal.session.branchName !== STAGING_BRANCH) {
|
|
1746
1746
|
return false;
|
|
1747
1747
|
}
|
|
@@ -5246,22 +5246,32 @@ ${blockers.join("\n")}`, {
|
|
|
5246
5246
|
async function workflowRelease(helpers, input) {
|
|
5247
5247
|
try {
|
|
5248
5248
|
return await withContextEnv(helpers.context.env, async () => {
|
|
5249
|
+
const traceReleaseStartup = (phase) => {
|
|
5250
|
+
console.error(`[release][startup] ${phase}`);
|
|
5251
|
+
};
|
|
5252
|
+
traceReleaseStartup("resolve workspace");
|
|
5249
5253
|
const root = workspaceRoot(resolveProjectRootOrThrow("release", helpers.cwd()));
|
|
5254
|
+
traceReleaseStartup("resolve session");
|
|
5250
5255
|
const session = resolveTreeseedWorkflowSession(root);
|
|
5251
5256
|
const executionMode = normalizeExecutionMode(input);
|
|
5257
|
+
traceReleaseStartup("inspect root repo");
|
|
5252
5258
|
const rootRepo = createWorkspaceRootRepoReport(root);
|
|
5259
|
+
traceReleaseStartup("inspect package repos");
|
|
5253
5260
|
const packageReports = createWorkspacePackageReports(root);
|
|
5254
5261
|
const explicitResumeRunId = helpers.context.workflow?.resumeRunId ?? null;
|
|
5262
|
+
traceReleaseStartup("check auto resume");
|
|
5255
5263
|
const autoResumeRun = executionMode === "execute" && !explicitResumeRunId && input.fresh !== true ? findAutoResumableReleaseRun(root, session.branchName, rootRepo, packageReports, { archiveStale: false }) : null;
|
|
5256
5264
|
const planAutoResumeRun = executionMode === "plan" && input.fresh !== true ? findAutoResumableReleaseRun(root, session.branchName, rootRepo, packageReports) : null;
|
|
5257
5265
|
const effectiveInput = autoResumeRun ? {
|
|
5258
5266
|
...autoResumeRun.input,
|
|
5259
5267
|
ciMode: input.ciMode ?? autoResumeRun.input.ciMode
|
|
5260
5268
|
} : input;
|
|
5269
|
+
traceReleaseStartup("local cleanup");
|
|
5261
5270
|
const localCleanup = maybeRunLocalWorkflowCleanup(helpers, root, "release", effectiveInput);
|
|
5262
5271
|
const level = effectiveInput.bump ?? "patch";
|
|
5263
5272
|
const ciMode = normalizeCiMode(effectiveInput.ciMode, "release");
|
|
5264
5273
|
const packageSelection = session.packageSelection;
|
|
5274
|
+
traceReleaseStartup("build release plan");
|
|
5265
5275
|
const plannedRelease = buildReleasePlanSnapshot({
|
|
5266
5276
|
root,
|
|
5267
5277
|
mode: session.mode,
|
|
@@ -5274,10 +5284,12 @@ async function workflowRelease(helpers, input) {
|
|
|
5274
5284
|
blockers: []
|
|
5275
5285
|
});
|
|
5276
5286
|
const selectedPackageNames = releasePlanPackageSelection(plannedRelease.packageSelection).selected;
|
|
5287
|
+
traceReleaseStartup("collect blockers");
|
|
5277
5288
|
const blockers = collectReleasePlanBlockers(session, session.mode, selectedPackageNames, {
|
|
5278
5289
|
level,
|
|
5279
5290
|
repairVersionLine: effectiveInput.repairVersionLine === true
|
|
5280
5291
|
});
|
|
5292
|
+
traceReleaseStartup("collect production readiness");
|
|
5281
5293
|
const plannedReadiness = collectTreeseedDeploymentReadiness({
|
|
5282
5294
|
tenantRoot: root,
|
|
5283
5295
|
environment: "prod",
|
|
@@ -5314,13 +5326,16 @@ async function workflowRelease(helpers, input) {
|
|
|
5314
5326
|
releaseBasePayload
|
|
5315
5327
|
);
|
|
5316
5328
|
}
|
|
5329
|
+
traceReleaseStartup("validate blockers");
|
|
5317
5330
|
if (blockers.length > 0) {
|
|
5318
5331
|
workflowError("release", "validation_failed", `Treeseed release cannot continue until blockers are resolved:
|
|
5319
5332
|
${blockers.join("\n")}`, {
|
|
5320
5333
|
details: { blockers, releasePlan: plannedRelease }
|
|
5321
5334
|
});
|
|
5322
5335
|
}
|
|
5336
|
+
traceReleaseStartup("prepare fresh release");
|
|
5323
5337
|
const freshPreparation = input.fresh === true ? prepareFreshReleaseRun(root, session.branchName, rootRepo, packageReports) : { archived: [], blockers: [] };
|
|
5338
|
+
traceReleaseStartup("compute versions");
|
|
5324
5339
|
const selectedVersions = releasePlanVersionMap(plannedRelease.plannedVersions);
|
|
5325
5340
|
const stableVersions = new Map([
|
|
5326
5341
|
...releasePlanStableDependencyVersionMap(plannedRelease).entries(),
|
|
@@ -5331,6 +5346,7 @@ ${blockers.join("\n")}`, {
|
|
|
5331
5346
|
...stableVersions.entries()
|
|
5332
5347
|
]);
|
|
5333
5348
|
const selectedPackageSet = new Set(selectedPackageNames);
|
|
5349
|
+
traceReleaseStartup("acquire workflow run");
|
|
5334
5350
|
const workflowRun = acquireWorkflowRun(
|
|
5335
5351
|
"release",
|
|
5336
5352
|
session,
|
package/dist/workflow/runs.d.ts
CHANGED
|
@@ -131,4 +131,7 @@ export declare function createWorkflowRunJournal(root: string, options: {
|
|
|
131
131
|
steps: Omit<TreeseedWorkflowRunStep, 'status' | 'completedAt' | 'data'>[];
|
|
132
132
|
}): TreeseedWorkflowRunJournal;
|
|
133
133
|
export declare function listWorkflowRunJournals(root: string): TreeseedWorkflowRunJournal[];
|
|
134
|
-
export declare function
|
|
134
|
+
export declare function listRecentWorkflowRunJournals(root: string, limit?: number): TreeseedWorkflowRunJournal[];
|
|
135
|
+
export declare function listInterruptedWorkflowRuns(root: string, options?: {
|
|
136
|
+
recentLimit?: number;
|
|
137
|
+
}): TreeseedWorkflowRunJournal[];
|
package/dist/workflow/runs.js
CHANGED
|
@@ -576,8 +576,42 @@ function listWorkflowRunJournals(root) {
|
|
|
576
576
|
}
|
|
577
577
|
return [...byId.values()].sort((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
578
578
|
}
|
|
579
|
-
function
|
|
580
|
-
|
|
579
|
+
function listRecentWorkflowRunJournalsForScope(root, scope, limit) {
|
|
580
|
+
const runsDir = workflowRunsRoot(root, null, scope);
|
|
581
|
+
if (!existsSync(runsDir)) {
|
|
582
|
+
return [];
|
|
583
|
+
}
|
|
584
|
+
return readdirSync(runsDir).filter((entry) => entry.endsWith(".json")).map((entry) => {
|
|
585
|
+
const path = resolve(runsDir, entry);
|
|
586
|
+
try {
|
|
587
|
+
return { path, mtimeMs: statSync(path).mtimeMs };
|
|
588
|
+
} catch {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
}).filter((entry) => entry != null).sort((left, right) => right.mtimeMs - left.mtimeMs).slice(0, Math.max(1, limit)).map((entry) => {
|
|
592
|
+
try {
|
|
593
|
+
if (statSync(entry.path).size > 5 * 1024 * 1024) {
|
|
594
|
+
const archivedSummary = archivedWorkflowRunSummary(entry.path);
|
|
595
|
+
if (archivedSummary) return archivedSummary;
|
|
596
|
+
}
|
|
597
|
+
} catch {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
return safeJsonParse(entry.path);
|
|
601
|
+
}).filter((entry) => entry != null);
|
|
602
|
+
}
|
|
603
|
+
function listRecentWorkflowRunJournals(root, limit = 50) {
|
|
604
|
+
const local = listRecentWorkflowRunJournalsForScope(root, "worktree", limit);
|
|
605
|
+
const shared = listRecentWorkflowRunJournalsForScope(root, "shared", limit);
|
|
606
|
+
const byId = /* @__PURE__ */ new Map();
|
|
607
|
+
for (const journal of [...local, ...shared]) {
|
|
608
|
+
byId.set(journal.runId, journal);
|
|
609
|
+
}
|
|
610
|
+
return [...byId.values()].sort((left, right) => right.createdAt.localeCompare(left.createdAt)).slice(0, Math.max(1, limit));
|
|
611
|
+
}
|
|
612
|
+
function listInterruptedWorkflowRuns(root, options = {}) {
|
|
613
|
+
const journals = options.recentLimit ? listRecentWorkflowRunJournals(root, options.recentLimit) : listWorkflowRunJournals(root);
|
|
614
|
+
return journals.filter((journal) => journal.status === "failed" && journal.resumable);
|
|
581
615
|
}
|
|
582
616
|
export {
|
|
583
617
|
acquireWorkflowLock,
|
|
@@ -591,6 +625,7 @@ export {
|
|
|
591
625
|
inspectWorkflowLock,
|
|
592
626
|
isSharedWorkflowCommand,
|
|
593
627
|
listInterruptedWorkflowRuns,
|
|
628
|
+
listRecentWorkflowRunJournals,
|
|
594
629
|
listWorkflowRunJournals,
|
|
595
630
|
readWorkflowRunJournal,
|
|
596
631
|
refreshWorkflowLock,
|