@treeseed/sdk 0.6.40 → 0.6.41
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.
|
@@ -245,8 +245,8 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
|
|
|
245
245
|
healthcheckTimeoutSeconds: number | null;
|
|
246
246
|
runtimeMode: string | null;
|
|
247
247
|
volume: {
|
|
248
|
-
id:
|
|
249
|
-
name:
|
|
248
|
+
id: any;
|
|
249
|
+
name: any;
|
|
250
250
|
mountPath: any;
|
|
251
251
|
created: boolean;
|
|
252
252
|
updated: boolean;
|
|
@@ -745,8 +745,8 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
|
|
|
745
745
|
healthcheckTimeoutSeconds: number | null;
|
|
746
746
|
runtimeMode: string | null;
|
|
747
747
|
volume: {
|
|
748
|
-
id:
|
|
749
|
-
name:
|
|
748
|
+
id: any;
|
|
749
|
+
name: any;
|
|
750
750
|
mountPath: any;
|
|
751
751
|
created: boolean;
|
|
752
752
|
updated: boolean;
|
|
@@ -312,8 +312,8 @@ export declare function deployRailwayService(tenantRoot: any, service: any, { dr
|
|
|
312
312
|
healthcheckTimeoutSeconds: number | null;
|
|
313
313
|
runtimeMode: string | null;
|
|
314
314
|
volume: {
|
|
315
|
-
id:
|
|
316
|
-
name:
|
|
315
|
+
id: any;
|
|
316
|
+
name: any;
|
|
317
317
|
mountPath: any;
|
|
318
318
|
created: boolean;
|
|
319
319
|
updated: boolean;
|
|
@@ -73,6 +73,61 @@ function configuredEnvValue(env, name) {
|
|
|
73
73
|
const value = env?.[name];
|
|
74
74
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
75
75
|
}
|
|
76
|
+
function parseRailwayJsonOutput(output) {
|
|
77
|
+
const trimmed = typeof output === "string" ? output.trim() : "";
|
|
78
|
+
if (!trimmed) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return JSON.parse(trimmed);
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
const lines = trimmed.split(/\r?\n/u);
|
|
86
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
87
|
+
const candidate = lines.slice(index).join("\n").trim();
|
|
88
|
+
if (!candidate.startsWith("{") && !candidate.startsWith("[")) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
return JSON.parse(candidate);
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
function normalizeRailwayCliVolume(value, { serviceId, environmentId, fallbackName, fallbackMountPath }) {
|
|
99
|
+
if (!value || typeof value !== "object") {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const record = value;
|
|
103
|
+
const id = typeof record.id === "string" && record.id.trim() ? record.id.trim() : "";
|
|
104
|
+
if (!id) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
const name = typeof record.name === "string" && record.name.trim() ? record.name.trim() : fallbackName;
|
|
108
|
+
const mountPath = typeof record.mountPath === "string" && record.mountPath.trim() ? record.mountPath.trim() : fallbackMountPath;
|
|
109
|
+
const sizeMb = typeof record.sizeMB === "number" ? record.sizeMB : null;
|
|
110
|
+
const currentSizeMb = typeof record.currentSizeMB === "number" ? record.currentSizeMB : null;
|
|
111
|
+
return {
|
|
112
|
+
id,
|
|
113
|
+
name,
|
|
114
|
+
projectId: null,
|
|
115
|
+
instances: [{
|
|
116
|
+
id,
|
|
117
|
+
serviceId,
|
|
118
|
+
environmentId,
|
|
119
|
+
mountPath,
|
|
120
|
+
sizeGb: sizeMb === null ? null : sizeMb / 1e3,
|
|
121
|
+
usedGb: currentSizeMb === null ? null : currentSizeMb / 1e3
|
|
122
|
+
}]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function normalizeRailwayCliVolumeList(value, options) {
|
|
126
|
+
if (!value || typeof value !== "object" || !Array.isArray(value.volumes)) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
return value.volumes.map((entry) => normalizeRailwayCliVolume(entry, options)).filter(Boolean);
|
|
130
|
+
}
|
|
76
131
|
function isUsableRailwayToken(value) {
|
|
77
132
|
return typeof value === "string" && value.trim().length >= 8;
|
|
78
133
|
}
|
|
@@ -959,10 +1014,13 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
959
1014
|
env
|
|
960
1015
|
}) : null;
|
|
961
1016
|
const volumeMountPath = service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
|
|
962
|
-
const volumeConfiguration = wantsRunnerVolume ? await
|
|
1017
|
+
const volumeConfiguration = wantsRunnerVolume ? await ensureRailwayServiceVolumeWithCliFallback({
|
|
1018
|
+
tenantRoot,
|
|
963
1019
|
projectId: project.id,
|
|
964
1020
|
environmentId: environment.id,
|
|
1021
|
+
environmentName: environment.name,
|
|
965
1022
|
serviceId: railwayService.id,
|
|
1023
|
+
serviceName: railwayService.name,
|
|
966
1024
|
name: deriveRailwayWorkerRunnerVolumeName(railwayService.name),
|
|
967
1025
|
mountPath: volumeMountPath,
|
|
968
1026
|
env
|
|
@@ -994,6 +1052,84 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
994
1052
|
} : null
|
|
995
1053
|
};
|
|
996
1054
|
}
|
|
1055
|
+
async function ensureRailwayServiceVolumeWithCliFallback({
|
|
1056
|
+
tenantRoot,
|
|
1057
|
+
projectId,
|
|
1058
|
+
environmentId,
|
|
1059
|
+
environmentName,
|
|
1060
|
+
serviceId,
|
|
1061
|
+
serviceName,
|
|
1062
|
+
name,
|
|
1063
|
+
mountPath,
|
|
1064
|
+
env = process.env
|
|
1065
|
+
}) {
|
|
1066
|
+
try {
|
|
1067
|
+
return await ensureRailwayServiceVolume({
|
|
1068
|
+
projectId,
|
|
1069
|
+
environmentId,
|
|
1070
|
+
serviceId,
|
|
1071
|
+
name,
|
|
1072
|
+
mountPath,
|
|
1073
|
+
env
|
|
1074
|
+
});
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1077
|
+
if (!message.includes("Problem processing request")) {
|
|
1078
|
+
throw error;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
const cliOptions = {
|
|
1082
|
+
cwd: tenantRoot,
|
|
1083
|
+
capture: true,
|
|
1084
|
+
env
|
|
1085
|
+
};
|
|
1086
|
+
const volumeArgs = ["volume", "--service", serviceId, "--environment", environmentId];
|
|
1087
|
+
const listResult = runRailway([...volumeArgs, "list", "--json"], cliOptions);
|
|
1088
|
+
const existingVolumes = normalizeRailwayCliVolumeList(parseRailwayJsonOutput(listResult.stdout ?? ""), {
|
|
1089
|
+
serviceId,
|
|
1090
|
+
environmentId,
|
|
1091
|
+
fallbackName: name,
|
|
1092
|
+
fallbackMountPath: mountPath
|
|
1093
|
+
});
|
|
1094
|
+
let volume = existingVolumes.find((entry) => entry.name === name) ?? existingVolumes.find((entry) => entry.instances.some((instance2) => instance2.mountPath === mountPath)) ?? existingVolumes[0] ?? null;
|
|
1095
|
+
let created = false;
|
|
1096
|
+
let updated = false;
|
|
1097
|
+
if (!volume) {
|
|
1098
|
+
const createResult = runRailway([...volumeArgs, "add", "--mount-path", mountPath, "--json"], cliOptions);
|
|
1099
|
+
volume = normalizeRailwayCliVolume(parseRailwayJsonOutput(createResult.stdout ?? ""), {
|
|
1100
|
+
serviceId,
|
|
1101
|
+
environmentId,
|
|
1102
|
+
fallbackName: name,
|
|
1103
|
+
fallbackMountPath: mountPath
|
|
1104
|
+
});
|
|
1105
|
+
if (!volume) {
|
|
1106
|
+
throw new Error(`Railway CLI volume add did not return a usable volume for ${serviceName} in ${environmentName}.`);
|
|
1107
|
+
}
|
|
1108
|
+
created = true;
|
|
1109
|
+
}
|
|
1110
|
+
const instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null;
|
|
1111
|
+
if (volume.name !== name || instance?.mountPath !== mountPath) {
|
|
1112
|
+
const updateResult = runRailway([...volumeArgs, "update", "--volume", volume.id, "--name", name, "--mount-path", mountPath, "--json"], cliOptions);
|
|
1113
|
+
const updatedVolume = normalizeRailwayCliVolume(parseRailwayJsonOutput(updateResult.stdout ?? ""), {
|
|
1114
|
+
serviceId,
|
|
1115
|
+
environmentId,
|
|
1116
|
+
fallbackName: name,
|
|
1117
|
+
fallbackMountPath: mountPath
|
|
1118
|
+
});
|
|
1119
|
+
volume = updatedVolume ?? {
|
|
1120
|
+
...volume,
|
|
1121
|
+
name,
|
|
1122
|
+
instances: volume.instances.map((entry) => ({ ...entry, mountPath }))
|
|
1123
|
+
};
|
|
1124
|
+
updated = true;
|
|
1125
|
+
}
|
|
1126
|
+
return {
|
|
1127
|
+
volume,
|
|
1128
|
+
instance: volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null,
|
|
1129
|
+
created,
|
|
1130
|
+
updated
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
997
1133
|
async function deployRailwayService(tenantRoot, service, {
|
|
998
1134
|
dryRun = false,
|
|
999
1135
|
write,
|