@treeseed/sdk 0.10.6 → 0.10.8
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/api/auth/d1-provider.d.ts +5 -0
- package/dist/api/auth/d1-provider.js +3 -0
- package/dist/api/auth/d1-store.d.ts +5 -0
- package/dist/api/auth/d1-store.js +62 -0
- package/dist/api/auth/memory-provider.d.ts +5 -0
- package/dist/api/auth/memory-provider.js +41 -0
- package/dist/api/types.d.ts +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +58 -0
- package/dist/market-client.d.ts +119 -0
- package/dist/market-client.js +79 -0
- package/dist/operations/repository-operations.d.ts +129 -0
- package/dist/operations/repository-operations.js +634 -0
- package/dist/operations/services/config-runtime.d.ts +7 -6
- package/dist/operations/services/config-runtime.js +45 -25
- package/dist/operations/services/deploy.d.ts +42 -0
- package/dist/operations/services/deploy.js +1 -1
- package/dist/operations/services/project-platform.d.ts +41 -1
- package/dist/operations/services/project-platform.js +14 -1
- package/dist/operations/services/railway-api.d.ts +35 -1
- package/dist/operations/services/railway-api.js +240 -35
- package/dist/operations/services/railway-deploy.d.ts +16 -234
- package/dist/operations/services/railway-deploy.js +177 -62
- package/dist/operations/services/release-candidate.js +1 -2
- package/dist/operations/services/runtime-tools.d.ts +14 -0
- package/dist/operations/services/runtime-tools.js +15 -1
- package/dist/operations/services/workspace-save.d.ts +24 -0
- package/dist/operations/services/workspace-save.js +143 -3
- package/dist/operations/services/workspace-tools.js +1 -1
- package/dist/platform/env.yaml +163 -2
- package/dist/platform/environment.d.ts +1 -0
- package/dist/platform/environment.js +9 -0
- package/dist/platform-operation-store.d.ts +90 -0
- package/dist/platform-operation-store.js +505 -0
- package/dist/platform-operations.d.ts +265 -0
- package/dist/platform-operations.js +421 -0
- package/dist/reconcile/bootstrap-systems.js +3 -3
- package/dist/reconcile/builtin-adapters.js +225 -29
- package/dist/reconcile/contracts.d.ts +1 -1
- package/dist/reconcile/desired-state.d.ts +14 -0
- package/dist/reconcile/desired-state.js +4 -0
- package/dist/reconcile/engine.d.ts +28 -0
- package/dist/reconcile/state.js +3 -0
- package/dist/reconcile/units.js +2 -0
- package/dist/workflow/operations.d.ts +13 -5
- package/dist/workflow/operations.js +69 -12
- package/dist/workflow-state.d.ts +2 -0
- package/dist/workflow-state.js +7 -2
- package/dist/workflow.d.ts +2 -0
- package/package.json +15 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type TreeseedBootstrapTaskPrefix, type TreeseedBootstrapWriter } from './bootstrap-runner.ts';
|
|
2
2
|
export declare function deriveRailwayWorkerRunnerServiceName(projectSlug: any, index?: number): string;
|
|
3
|
+
export declare function deriveRailwayMarketOperationsRunnerServiceName(baseServiceName: any, index?: number): string;
|
|
3
4
|
export declare function deriveRailwayWorkerRunnerVolumeName(serviceName: any, environmentName?: string): string;
|
|
5
|
+
export declare function deriveRailwayMarketOperationsRunnerVolumeName(serviceName: any, environmentName?: string): string;
|
|
4
6
|
export declare function railwayServiceRuntimeStartCommand(service: any): any;
|
|
5
7
|
export declare function collectRailwayDeploymentStatusChecks(statusPayload: any, scope: any, services: any): any;
|
|
6
8
|
export declare function isUsableRailwayToken(value: any): boolean;
|
|
@@ -17,30 +19,7 @@ export declare function runRailway(args: any, { cwd, capture, allowFailure, inpu
|
|
|
17
19
|
allowFailure?: boolean | undefined;
|
|
18
20
|
}): import("child_process").SpawnSyncReturns<string>;
|
|
19
21
|
export declare function waitForRailwayManagedDeploymentsSettled(tenantRoot: any, scope: any, { services, env, timeoutMs, pollMs, onProgress, }?: {
|
|
20
|
-
services?:
|
|
21
|
-
key: string;
|
|
22
|
-
scope: string;
|
|
23
|
-
projectId: string | null;
|
|
24
|
-
projectName: string;
|
|
25
|
-
serviceId: string | null;
|
|
26
|
-
serviceName: string;
|
|
27
|
-
rootDir: string;
|
|
28
|
-
publicBaseUrl: string | null;
|
|
29
|
-
railwayEnvironment: string;
|
|
30
|
-
buildCommand: string | null;
|
|
31
|
-
startCommand: string | null;
|
|
32
|
-
healthcheckPath: any;
|
|
33
|
-
healthcheckTimeoutSeconds: any;
|
|
34
|
-
healthcheckIntervalSeconds: any;
|
|
35
|
-
restartPolicy: any;
|
|
36
|
-
runtimeMode: any;
|
|
37
|
-
schedule: string[];
|
|
38
|
-
hostingKind: string;
|
|
39
|
-
runnerPool: {
|
|
40
|
-
bootstrapIndex: number;
|
|
41
|
-
volumeMountPath: string;
|
|
42
|
-
} | null;
|
|
43
|
-
} | null)[] | undefined;
|
|
22
|
+
services?: unknown[] | undefined;
|
|
44
23
|
env?: NodeJS.ProcessEnv | undefined;
|
|
45
24
|
timeoutMs?: number | undefined;
|
|
46
25
|
pollMs?: number | undefined;
|
|
@@ -75,135 +54,34 @@ export declare function ensureRailwayEnvironmentExists(service: any, { env }?: {
|
|
|
75
54
|
export declare function ensureRailwayServiceExists(service: any, { env }?: {
|
|
76
55
|
env?: NodeJS.ProcessEnv | undefined;
|
|
77
56
|
}): import("child_process").SpawnSyncReturns<string>;
|
|
57
|
+
export declare function ensureRailwayDatabaseServiceExists(service: any, { database, env, }?: {
|
|
58
|
+
database?: string | undefined;
|
|
59
|
+
env?: NodeJS.ProcessEnv | undefined;
|
|
60
|
+
}): import("child_process").SpawnSyncReturns<string>;
|
|
78
61
|
export declare function ensureRailwayProjectContext(service: any, { env, allowFailure, capture }?: {
|
|
79
62
|
env?: NodeJS.ProcessEnv | undefined;
|
|
80
63
|
allowFailure?: boolean | undefined;
|
|
81
64
|
capture?: boolean | undefined;
|
|
82
65
|
}): import("child_process").SpawnSyncReturns<string> | null;
|
|
83
|
-
export declare function configuredRailwayServices(tenantRoot: any, scope: any):
|
|
84
|
-
key: string;
|
|
85
|
-
scope: string;
|
|
86
|
-
projectId: string | null;
|
|
87
|
-
projectName: string;
|
|
88
|
-
serviceId: string | null;
|
|
89
|
-
serviceName: string;
|
|
90
|
-
rootDir: string;
|
|
91
|
-
publicBaseUrl: string | null;
|
|
92
|
-
railwayEnvironment: string;
|
|
93
|
-
buildCommand: string | null;
|
|
94
|
-
startCommand: string | null;
|
|
95
|
-
healthcheckPath: any;
|
|
96
|
-
healthcheckTimeoutSeconds: any;
|
|
97
|
-
healthcheckIntervalSeconds: any;
|
|
98
|
-
restartPolicy: any;
|
|
99
|
-
runtimeMode: any;
|
|
100
|
-
schedule: string[];
|
|
101
|
-
hostingKind: string;
|
|
102
|
-
runnerPool: {
|
|
103
|
-
bootstrapIndex: number;
|
|
104
|
-
volumeMountPath: string;
|
|
105
|
-
} | null;
|
|
106
|
-
} | null)[];
|
|
66
|
+
export declare function configuredRailwayServices(tenantRoot: any, scope: any): unknown[];
|
|
107
67
|
export declare function configuredRailwayScheduledJobs(tenantRoot: any, scope: any, { phase }?: {
|
|
108
68
|
phase?: string | undefined;
|
|
109
|
-
}):
|
|
110
|
-
service: string;
|
|
111
|
-
projectId: string | null;
|
|
112
|
-
projectName: string;
|
|
113
|
-
serviceId: string | null;
|
|
114
|
-
serviceName: string;
|
|
115
|
-
environment: string;
|
|
116
|
-
environmentId: string | null;
|
|
117
|
-
expression: string;
|
|
118
|
-
command: string | null;
|
|
119
|
-
enabled: boolean;
|
|
120
|
-
logicalName: string;
|
|
121
|
-
}[];
|
|
69
|
+
}): any[];
|
|
122
70
|
export declare function resolveRailwayDeploymentProfile(tenantRoot: any): {
|
|
123
71
|
hostingKind: string;
|
|
124
72
|
managedTopology: string[];
|
|
125
73
|
};
|
|
126
74
|
export declare function validateRailwayServiceConfiguration(tenantRoot: any, scope: any): {
|
|
127
|
-
services:
|
|
128
|
-
|
|
129
|
-
scope: string;
|
|
130
|
-
projectId: string | null;
|
|
131
|
-
projectName: string;
|
|
132
|
-
serviceId: string | null;
|
|
133
|
-
serviceName: string;
|
|
134
|
-
rootDir: string;
|
|
135
|
-
publicBaseUrl: string | null;
|
|
136
|
-
railwayEnvironment: string;
|
|
137
|
-
buildCommand: string | null;
|
|
138
|
-
startCommand: string | null;
|
|
139
|
-
healthcheckPath: any;
|
|
140
|
-
healthcheckTimeoutSeconds: any;
|
|
141
|
-
healthcheckIntervalSeconds: any;
|
|
142
|
-
restartPolicy: any;
|
|
143
|
-
runtimeMode: any;
|
|
144
|
-
schedule: string[];
|
|
145
|
-
hostingKind: string;
|
|
146
|
-
runnerPool: {
|
|
147
|
-
bootstrapIndex: number;
|
|
148
|
-
volumeMountPath: string;
|
|
149
|
-
} | null;
|
|
150
|
-
} | null)[];
|
|
151
|
-
schedules: {
|
|
152
|
-
service: string;
|
|
153
|
-
projectId: string | null;
|
|
154
|
-
projectName: string;
|
|
155
|
-
serviceId: string | null;
|
|
156
|
-
serviceName: string;
|
|
157
|
-
environment: string;
|
|
158
|
-
environmentId: string | null;
|
|
159
|
-
expression: string;
|
|
160
|
-
command: string | null;
|
|
161
|
-
enabled: boolean;
|
|
162
|
-
logicalName: string;
|
|
163
|
-
}[];
|
|
75
|
+
services: unknown[];
|
|
76
|
+
schedules: any[];
|
|
164
77
|
hostingKind: string;
|
|
165
78
|
managedTopology: string[];
|
|
166
79
|
};
|
|
167
80
|
export declare function validateRailwayDeployPrerequisites(tenantRoot: any, scope: any, { env }?: {
|
|
168
81
|
env?: NodeJS.ProcessEnv | undefined;
|
|
169
82
|
}): {
|
|
170
|
-
services:
|
|
171
|
-
|
|
172
|
-
scope: string;
|
|
173
|
-
projectId: string | null;
|
|
174
|
-
projectName: string;
|
|
175
|
-
serviceId: string | null;
|
|
176
|
-
serviceName: string;
|
|
177
|
-
rootDir: string;
|
|
178
|
-
publicBaseUrl: string | null;
|
|
179
|
-
railwayEnvironment: string;
|
|
180
|
-
buildCommand: string | null;
|
|
181
|
-
startCommand: string | null;
|
|
182
|
-
healthcheckPath: any;
|
|
183
|
-
healthcheckTimeoutSeconds: any;
|
|
184
|
-
healthcheckIntervalSeconds: any;
|
|
185
|
-
restartPolicy: any;
|
|
186
|
-
runtimeMode: any;
|
|
187
|
-
schedule: string[];
|
|
188
|
-
hostingKind: string;
|
|
189
|
-
runnerPool: {
|
|
190
|
-
bootstrapIndex: number;
|
|
191
|
-
volumeMountPath: string;
|
|
192
|
-
} | null;
|
|
193
|
-
} | null)[];
|
|
194
|
-
schedules: {
|
|
195
|
-
service: string;
|
|
196
|
-
projectId: string | null;
|
|
197
|
-
projectName: string;
|
|
198
|
-
serviceId: string | null;
|
|
199
|
-
serviceName: string;
|
|
200
|
-
environment: string;
|
|
201
|
-
environmentId: string | null;
|
|
202
|
-
expression: string;
|
|
203
|
-
command: string | null;
|
|
204
|
-
enabled: boolean;
|
|
205
|
-
logicalName: string;
|
|
206
|
-
}[];
|
|
83
|
+
services: unknown[];
|
|
84
|
+
schedules: any[];
|
|
207
85
|
hostingKind: string;
|
|
208
86
|
managedTopology: string[];
|
|
209
87
|
};
|
|
@@ -211,50 +89,7 @@ export declare function ensureRailwayScheduledJobs(tenantRoot: any, scope: any,
|
|
|
211
89
|
dryRun?: boolean | undefined;
|
|
212
90
|
fetchImpl?: typeof fetch | undefined;
|
|
213
91
|
env?: NodeJS.ProcessEnv | undefined;
|
|
214
|
-
}): Promise<
|
|
215
|
-
id: null;
|
|
216
|
-
status: string;
|
|
217
|
-
enabled: boolean;
|
|
218
|
-
command: string | null;
|
|
219
|
-
message: string;
|
|
220
|
-
service: string;
|
|
221
|
-
projectId: string | null;
|
|
222
|
-
projectName: string;
|
|
223
|
-
serviceId: string | null;
|
|
224
|
-
serviceName: string;
|
|
225
|
-
environment: string;
|
|
226
|
-
environmentId: string | null;
|
|
227
|
-
expression: string;
|
|
228
|
-
logicalName: string;
|
|
229
|
-
}[] | ({
|
|
230
|
-
id: null;
|
|
231
|
-
projectId: string | null;
|
|
232
|
-
serviceId: string | null;
|
|
233
|
-
environmentId: string | null;
|
|
234
|
-
status: string;
|
|
235
|
-
enabled: boolean;
|
|
236
|
-
command: string | null;
|
|
237
|
-
service: string;
|
|
238
|
-
projectName: string;
|
|
239
|
-
serviceName: string;
|
|
240
|
-
environment: string;
|
|
241
|
-
expression: string;
|
|
242
|
-
logicalName: string;
|
|
243
|
-
} | {
|
|
244
|
-
projectId: string;
|
|
245
|
-
id: string | null;
|
|
246
|
-
status: string;
|
|
247
|
-
enabled: boolean;
|
|
248
|
-
command: string | null;
|
|
249
|
-
serviceId: string;
|
|
250
|
-
environmentId: string;
|
|
251
|
-
service: string;
|
|
252
|
-
projectName: string;
|
|
253
|
-
serviceName: string;
|
|
254
|
-
environment: string;
|
|
255
|
-
expression: string;
|
|
256
|
-
logicalName: string;
|
|
257
|
-
})[]>;
|
|
92
|
+
}): Promise<any[]>;
|
|
258
93
|
export declare function verifyRailwayScheduledJobs(tenantRoot: any, scope: any, { fetchImpl, apiToken, apiUrl, env }?: {
|
|
259
94
|
fetchImpl?: typeof fetch | undefined;
|
|
260
95
|
env?: NodeJS.ProcessEnv | undefined;
|
|
@@ -262,63 +97,10 @@ export declare function verifyRailwayScheduledJobs(tenantRoot: any, scope: any,
|
|
|
262
97
|
ok: boolean;
|
|
263
98
|
unsupported: boolean;
|
|
264
99
|
message: string;
|
|
265
|
-
checks:
|
|
266
|
-
id: null;
|
|
267
|
-
ok: boolean;
|
|
268
|
-
status: string;
|
|
269
|
-
message: string;
|
|
270
|
-
service: string;
|
|
271
|
-
projectId: string | null;
|
|
272
|
-
projectName: string;
|
|
273
|
-
serviceId: string | null;
|
|
274
|
-
serviceName: string;
|
|
275
|
-
environment: string;
|
|
276
|
-
environmentId: string | null;
|
|
277
|
-
expression: string;
|
|
278
|
-
command: string | null;
|
|
279
|
-
enabled: boolean;
|
|
280
|
-
logicalName: string;
|
|
281
|
-
}[];
|
|
100
|
+
checks: any[];
|
|
282
101
|
} | {
|
|
283
102
|
ok: boolean;
|
|
284
|
-
checks:
|
|
285
|
-
id: null;
|
|
286
|
-
ok: boolean;
|
|
287
|
-
status: string;
|
|
288
|
-
message: string;
|
|
289
|
-
service: string;
|
|
290
|
-
projectId: string | null;
|
|
291
|
-
projectName: string;
|
|
292
|
-
serviceId: string | null;
|
|
293
|
-
serviceName: string;
|
|
294
|
-
environment: string;
|
|
295
|
-
environmentId: string | null;
|
|
296
|
-
expression: string;
|
|
297
|
-
command: string | null;
|
|
298
|
-
enabled: boolean;
|
|
299
|
-
logicalName: string;
|
|
300
|
-
} | {
|
|
301
|
-
id: string | null;
|
|
302
|
-
projectId: string;
|
|
303
|
-
serviceId: string;
|
|
304
|
-
environmentId: string;
|
|
305
|
-
ok: boolean;
|
|
306
|
-
status: string;
|
|
307
|
-
observed: {
|
|
308
|
-
expression: string | null;
|
|
309
|
-
command: string | null;
|
|
310
|
-
enabled: boolean;
|
|
311
|
-
} | null;
|
|
312
|
-
message: string | undefined;
|
|
313
|
-
service: string;
|
|
314
|
-
projectName: string;
|
|
315
|
-
serviceName: string;
|
|
316
|
-
environment: string;
|
|
317
|
-
expression: string;
|
|
318
|
-
command: string | null;
|
|
319
|
-
enabled: boolean;
|
|
320
|
-
logicalName: string;
|
|
321
|
-
})[];
|
|
103
|
+
checks: any[];
|
|
322
104
|
unsupported?: undefined;
|
|
323
105
|
message?: undefined;
|
|
324
106
|
}>;
|
|
@@ -30,26 +30,38 @@ function normalizeScope(scope) {
|
|
|
30
30
|
function resolveRailwayEnvironmentForScope(scope, configuredEnvironment) {
|
|
31
31
|
return normalizeRailwayEnvironmentName(configuredEnvironment || normalizeScope(scope));
|
|
32
32
|
}
|
|
33
|
-
const RAILWAY_SERVICE_KEYS = ["api", "
|
|
34
|
-
const HOSTED_PROJECT_SERVICE_KEYS = ["api"
|
|
33
|
+
const RAILWAY_SERVICE_KEYS = ["api", "marketOperationsRunner"];
|
|
34
|
+
const HOSTED_PROJECT_SERVICE_KEYS = ["api"];
|
|
35
35
|
const WORKER_RUNNER_BOOTSTRAP_INDEX = 1;
|
|
36
36
|
const WORKER_RUNNER_VOLUME_MOUNT_PATH = "/data";
|
|
37
|
+
const MARKET_OPERATIONS_RUNNER_BOOTSTRAP_COUNT = 2;
|
|
37
38
|
function shouldManageRailwaySchedules(scope, phase = "deploy") {
|
|
38
39
|
const environment = normalizeRailwayEnvironmentName(scope);
|
|
39
40
|
return phase === "deploy" && (environment === "staging" || environment === "production");
|
|
40
41
|
}
|
|
41
42
|
function railwayServiceNameSuffix(serviceKey) {
|
|
42
|
-
return serviceKey === "workdayManager" ? "workday-manager" : serviceKey === "workerRunner" ? "worker-runner" : serviceKey;
|
|
43
|
+
return serviceKey === "workdayManager" ? "workday-manager" : serviceKey === "workerRunner" ? "worker-runner" : serviceKey === "marketOperationsRunner" ? "market-operations-runner" : serviceKey;
|
|
43
44
|
}
|
|
44
45
|
function deriveRailwayWorkerRunnerServiceName(projectSlug, index = WORKER_RUNNER_BOOTSTRAP_INDEX) {
|
|
45
46
|
const normalizedIndex = Math.max(1, Number.parseInt(String(index), 10) || WORKER_RUNNER_BOOTSTRAP_INDEX);
|
|
46
47
|
return `${projectSlug}-worker-runner-${String(normalizedIndex).padStart(2, "0")}`;
|
|
47
48
|
}
|
|
49
|
+
function deriveRailwayMarketOperationsRunnerServiceName(baseServiceName, index = WORKER_RUNNER_BOOTSTRAP_INDEX) {
|
|
50
|
+
const normalizedIndex = Math.max(1, Number.parseInt(String(index), 10) || WORKER_RUNNER_BOOTSTRAP_INDEX);
|
|
51
|
+
const base = String(baseServiceName ?? "").trim().replace(/-\d+$/u, "") || "treeseed-market-operations-runner";
|
|
52
|
+
return `${base}-${String(normalizedIndex).padStart(2, "0")}`;
|
|
53
|
+
}
|
|
48
54
|
function deriveRailwayWorkerRunnerVolumeName(serviceName, environmentName = "") {
|
|
49
55
|
const environment = normalizeRailwayEnvironmentName(environmentName);
|
|
50
|
-
const environmentSuffix = environment
|
|
56
|
+
const environmentSuffix = environment === "production" ? "-prod" : environment ? `-${environment}` : "";
|
|
51
57
|
return `${serviceName}${environmentSuffix}-data`;
|
|
52
58
|
}
|
|
59
|
+
function deriveRailwayMarketOperationsRunnerVolumeName(serviceName, environmentName = "") {
|
|
60
|
+
const environment = normalizeRailwayEnvironmentName(environmentName);
|
|
61
|
+
const environmentSuffix = environment === "production" ? "-prod" : environment ? `-${environment}` : "";
|
|
62
|
+
const index = String(serviceName ?? "").match(/-(\d+)$/u)?.[1] ?? "01";
|
|
63
|
+
return `market-ops-runner-${index}${environmentSuffix}-data`;
|
|
64
|
+
}
|
|
53
65
|
function railwayServiceRuntimeStartCommand(service) {
|
|
54
66
|
return service.startCommand;
|
|
55
67
|
}
|
|
@@ -201,6 +213,7 @@ function normalizeRailwayCliVolume(value, { serviceId, environmentId, fallbackNa
|
|
|
201
213
|
serviceId,
|
|
202
214
|
environmentId,
|
|
203
215
|
mountPath,
|
|
216
|
+
state: "READY",
|
|
204
217
|
sizeGb: sizeMb === null ? null : sizeMb / 1e3,
|
|
205
218
|
usedGb: currentSizeMb === null ? null : currentSizeMb / 1e3
|
|
206
219
|
}]
|
|
@@ -668,6 +681,66 @@ function ensureRailwayServiceExists(service, { env = process.env } = {}) {
|
|
|
668
681
|
}
|
|
669
682
|
return refreshed;
|
|
670
683
|
}
|
|
684
|
+
function ensureRailwayDatabaseServiceExists(service, {
|
|
685
|
+
database = "postgres",
|
|
686
|
+
env = process.env
|
|
687
|
+
} = {}) {
|
|
688
|
+
const serviceSelector = typeof (service?.serviceName ?? service?.serviceId) === "string" ? String(service.serviceName ?? service.serviceId).trim() : "";
|
|
689
|
+
if (!serviceSelector) {
|
|
690
|
+
throw new Error(`Railway database service ${service?.key ?? "(unknown)"} is missing a service selector.`);
|
|
691
|
+
}
|
|
692
|
+
const projectSelector = typeof service?.projectId === "string" && service.projectId.trim() ? service.projectId.trim() : typeof service?.projectName === "string" && service.projectName.trim() ? service.projectName.trim() : "";
|
|
693
|
+
if (!projectSelector) {
|
|
694
|
+
throw new Error(`Railway database service ${service?.key ?? serviceSelector} is missing a project selector.`);
|
|
695
|
+
}
|
|
696
|
+
const linkArgs = ["link", "--project", projectSelector];
|
|
697
|
+
const workspace = resolveRailwayWorkspace(env);
|
|
698
|
+
if (workspace) {
|
|
699
|
+
linkArgs.push("--workspace", workspace);
|
|
700
|
+
}
|
|
701
|
+
const environmentName = normalizeRailwayEnvironmentName(service?.railwayEnvironment);
|
|
702
|
+
if (environmentName) {
|
|
703
|
+
linkArgs.push("--environment", environmentName);
|
|
704
|
+
}
|
|
705
|
+
const linkResult = runRailway(linkArgs, {
|
|
706
|
+
cwd: service.rootDir,
|
|
707
|
+
capture: true,
|
|
708
|
+
allowFailure: true,
|
|
709
|
+
env
|
|
710
|
+
});
|
|
711
|
+
if ((linkResult.status ?? 1) !== 0) {
|
|
712
|
+
throw new Error(railwayMessage(linkResult) || `railway ${linkArgs.join(" ")} failed`);
|
|
713
|
+
}
|
|
714
|
+
const statusArgs = ["service", "status", "--service", serviceSelector, "--environment", service.railwayEnvironment, "--json"];
|
|
715
|
+
const statusResult = runRailway(statusArgs, {
|
|
716
|
+
cwd: service.rootDir,
|
|
717
|
+
capture: true,
|
|
718
|
+
allowFailure: true,
|
|
719
|
+
env
|
|
720
|
+
});
|
|
721
|
+
if (statusResult.status === 0) {
|
|
722
|
+
return statusResult;
|
|
723
|
+
}
|
|
724
|
+
const addResult = runRailway(["add", "--database", database, "--service", serviceSelector, "--json"], {
|
|
725
|
+
cwd: service.rootDir,
|
|
726
|
+
capture: true,
|
|
727
|
+
allowFailure: true,
|
|
728
|
+
env
|
|
729
|
+
});
|
|
730
|
+
if (addResult.status !== 0 && !isRailwayAlreadyExistsMessage(addResult)) {
|
|
731
|
+
throw new Error(railwayMessage(addResult) || `railway add --database ${database} --service ${serviceSelector} failed`);
|
|
732
|
+
}
|
|
733
|
+
const refreshed = runRailway(statusArgs, {
|
|
734
|
+
cwd: service.rootDir,
|
|
735
|
+
capture: true,
|
|
736
|
+
allowFailure: true,
|
|
737
|
+
env
|
|
738
|
+
});
|
|
739
|
+
if (refreshed.status !== 0) {
|
|
740
|
+
throw new Error(railwayMessage(refreshed) || `railway service status --service ${serviceSelector} failed`);
|
|
741
|
+
}
|
|
742
|
+
return refreshed;
|
|
743
|
+
}
|
|
671
744
|
function ensureRailwayProjectContext(service, { env = process.env, allowFailure = false, capture = false } = {}) {
|
|
672
745
|
ensureRailwayProjectExists(service, { env });
|
|
673
746
|
let projectSelector = service?.projectId ?? "";
|
|
@@ -718,7 +791,12 @@ function ensureRailwayProjectContext(service, { env = process.env, allowFailure
|
|
|
718
791
|
function configuredRailwayServices(tenantRoot, scope) {
|
|
719
792
|
const deployConfig = loadCliDeployConfig(tenantRoot);
|
|
720
793
|
const normalizedScope = normalizeScope(scope);
|
|
721
|
-
|
|
794
|
+
let identity;
|
|
795
|
+
try {
|
|
796
|
+
identity = resolveTreeseedResourceIdentity(deployConfig, createPersistentDeployTarget(normalizedScope));
|
|
797
|
+
} catch {
|
|
798
|
+
identity = { deploymentKey: deployConfig.slug ?? deployConfig.name ?? "treeseed" };
|
|
799
|
+
}
|
|
722
800
|
const managedRuntime = deployConfig.runtime?.mode === "treeseed_managed";
|
|
723
801
|
const hostingKind = deployConfig.hosting?.kind ?? (managedRuntime ? "hosted_project" : "self_hosted_project");
|
|
724
802
|
if (!managedRuntime) {
|
|
@@ -726,42 +804,58 @@ function configuredRailwayServices(tenantRoot, scope) {
|
|
|
726
804
|
}
|
|
727
805
|
const configuredOptionalServiceKeys = Object.keys(deployConfig.services ?? {}).filter((serviceKey) => RAILWAY_SERVICE_KEYS.includes(serviceKey));
|
|
728
806
|
const serviceKeys = hostingKind === "hosted_project" ? [.../* @__PURE__ */ new Set([...HOSTED_PROJECT_SERVICE_KEYS, ...configuredOptionalServiceKeys])] : RAILWAY_SERVICE_KEYS;
|
|
729
|
-
return serviceKeys.
|
|
807
|
+
return serviceKeys.flatMap((serviceKey) => {
|
|
730
808
|
const service = deployConfig.services?.[serviceKey];
|
|
731
809
|
if (!service || service.enabled === false || (service.provider ?? "railway") !== "railway") {
|
|
732
|
-
return
|
|
810
|
+
return [];
|
|
733
811
|
}
|
|
734
|
-
const defaultRootDir = ["api", "
|
|
812
|
+
const defaultRootDir = ["api", "marketOperationsRunner"].includes(serviceKey) ? "." : "packages/core";
|
|
735
813
|
const serviceRoot = resolve(tenantRoot, service.railway?.rootDir ?? service.rootDir ?? defaultRootDir);
|
|
736
814
|
const railwayEnvironment = resolveRailwayEnvironmentForScope(
|
|
737
815
|
normalizedScope,
|
|
738
816
|
service.environments?.[normalizedScope]?.railwayEnvironment
|
|
739
817
|
);
|
|
740
818
|
const publicBaseUrl = service.environments?.[normalizedScope]?.baseUrl ?? service.publicBaseUrl ?? null;
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
819
|
+
const configuredServiceName = service.railway?.serviceName ?? (serviceKey === "workerRunner" ? deriveRailwayWorkerRunnerServiceName(identity.deploymentKey) : `${identity.deploymentKey}-${railwayServiceNameSuffix(serviceKey)}`);
|
|
820
|
+
const configuredRunnerPool = service.railway?.runnerPool && typeof service.railway.runnerPool === "object" ? service.railway.runnerPool : null;
|
|
821
|
+
const runnerPool = serviceKey === "marketOperationsRunner" ? {
|
|
822
|
+
bootstrapCount: Math.max(1, Number.parseInt(String(configuredRunnerPool?.bootstrapCount ?? MARKET_OPERATIONS_RUNNER_BOOTSTRAP_COUNT), 10) || MARKET_OPERATIONS_RUNNER_BOOTSTRAP_COUNT),
|
|
823
|
+
maxRunners: Math.max(1, Number.parseInt(String(configuredRunnerPool?.maxRunners ?? configuredRunnerPool?.bootstrapCount ?? MARKET_OPERATIONS_RUNNER_BOOTSTRAP_COUNT), 10) || MARKET_OPERATIONS_RUNNER_BOOTSTRAP_COUNT),
|
|
824
|
+
volumeMountPath: service.railway?.volumeMountPath ?? configuredRunnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH
|
|
825
|
+
} : serviceKey === "workerRunner" ? {
|
|
826
|
+
bootstrapIndex: WORKER_RUNNER_BOOTSTRAP_INDEX,
|
|
827
|
+
volumeMountPath: WORKER_RUNNER_VOLUME_MOUNT_PATH
|
|
828
|
+
} : null;
|
|
829
|
+
const instanceCount = serviceKey === "marketOperationsRunner" ? runnerPool.bootstrapCount : 1;
|
|
830
|
+
return Array.from({ length: instanceCount }, (_, offset) => {
|
|
831
|
+
const runnerIndex = offset + 1;
|
|
832
|
+
const serviceName = serviceKey === "marketOperationsRunner" ? deriveRailwayMarketOperationsRunnerServiceName(configuredServiceName, runnerIndex) : configuredServiceName;
|
|
833
|
+
return {
|
|
834
|
+
key: serviceKey,
|
|
835
|
+
instanceKey: serviceKey === "marketOperationsRunner" ? `${serviceKey}:${runnerIndex}` : serviceKey,
|
|
836
|
+
runnerIndex: serviceKey === "marketOperationsRunner" ? runnerIndex : null,
|
|
837
|
+
scope: normalizedScope,
|
|
838
|
+
projectId: service.railway?.projectId ?? null,
|
|
839
|
+
projectName: service.railway?.projectName ?? identity.deploymentKey,
|
|
840
|
+
serviceId: service.railway?.serviceId ?? null,
|
|
841
|
+
serviceName,
|
|
842
|
+
runnerId: serviceKey === "marketOperationsRunner" ? serviceName : null,
|
|
843
|
+
rootDir: serviceRoot,
|
|
844
|
+
publicBaseUrl,
|
|
845
|
+
railwayEnvironment,
|
|
846
|
+
buildCommand: service.railway?.buildCommand ?? null,
|
|
847
|
+
startCommand: service.railway?.startCommand ?? null,
|
|
848
|
+
healthcheckPath: service.railway?.healthcheckPath ?? null,
|
|
849
|
+
healthcheckTimeoutSeconds: service.railway?.healthcheckTimeoutSeconds ?? null,
|
|
850
|
+
healthcheckIntervalSeconds: service.railway?.healthcheckIntervalSeconds ?? null,
|
|
851
|
+
restartPolicy: service.railway?.restartPolicy ?? null,
|
|
852
|
+
runtimeMode: service.railway?.runtimeMode ?? null,
|
|
853
|
+
volumeMountPath: serviceKey === "marketOperationsRunner" ? runnerPool.volumeMountPath : service.railway?.volumeMountPath ?? null,
|
|
854
|
+
schedule: normalizeScheduleExpressions(service.railway?.schedule),
|
|
855
|
+
hostingKind,
|
|
856
|
+
runnerPool
|
|
857
|
+
};
|
|
858
|
+
});
|
|
765
859
|
}).filter(Boolean);
|
|
766
860
|
}
|
|
767
861
|
function configuredRailwayScheduledJobs(tenantRoot, scope, { phase = "deploy" } = {}) {
|
|
@@ -1471,7 +1565,7 @@ async function resolveRailwayDeployProjectContext(service, { env = process.env }
|
|
|
1471
1565
|
}
|
|
1472
1566
|
async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, service, { env = process.env } = {}) {
|
|
1473
1567
|
const wantsInstanceConfig = service.buildCommand || service.startCommand || service.rootDir || service.healthcheckPath || service.healthcheckTimeoutSeconds !== null || service.healthcheckTimeoutSeconds !== void 0 || service.healthcheckIntervalSeconds !== null || service.healthcheckIntervalSeconds !== void 0 || service.restartPolicy || service.runtimeMode;
|
|
1474
|
-
const wantsRunnerVolume = service.key === "workerRunner";
|
|
1568
|
+
const wantsRunnerVolume = service.key === "workerRunner" || Boolean(service.volumeMountPath);
|
|
1475
1569
|
if (!wantsInstanceConfig && !wantsRunnerVolume) {
|
|
1476
1570
|
return null;
|
|
1477
1571
|
}
|
|
@@ -1534,11 +1628,23 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1534
1628
|
environmentId: environment.id,
|
|
1535
1629
|
serviceId: railwayService.id,
|
|
1536
1630
|
variables: {
|
|
1537
|
-
TREESEED_SKIP_PACKAGE_PREPARE: "1"
|
|
1631
|
+
TREESEED_SKIP_PACKAGE_PREPARE: "1",
|
|
1632
|
+
...service.key === "marketOperationsRunner" ? {
|
|
1633
|
+
NIXPACKS_APT_PKGS: "git",
|
|
1634
|
+
NIXPACKS_PKGS: "git",
|
|
1635
|
+
TREESEED_PLATFORM_RUNNER_ID: service.runnerId ?? railwayService.name,
|
|
1636
|
+
TREESEED_PLATFORM_RUNNER_DATA_DIR: service.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH,
|
|
1637
|
+
TREESEED_PLATFORM_RUNNER_ENVIRONMENT: normalizeScope(service.scope) === "prod" ? "production" : normalizeScope(service.scope),
|
|
1638
|
+
TREESEED_MARKET_ID: normalizeScope(service.scope),
|
|
1639
|
+
...configuredEnvValue(env, "TREESEED_PLATFORM_RUNNER_SECRET") ? { TREESEED_PLATFORM_RUNNER_SECRET: configuredEnvValue(env, "TREESEED_PLATFORM_RUNNER_SECRET") } : {},
|
|
1640
|
+
...configuredEnvValue(env, "TREESEED_MARKET_API_BASE_URL") || configuredEnvValue(env, "TREESEED_MARKET_URL") ? {
|
|
1641
|
+
TREESEED_MARKET_API_BASE_URL: configuredEnvValue(env, "TREESEED_MARKET_API_BASE_URL") || configuredEnvValue(env, "TREESEED_MARKET_URL")
|
|
1642
|
+
} : {}
|
|
1643
|
+
} : {}
|
|
1538
1644
|
},
|
|
1539
1645
|
env
|
|
1540
1646
|
});
|
|
1541
|
-
const volumeMountPath = service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
|
|
1647
|
+
const volumeMountPath = service.volumeMountPath ?? service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
|
|
1542
1648
|
const volumeConfiguration = wantsRunnerVolume ? await ensureRailwayServiceVolumeWithCliFallback({
|
|
1543
1649
|
tenantRoot,
|
|
1544
1650
|
projectId: project.id,
|
|
@@ -1546,24 +1652,27 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
|
|
|
1546
1652
|
environmentName: environment.name,
|
|
1547
1653
|
serviceId: railwayService.id,
|
|
1548
1654
|
serviceName: railwayService.name,
|
|
1549
|
-
name: deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1655
|
+
name: service.key === "marketOperationsRunner" ? deriveRailwayMarketOperationsRunnerVolumeName(railwayService.name, environment.name) : deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1550
1656
|
mountPath: volumeMountPath,
|
|
1657
|
+
preferCli: service.key === "marketOperationsRunner",
|
|
1551
1658
|
env
|
|
1552
1659
|
}) : null;
|
|
1553
1660
|
if (wantsRunnerVolume) {
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1661
|
+
if (service.key === "workerRunner") {
|
|
1662
|
+
await upsertRailwayVariables({
|
|
1663
|
+
projectId: project.id,
|
|
1664
|
+
environmentId: environment.id,
|
|
1665
|
+
serviceId: railwayService.id,
|
|
1666
|
+
variables: {
|
|
1667
|
+
TREESEED_RUNNER_SERVICE_NAME: railwayService.name,
|
|
1668
|
+
TREESEED_RUNNER_VOLUME_ROOT: volumeMountPath,
|
|
1669
|
+
TREESEED_RUNNER_VOLUME_NAME: volumeConfiguration?.volume.name ?? deriveRailwayWorkerRunnerVolumeName(railwayService.name, environment.name),
|
|
1670
|
+
TREESEED_WORKER_IDLE_EXIT_MS: configuredEnvValue(env, "TREESEED_WORKER_IDLE_EXIT_MS") || "60000",
|
|
1671
|
+
...volumeConfiguration?.volume.id ? { TREESEED_RUNNER_VOLUME_ID: volumeConfiguration.volume.id } : {}
|
|
1672
|
+
},
|
|
1673
|
+
env
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1567
1676
|
}
|
|
1568
1677
|
return {
|
|
1569
1678
|
projectId: project.id,
|
|
@@ -1592,21 +1701,24 @@ async function ensureRailwayServiceVolumeWithCliFallback({
|
|
|
1592
1701
|
serviceName,
|
|
1593
1702
|
name,
|
|
1594
1703
|
mountPath,
|
|
1704
|
+
preferCli = false,
|
|
1595
1705
|
env = process.env
|
|
1596
1706
|
}) {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1707
|
+
if (!preferCli) {
|
|
1708
|
+
try {
|
|
1709
|
+
return await ensureRailwayServiceVolume({
|
|
1710
|
+
projectId,
|
|
1711
|
+
environmentId,
|
|
1712
|
+
serviceId,
|
|
1713
|
+
name,
|
|
1714
|
+
mountPath,
|
|
1715
|
+
env
|
|
1716
|
+
});
|
|
1717
|
+
} catch (error) {
|
|
1718
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1719
|
+
if (!message.includes("Problem processing request")) {
|
|
1720
|
+
throw error;
|
|
1721
|
+
}
|
|
1610
1722
|
}
|
|
1611
1723
|
}
|
|
1612
1724
|
const cliOptions = {
|
|
@@ -1795,8 +1907,11 @@ export {
|
|
|
1795
1907
|
configuredRailwayScheduledJobs,
|
|
1796
1908
|
configuredRailwayServices,
|
|
1797
1909
|
deployRailwayService,
|
|
1910
|
+
deriveRailwayMarketOperationsRunnerServiceName,
|
|
1911
|
+
deriveRailwayMarketOperationsRunnerVolumeName,
|
|
1798
1912
|
deriveRailwayWorkerRunnerServiceName,
|
|
1799
1913
|
deriveRailwayWorkerRunnerVolumeName,
|
|
1914
|
+
ensureRailwayDatabaseServiceExists,
|
|
1800
1915
|
ensureRailwayEnvironmentExists,
|
|
1801
1916
|
ensureRailwayProjectContext,
|
|
1802
1917
|
ensureRailwayProjectExists,
|
|
@@ -365,12 +365,11 @@ function dependencyRehearsalChecks(root, plannedVersions, selectedPackageNames,
|
|
|
365
365
|
});
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
-
const selectedPackageSet = new Set(selectedPackageNames);
|
|
369
368
|
const devReferenceIssues = collectInternalDevReferenceIssues(root);
|
|
370
369
|
const unrehearsableDevReferences = devReferenceIssues.filter((issue) => {
|
|
371
370
|
const dependencyName = issue.dependencyName ?? "";
|
|
372
371
|
const planned = plannedVersions[dependencyName];
|
|
373
|
-
return !
|
|
372
|
+
return !planned || !STABLE_SEMVER.test(planned);
|
|
374
373
|
});
|
|
375
374
|
if (unrehearsableDevReferences.length > 0) {
|
|
376
375
|
addFailure(failures, {
|