@nodetool-ai/deploy 0.7.0-rc.11
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/admin-client.d.ts +58 -0
- package/dist/admin-client.d.ts.map +1 -0
- package/dist/admin-client.js +275 -0
- package/dist/admin-client.js.map +1 -0
- package/dist/admin-operations.d.ts +197 -0
- package/dist/admin-operations.d.ts.map +1 -0
- package/dist/admin-operations.js +433 -0
- package/dist/admin-operations.js.map +1 -0
- package/dist/admin-routes.d.ts +306 -0
- package/dist/admin-routes.d.ts.map +1 -0
- package/dist/admin-routes.js +383 -0
- package/dist/admin-routes.js.map +1 -0
- package/dist/api-user-manager.d.ts +72 -0
- package/dist/api-user-manager.d.ts.map +1 -0
- package/dist/api-user-manager.js +89 -0
- package/dist/api-user-manager.js.map +1 -0
- package/dist/auth.d.ts +67 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +142 -0
- package/dist/auth.js.map +1 -0
- package/dist/collection-routes.d.ts +37 -0
- package/dist/collection-routes.d.ts.map +1 -0
- package/dist/collection-routes.js +43 -0
- package/dist/collection-routes.js.map +1 -0
- package/dist/compose.d.ts +52 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +153 -0
- package/dist/compose.js.map +1 -0
- package/dist/configure.d.ts +87 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +104 -0
- package/dist/configure.js.map +1 -0
- package/dist/deploy-to-gcp.d.ts +67 -0
- package/dist/deploy-to-gcp.d.ts.map +1 -0
- package/dist/deploy-to-gcp.js +268 -0
- package/dist/deploy-to-gcp.js.map +1 -0
- package/dist/deploy-to-runpod.d.ts +53 -0
- package/dist/deploy-to-runpod.d.ts.map +1 -0
- package/dist/deploy-to-runpod.js +207 -0
- package/dist/deploy-to-runpod.js.map +1 -0
- package/dist/deploy.d.ts +54 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +82 -0
- package/dist/deploy.js.map +1 -0
- package/dist/deployment-config.d.ts +1073 -0
- package/dist/deployment-config.d.ts.map +1 -0
- package/dist/deployment-config.js +536 -0
- package/dist/deployment-config.js.map +1 -0
- package/dist/docker-run.d.ts +85 -0
- package/dist/docker-run.d.ts.map +1 -0
- package/dist/docker-run.js +202 -0
- package/dist/docker-run.js.map +1 -0
- package/dist/docker.d.ts +98 -0
- package/dist/docker.d.ts.map +1 -0
- package/dist/docker.js +396 -0
- package/dist/docker.js.map +1 -0
- package/dist/fly.d.ts +40 -0
- package/dist/fly.d.ts.map +1 -0
- package/dist/fly.js +291 -0
- package/dist/fly.js.map +1 -0
- package/dist/gcp.d.ts +59 -0
- package/dist/gcp.d.ts.map +1 -0
- package/dist/gcp.js +339 -0
- package/dist/gcp.js.map +1 -0
- package/dist/google-cloud-run-api.d.ts +134 -0
- package/dist/google-cloud-run-api.d.ts.map +1 -0
- package/dist/google-cloud-run-api.js +532 -0
- package/dist/google-cloud-run-api.js.map +1 -0
- package/dist/huggingface.d.ts +69 -0
- package/dist/huggingface.d.ts.map +1 -0
- package/dist/huggingface.js +346 -0
- package/dist/huggingface.js.map +1 -0
- package/dist/image-builder.d.ts +35 -0
- package/dist/image-builder.d.ts.map +1 -0
- package/dist/image-builder.js +157 -0
- package/dist/image-builder.js.map +1 -0
- package/dist/image-spec.d.ts +41 -0
- package/dist/image-spec.d.ts.map +1 -0
- package/dist/image-spec.js +49 -0
- package/dist/image-spec.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.d.ts +121 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +225 -0
- package/dist/manager.js.map +1 -0
- package/dist/progress.d.ts +91 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +262 -0
- package/dist/progress.js.map +1 -0
- package/dist/railway.d.ts +65 -0
- package/dist/railway.d.ts.map +1 -0
- package/dist/railway.js +284 -0
- package/dist/railway.js.map +1 -0
- package/dist/remote-users.d.ts +74 -0
- package/dist/remote-users.d.ts.map +1 -0
- package/dist/remote-users.js +172 -0
- package/dist/remote-users.js.map +1 -0
- package/dist/runpod-api.d.ts +206 -0
- package/dist/runpod-api.d.ts.map +1 -0
- package/dist/runpod-api.js +703 -0
- package/dist/runpod-api.js.map +1 -0
- package/dist/runpod.d.ts +82 -0
- package/dist/runpod.d.ts.map +1 -0
- package/dist/runpod.js +188 -0
- package/dist/runpod.js.map +1 -0
- package/dist/self-hosted.d.ts +157 -0
- package/dist/self-hosted.d.ts.map +1 -0
- package/dist/self-hosted.js +799 -0
- package/dist/self-hosted.js.map +1 -0
- package/dist/ssh.d.ts +166 -0
- package/dist/ssh.d.ts.map +1 -0
- package/dist/ssh.js +430 -0
- package/dist/ssh.js.map +1 -0
- package/dist/state.d.ts +83 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +368 -0
- package/dist/state.js.map +1 -0
- package/dist/storage-routes.d.ts +55 -0
- package/dist/storage-routes.d.ts.map +1 -0
- package/dist/storage-routes.js +160 -0
- package/dist/storage-routes.js.map +1 -0
- package/dist/sync.d.ts +38 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +130 -0
- package/dist/sync.js.map +1 -0
- package/dist/workflow-syncer.d.ts +51 -0
- package/dist/workflow-syncer.d.ts.map +1 -0
- package/dist/workflow-syncer.js +192 -0
- package/dist/workflow-syncer.js.map +1 -0
- package/package.json +58 -0
package/dist/progress.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress management for NodeTool deployments.
|
|
3
|
+
*
|
|
4
|
+
* Provides a console-based progress display for deployment operations
|
|
5
|
+
* including file downloads, Docker pulls, and health checks.
|
|
6
|
+
*/
|
|
7
|
+
const defaultLogger = {
|
|
8
|
+
log: (msg) => console.log(msg),
|
|
9
|
+
error: (msg) => console.error(msg)
|
|
10
|
+
};
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Simple Progress Bar Renderer
|
|
13
|
+
// ============================================================================
|
|
14
|
+
function renderBar(completed, total, width = 30) {
|
|
15
|
+
const ratio = Math.min(completed / total, 1);
|
|
16
|
+
const filled = Math.round(ratio * width);
|
|
17
|
+
const empty = width - filled;
|
|
18
|
+
const pct = (ratio * 100).toFixed(0);
|
|
19
|
+
return `[${"#".repeat(filled)}${"-".repeat(empty)}] ${pct}%`;
|
|
20
|
+
}
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// ProgressManager
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Manages progress display for deployment operations.
|
|
26
|
+
*
|
|
27
|
+
* Unlike the Python version which uses Rich progress bars, this uses simple
|
|
28
|
+
* console output that works in any Node.js environment.
|
|
29
|
+
*/
|
|
30
|
+
export class ProgressManager {
|
|
31
|
+
logger;
|
|
32
|
+
tasks = new Map();
|
|
33
|
+
started = false;
|
|
34
|
+
constructor(logger) {
|
|
35
|
+
this.logger = logger ?? defaultLogger;
|
|
36
|
+
}
|
|
37
|
+
/** Start the progress display. */
|
|
38
|
+
start() {
|
|
39
|
+
this.started = true;
|
|
40
|
+
}
|
|
41
|
+
/** Stop the progress display and clear all tasks. */
|
|
42
|
+
stop() {
|
|
43
|
+
this.tasks.clear();
|
|
44
|
+
this.started = false;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Add a new progress task.
|
|
48
|
+
*
|
|
49
|
+
* @returns A numeric task index (for compatibility).
|
|
50
|
+
*/
|
|
51
|
+
addTask(operationId, description, total = null) {
|
|
52
|
+
if (!this.started)
|
|
53
|
+
this.start();
|
|
54
|
+
if (!this.tasks.has(operationId)) {
|
|
55
|
+
this.tasks.set(operationId, {
|
|
56
|
+
description,
|
|
57
|
+
total,
|
|
58
|
+
completed: 0
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return this.tasks.size - 1;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Update a progress task.
|
|
65
|
+
*/
|
|
66
|
+
updateTask(operationId, completed, description) {
|
|
67
|
+
const info = this.tasks.get(operationId);
|
|
68
|
+
if (!info)
|
|
69
|
+
return;
|
|
70
|
+
if (completed !== undefined) {
|
|
71
|
+
info.completed = completed;
|
|
72
|
+
}
|
|
73
|
+
if (description !== undefined) {
|
|
74
|
+
info.description = description;
|
|
75
|
+
}
|
|
76
|
+
// Print current progress
|
|
77
|
+
if (info.total !== null && info.total > 0) {
|
|
78
|
+
this.logger.log(` ${info.description} ${renderBar(info.completed, info.total)}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.logger.log(` ${info.description}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Mark a task as completed and remove it.
|
|
86
|
+
*/
|
|
87
|
+
completeTask(operationId) {
|
|
88
|
+
const info = this.tasks.get(operationId);
|
|
89
|
+
if (!info)
|
|
90
|
+
return;
|
|
91
|
+
if (info.total !== null && info.total > 0) {
|
|
92
|
+
this.logger.log(` ${info.description} ${renderBar(info.total, info.total)}`);
|
|
93
|
+
}
|
|
94
|
+
this.tasks.delete(operationId);
|
|
95
|
+
if (this.tasks.size === 0) {
|
|
96
|
+
this.stop();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Remove a task without completing it.
|
|
101
|
+
*/
|
|
102
|
+
removeTask(operationId) {
|
|
103
|
+
this.tasks.delete(operationId);
|
|
104
|
+
if (this.tasks.size === 0) {
|
|
105
|
+
this.stop();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Display a progress update from a deployment operation.
|
|
110
|
+
*/
|
|
111
|
+
displayProgressUpdate(progressUpdate) {
|
|
112
|
+
const status = progressUpdate.status ?? "unknown";
|
|
113
|
+
const message = progressUpdate.message ?? "";
|
|
114
|
+
if (status === "starting") {
|
|
115
|
+
this.logger.log(`[starting] ${message}`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (status === "progress") {
|
|
119
|
+
this.handleProgressStatus(progressUpdate, message);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (status === "completed") {
|
|
123
|
+
this.logger.log(`[completed] ${message}`);
|
|
124
|
+
// Complete any active download/file progress tasks
|
|
125
|
+
for (const opId of Array.from(this.tasks.keys())) {
|
|
126
|
+
if (opId.includes("download") || opId.startsWith("files_")) {
|
|
127
|
+
this.completeTask(opId);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (progressUpdate.downloaded_files !== undefined) {
|
|
131
|
+
this.logger.log(` Downloaded ${progressUpdate.downloaded_files} files`);
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (status.startsWith("pulling")) {
|
|
136
|
+
this.handlePullingStatus(progressUpdate, status);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (status === "error") {
|
|
140
|
+
const error = progressUpdate.error ?? "Unknown error";
|
|
141
|
+
this.logger.error(`[error] ${error}`);
|
|
142
|
+
this.stop();
|
|
143
|
+
throw new Error("Deployment failed");
|
|
144
|
+
}
|
|
145
|
+
if (status === "healthy") {
|
|
146
|
+
this.handleHealthyStatus(progressUpdate);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Unknown status — just log
|
|
150
|
+
if (message) {
|
|
151
|
+
this.logger.log(`[${status}] ${message}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// --------------------------------------------------------------------------
|
|
155
|
+
// Private helpers
|
|
156
|
+
// --------------------------------------------------------------------------
|
|
157
|
+
handleProgressStatus(update, message) {
|
|
158
|
+
if (update.current_file !== undefined) {
|
|
159
|
+
const currentFile = update.current_file;
|
|
160
|
+
if (update.file_progress !== undefined &&
|
|
161
|
+
update.total_files !== undefined) {
|
|
162
|
+
const fileNum = update.file_progress;
|
|
163
|
+
const totalFiles = update.total_files;
|
|
164
|
+
const operationId = `files_${currentFile}`;
|
|
165
|
+
const desc = `Downloading files (${fileNum}/${totalFiles}): ${currentFile}`;
|
|
166
|
+
if (!this.tasks.has(operationId)) {
|
|
167
|
+
this.addTask(operationId, desc, totalFiles);
|
|
168
|
+
}
|
|
169
|
+
this.updateTask(operationId, fileNum, desc);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.logger.log(` File: ${currentFile}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (update.downloaded_size !== undefined &&
|
|
176
|
+
update.total_size !== undefined) {
|
|
177
|
+
const downloaded = update.downloaded_size;
|
|
178
|
+
const total = update.total_size;
|
|
179
|
+
if (total > 0) {
|
|
180
|
+
const operationId = update.operation_id ?? "download";
|
|
181
|
+
const currentFile = update.current_file ?? "";
|
|
182
|
+
const downloadedMb = (downloaded / (1024 * 1024)).toFixed(1);
|
|
183
|
+
const totalMb = (total / (1024 * 1024)).toFixed(1);
|
|
184
|
+
let desc = "Downloading";
|
|
185
|
+
if (currentFile)
|
|
186
|
+
desc += ` ${currentFile}`;
|
|
187
|
+
desc += ` (${downloadedMb}/${totalMb} MB)`;
|
|
188
|
+
if (!this.tasks.has(operationId)) {
|
|
189
|
+
this.addTask(operationId, desc, total);
|
|
190
|
+
}
|
|
191
|
+
this.updateTask(operationId, downloaded, desc);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// General progress message
|
|
195
|
+
if (update.current_file === undefined &&
|
|
196
|
+
update.downloaded_size === undefined &&
|
|
197
|
+
message) {
|
|
198
|
+
this.logger.log(` ${message}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
handlePullingStatus(update, status) {
|
|
202
|
+
const digest = update.digest ?? "";
|
|
203
|
+
const total = update.total;
|
|
204
|
+
const completed = update.completed;
|
|
205
|
+
const layerId = status.includes(" ")
|
|
206
|
+
? status.replace("pulling ", "")
|
|
207
|
+
: "unknown";
|
|
208
|
+
const operationId = `pull_${layerId}`;
|
|
209
|
+
let description = `Pulling layer ${layerId}`;
|
|
210
|
+
if (digest.includes("sha256:")) {
|
|
211
|
+
const shortDigest = digest.split(":").pop()?.slice(0, 12) ?? "";
|
|
212
|
+
description += ` (sha256:${shortDigest})`;
|
|
213
|
+
}
|
|
214
|
+
if (total && completed !== undefined) {
|
|
215
|
+
const totalMb = (total / (1024 * 1024)).toFixed(1);
|
|
216
|
+
const completedMb = (completed / (1024 * 1024)).toFixed(1);
|
|
217
|
+
description += ` (${completedMb}/${totalMb} MB)`;
|
|
218
|
+
if (!this.tasks.has(operationId)) {
|
|
219
|
+
this.addTask(operationId, description, total);
|
|
220
|
+
}
|
|
221
|
+
this.updateTask(operationId, completed, description);
|
|
222
|
+
}
|
|
223
|
+
else if (total) {
|
|
224
|
+
const totalMb = (total / (1024 * 1024)).toFixed(1);
|
|
225
|
+
description += ` (${totalMb} MB)`;
|
|
226
|
+
this.logger.log(` ${description}`);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.logger.log(` ${description}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
handleHealthyStatus(update) {
|
|
233
|
+
this.logger.log("[healthy] System is healthy");
|
|
234
|
+
this.logger.log(` Platform: ${update.platform ?? "Unknown"}`);
|
|
235
|
+
this.logger.log(` Python: ${update.python_version ?? "Unknown"}`);
|
|
236
|
+
this.logger.log(` Hostname: ${update.hostname ?? "Unknown"}`);
|
|
237
|
+
const memory = update.memory;
|
|
238
|
+
if (memory && typeof memory === "object") {
|
|
239
|
+
this.logger.log(` Memory: ${memory.available_gb?.toFixed(1) ?? "?"}GB available / ${memory.total_gb?.toFixed(1) ?? "?"}GB total (${memory.used_percent ?? "?"}% used)`);
|
|
240
|
+
}
|
|
241
|
+
const disk = update.disk;
|
|
242
|
+
if (disk && typeof disk === "object") {
|
|
243
|
+
this.logger.log(` Disk: ${disk.free_gb?.toFixed(1) ?? "?"}GB free / ${disk.total_gb?.toFixed(1) ?? "?"}GB total (${disk.used_percent ?? "?"}% used)`);
|
|
244
|
+
}
|
|
245
|
+
const gpus = update.gpus;
|
|
246
|
+
if (Array.isArray(gpus) && gpus.length > 0) {
|
|
247
|
+
this.logger.log(" GPUs:");
|
|
248
|
+
for (let i = 0; i < gpus.length; i++) {
|
|
249
|
+
const gpu = gpus[i];
|
|
250
|
+
const name = gpu.name ?? "Unknown";
|
|
251
|
+
const usedMb = gpu.memory_used_mb ?? 0;
|
|
252
|
+
const totalMb = gpu.memory_total_mb ?? 0;
|
|
253
|
+
const usedPct = totalMb > 0 ? ((usedMb / totalMb) * 100).toFixed(1) : "0.0";
|
|
254
|
+
this.logger.log(` GPU ${i}: ${name} - ${usedMb}MB/${totalMb}MB (${usedPct}% used)`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
else if (gpus === "unavailable") {
|
|
258
|
+
this.logger.log(" GPUs: Not available");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway deployment implementation for NodeTool.
|
|
3
|
+
*
|
|
4
|
+
* Handles deployment to Railway using the `railway` CLI, including:
|
|
5
|
+
* - Docker image building and deployment
|
|
6
|
+
* - Environment variable configuration
|
|
7
|
+
* - Service management (create, destroy, status, logs)
|
|
8
|
+
*/
|
|
9
|
+
import { StateManager } from "./state.js";
|
|
10
|
+
import type { RailwayDeployment } from "./deployment-config.js";
|
|
11
|
+
import type { DeployResult } from "./self-hosted.js";
|
|
12
|
+
/**
|
|
13
|
+
* Handles deployment to Railway.
|
|
14
|
+
*
|
|
15
|
+
* Orchestrates the entire Railway deployment process including:
|
|
16
|
+
* - Docker image building from an image spec
|
|
17
|
+
* - Linking to a Railway project
|
|
18
|
+
* - Setting environment variables
|
|
19
|
+
* - Deploying the service
|
|
20
|
+
* - State management
|
|
21
|
+
*/
|
|
22
|
+
export declare class RailwayDeployer {
|
|
23
|
+
readonly deploymentName: string;
|
|
24
|
+
readonly deployment: RailwayDeployment;
|
|
25
|
+
readonly stateManager: StateManager;
|
|
26
|
+
constructor(deploymentName: string, deployment: RailwayDeployment, stateManager?: StateManager);
|
|
27
|
+
/**
|
|
28
|
+
* Generate a deployment plan showing what changes will be made.
|
|
29
|
+
*/
|
|
30
|
+
plan(): Promise<Record<string, unknown>>;
|
|
31
|
+
/**
|
|
32
|
+
* Apply the deployment to Railway.
|
|
33
|
+
*
|
|
34
|
+
* Steps:
|
|
35
|
+
* 1. Load image spec and build Docker image
|
|
36
|
+
* 2. Link to Railway project
|
|
37
|
+
* 3. Set environment variables
|
|
38
|
+
* 4. Deploy with `railway up`
|
|
39
|
+
* 5. Update deployment state
|
|
40
|
+
*
|
|
41
|
+
* @param opts.dryRun If true, only show what would be done without executing.
|
|
42
|
+
*/
|
|
43
|
+
apply(opts?: {
|
|
44
|
+
dryRun?: boolean;
|
|
45
|
+
}): Promise<DeployResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Destroy the Railway service.
|
|
48
|
+
*/
|
|
49
|
+
destroy(): Promise<DeployResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Get current deployment status from Railway.
|
|
52
|
+
*/
|
|
53
|
+
status(): Promise<Record<string, unknown>>;
|
|
54
|
+
/**
|
|
55
|
+
* Get logs from the Railway service.
|
|
56
|
+
*
|
|
57
|
+
* @param opts.follow Stream logs in real time.
|
|
58
|
+
* @param opts.tail Number of recent log lines to fetch.
|
|
59
|
+
*/
|
|
60
|
+
logs(opts?: {
|
|
61
|
+
follow?: boolean;
|
|
62
|
+
tail?: number;
|
|
63
|
+
}): Promise<string>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=railway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railway.d.ts","sourceRoot":"","sources":["../src/railway.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAsCrD;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;gBAGlC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,CAAC,EAAE,YAAY;IAS7B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAuC9C;;;;;;;;;;;OAWG;IACG,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IA0F/D;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;IAgDtC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAqChD;;;;;OAKG;IACG,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAgCxE"}
|
package/dist/railway.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway deployment implementation for NodeTool.
|
|
3
|
+
*
|
|
4
|
+
* Handles deployment to Railway using the `railway` CLI, including:
|
|
5
|
+
* - Docker image building and deployment
|
|
6
|
+
* - Environment variable configuration
|
|
7
|
+
* - Service management (create, destroy, status, logs)
|
|
8
|
+
*/
|
|
9
|
+
import { execFile } from "node:child_process";
|
|
10
|
+
import { promisify } from "node:util";
|
|
11
|
+
import * as fs from "node:fs/promises";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import * as os from "node:os";
|
|
14
|
+
import { createLogger } from "@nodetool-ai/config";
|
|
15
|
+
const log = createLogger("nodetool.deploy.railway");
|
|
16
|
+
import { loadImageSpec } from "./image-spec.js";
|
|
17
|
+
import { generateDockerfile } from "./image-builder.js";
|
|
18
|
+
import { StateManager } from "./state.js";
|
|
19
|
+
import { DeploymentStatus } from "./deployment-config.js";
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Helpers
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/**
|
|
25
|
+
* Run a `railway` CLI command and return stdout.
|
|
26
|
+
* Throws a descriptive error when the CLI is not installed.
|
|
27
|
+
*/
|
|
28
|
+
async function railwayCli(args, opts) {
|
|
29
|
+
try {
|
|
30
|
+
const { stdout } = await execFileAsync("railway", args, {
|
|
31
|
+
timeout: opts?.timeout ?? 60_000,
|
|
32
|
+
cwd: opts?.cwd
|
|
33
|
+
});
|
|
34
|
+
return stdout;
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
38
|
+
if (msg.includes("ENOENT")) {
|
|
39
|
+
throw new Error("railway CLI not found. Install it with: npm install -g @railway/cli\n" +
|
|
40
|
+
"See https://docs.railway.app/develop/cli for details.");
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`railway CLI failed: ${msg}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// RailwayDeployer class
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Handles deployment to Railway.
|
|
50
|
+
*
|
|
51
|
+
* Orchestrates the entire Railway deployment process including:
|
|
52
|
+
* - Docker image building from an image spec
|
|
53
|
+
* - Linking to a Railway project
|
|
54
|
+
* - Setting environment variables
|
|
55
|
+
* - Deploying the service
|
|
56
|
+
* - State management
|
|
57
|
+
*/
|
|
58
|
+
export class RailwayDeployer {
|
|
59
|
+
deploymentName;
|
|
60
|
+
deployment;
|
|
61
|
+
stateManager;
|
|
62
|
+
constructor(deploymentName, deployment, stateManager) {
|
|
63
|
+
this.deploymentName = deploymentName;
|
|
64
|
+
this.deployment = deployment;
|
|
65
|
+
this.stateManager = stateManager ?? new StateManager();
|
|
66
|
+
}
|
|
67
|
+
// ---------- Public API ----------
|
|
68
|
+
/**
|
|
69
|
+
* Generate a deployment plan showing what changes will be made.
|
|
70
|
+
*/
|
|
71
|
+
async plan() {
|
|
72
|
+
const planResult = {
|
|
73
|
+
deployment_name: this.deploymentName,
|
|
74
|
+
type: "railway",
|
|
75
|
+
project: this.deployment.project,
|
|
76
|
+
service: this.deployment.service,
|
|
77
|
+
changes: [],
|
|
78
|
+
will_create: [],
|
|
79
|
+
will_update: [],
|
|
80
|
+
will_destroy: []
|
|
81
|
+
};
|
|
82
|
+
const changes = planResult["changes"];
|
|
83
|
+
const willCreate = planResult["will_create"];
|
|
84
|
+
const currentState = await this.stateManager.readState(this.deploymentName);
|
|
85
|
+
willCreate.push("Docker image (if changed)");
|
|
86
|
+
if (!currentState || !currentState["last_deployed"]) {
|
|
87
|
+
changes.push("Initial deployment - will create all resources");
|
|
88
|
+
willCreate.push(`Railway service: ${this.deployment.service}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
changes.push("Will re-deploy service with current configuration");
|
|
92
|
+
planResult["will_update"].push(`Railway service: ${this.deployment.service}`);
|
|
93
|
+
}
|
|
94
|
+
if (this.deployment.environment) {
|
|
95
|
+
const envKeys = Object.keys(this.deployment.environment);
|
|
96
|
+
if (envKeys.length > 0) {
|
|
97
|
+
changes.push(`Environment variables: ${envKeys.join(", ")}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return planResult;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Apply the deployment to Railway.
|
|
104
|
+
*
|
|
105
|
+
* Steps:
|
|
106
|
+
* 1. Load image spec and build Docker image
|
|
107
|
+
* 2. Link to Railway project
|
|
108
|
+
* 3. Set environment variables
|
|
109
|
+
* 4. Deploy with `railway up`
|
|
110
|
+
* 5. Update deployment state
|
|
111
|
+
*
|
|
112
|
+
* @param opts.dryRun If true, only show what would be done without executing.
|
|
113
|
+
*/
|
|
114
|
+
async apply(opts) {
|
|
115
|
+
if (opts?.dryRun) {
|
|
116
|
+
return (await this.plan());
|
|
117
|
+
}
|
|
118
|
+
const results = {
|
|
119
|
+
deployment_name: this.deploymentName,
|
|
120
|
+
status: "success",
|
|
121
|
+
steps: [],
|
|
122
|
+
errors: []
|
|
123
|
+
};
|
|
124
|
+
if (!/^[\w-]+$/.test(this.deployment.project)) {
|
|
125
|
+
throw new Error(`Invalid Railway project: "${this.deployment.project}"`);
|
|
126
|
+
}
|
|
127
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "nodetool-railway-"));
|
|
128
|
+
try {
|
|
129
|
+
await this.stateManager.updateDeploymentStatus(this.deploymentName, DeploymentStatus.DEPLOYING);
|
|
130
|
+
// 1. Generate Dockerfile from image spec
|
|
131
|
+
results.steps.push("Loading image spec...");
|
|
132
|
+
const spec = await loadImageSpec(this.deployment.image);
|
|
133
|
+
results.steps.push("Generating Dockerfile...");
|
|
134
|
+
const dockerfile = generateDockerfile(spec);
|
|
135
|
+
await fs.writeFile(path.join(tmpDir, "Dockerfile"), dockerfile);
|
|
136
|
+
results.steps.push("Wrote Dockerfile to temp directory");
|
|
137
|
+
// 2. Link to Railway project
|
|
138
|
+
results.steps.push(`Linking to Railway project: ${this.deployment.project}...`);
|
|
139
|
+
await railwayCli(["link", "--project", this.deployment.project], {
|
|
140
|
+
cwd: tmpDir
|
|
141
|
+
});
|
|
142
|
+
results.steps.push("Linked to Railway project");
|
|
143
|
+
// 3. Set environment variables (must be after link)
|
|
144
|
+
if (this.deployment.environment) {
|
|
145
|
+
const envEntries = Object.entries(this.deployment.environment);
|
|
146
|
+
if (envEntries.length > 0) {
|
|
147
|
+
results.steps.push("Setting environment variables...");
|
|
148
|
+
const vars = envEntries.map(([k, v]) => `${k}=${v}`);
|
|
149
|
+
await railwayCli(["variables", "set", ...vars], { cwd: tmpDir });
|
|
150
|
+
results.steps.push(`Set ${envEntries.length} environment variable(s)`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// 4. Deploy from temp dir (Railway detects Dockerfile)
|
|
154
|
+
results.steps.push(`Deploying service: ${this.deployment.service}...`);
|
|
155
|
+
await railwayCli(["up", "--service", this.deployment.service], {
|
|
156
|
+
cwd: tmpDir,
|
|
157
|
+
timeout: 300_000
|
|
158
|
+
});
|
|
159
|
+
results.steps.push("Railway deployment completed");
|
|
160
|
+
// 4. Update state
|
|
161
|
+
await this.stateManager.writeState(this.deploymentName, {
|
|
162
|
+
status: DeploymentStatus.SERVING,
|
|
163
|
+
project: this.deployment.project,
|
|
164
|
+
service: this.deployment.service
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
results.status = "error";
|
|
169
|
+
results.errors.push(e instanceof Error ? e.message : String(e));
|
|
170
|
+
await this.stateManager.updateDeploymentStatus(this.deploymentName, DeploymentStatus.ERROR);
|
|
171
|
+
throw e;
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
await fs.rm(tmpDir, { recursive: true, force: true }).catch((err) => {
|
|
175
|
+
log.debug(`Failed to clean up Railway temp dir ${tmpDir}`, err);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return results;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Destroy the Railway service.
|
|
182
|
+
*/
|
|
183
|
+
async destroy() {
|
|
184
|
+
const results = {
|
|
185
|
+
deployment_name: this.deploymentName,
|
|
186
|
+
status: "success",
|
|
187
|
+
steps: [],
|
|
188
|
+
errors: []
|
|
189
|
+
};
|
|
190
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "nodetool-railway-"));
|
|
191
|
+
try {
|
|
192
|
+
results.steps.push(`Deleting Railway service: ${this.deployment.service}...`);
|
|
193
|
+
// Link to project first so the CLI knows which project to target
|
|
194
|
+
await railwayCli(["link", "--project", this.deployment.project], {
|
|
195
|
+
cwd: tmpDir
|
|
196
|
+
});
|
|
197
|
+
await railwayCli(["service", "delete", this.deployment.service, "--yes"], { cwd: tmpDir });
|
|
198
|
+
results.steps.push("Service deleted successfully");
|
|
199
|
+
await this.stateManager.updateDeploymentStatus(this.deploymentName, DeploymentStatus.DESTROYED);
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
results.status = "error";
|
|
203
|
+
results.errors.push(e instanceof Error ? e.message : String(e));
|
|
204
|
+
await this.stateManager.updateDeploymentStatus(this.deploymentName, DeploymentStatus.ERROR);
|
|
205
|
+
throw e;
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
await fs.rm(tmpDir, { recursive: true, force: true }).catch((err) => {
|
|
209
|
+
log.debug(`Failed to clean up Railway temp dir ${tmpDir}`, err);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get current deployment status from Railway.
|
|
216
|
+
*/
|
|
217
|
+
async status() {
|
|
218
|
+
const statusInfo = {
|
|
219
|
+
deployment_name: this.deploymentName,
|
|
220
|
+
type: "railway",
|
|
221
|
+
project: this.deployment.project,
|
|
222
|
+
service: this.deployment.service
|
|
223
|
+
};
|
|
224
|
+
// Get state from state manager
|
|
225
|
+
const state = await this.stateManager.readState(this.deploymentName);
|
|
226
|
+
if (state) {
|
|
227
|
+
statusInfo["status"] = state["status"] ?? "unknown";
|
|
228
|
+
statusInfo["last_deployed"] = state["last_deployed"];
|
|
229
|
+
}
|
|
230
|
+
// Try to get live status from Railway
|
|
231
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "nodetool-railway-"));
|
|
232
|
+
try {
|
|
233
|
+
await railwayCli(["link", "--project", this.deployment.project], {
|
|
234
|
+
cwd: tmpDir
|
|
235
|
+
});
|
|
236
|
+
const output = await railwayCli(["status", "--json"], { cwd: tmpDir });
|
|
237
|
+
statusInfo["live_status"] = JSON.parse(output);
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
statusInfo["live_status_error"] =
|
|
241
|
+
e instanceof Error ? e.message : String(e);
|
|
242
|
+
}
|
|
243
|
+
finally {
|
|
244
|
+
await fs.rm(tmpDir, { recursive: true, force: true }).catch((err) => {
|
|
245
|
+
log.debug(`Failed to clean up Railway temp dir ${tmpDir}`, err);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return statusInfo;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get logs from the Railway service.
|
|
252
|
+
*
|
|
253
|
+
* @param opts.follow Stream logs in real time.
|
|
254
|
+
* @param opts.tail Number of recent log lines to fetch.
|
|
255
|
+
*/
|
|
256
|
+
async logs(opts) {
|
|
257
|
+
if (opts?.follow) {
|
|
258
|
+
throw new Error("Streaming logs not supported. Use 'railway logs --service " +
|
|
259
|
+
`${this.deployment.service} --follow' directly.`);
|
|
260
|
+
}
|
|
261
|
+
const args = ["logs", "--service", this.deployment.service];
|
|
262
|
+
if (opts?.tail !== undefined) {
|
|
263
|
+
args.push("--tail", String(opts.tail));
|
|
264
|
+
}
|
|
265
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "nodetool-railway-"));
|
|
266
|
+
try {
|
|
267
|
+
// Link to project so CLI targets the right one
|
|
268
|
+
await railwayCli(["link", "--project", this.deployment.project], {
|
|
269
|
+
cwd: tmpDir
|
|
270
|
+
});
|
|
271
|
+
return await railwayCli(args, { cwd: tmpDir, timeout: 30_000 });
|
|
272
|
+
}
|
|
273
|
+
catch (e) {
|
|
274
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
275
|
+
throw new Error(`Failed to fetch Railway logs: ${msg}`);
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
await fs.rm(tmpDir, { recursive: true, force: true }).catch((err) => {
|
|
279
|
+
log.debug(`Failed to clean up Railway temp dir ${tmpDir}`, err);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=railway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"railway.js","sourceRoot":"","sources":["../src/railway.ts"],"names":[],"mappings":"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"}
|