@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.
Files changed (133) hide show
  1. package/dist/admin-client.d.ts +58 -0
  2. package/dist/admin-client.d.ts.map +1 -0
  3. package/dist/admin-client.js +275 -0
  4. package/dist/admin-client.js.map +1 -0
  5. package/dist/admin-operations.d.ts +197 -0
  6. package/dist/admin-operations.d.ts.map +1 -0
  7. package/dist/admin-operations.js +433 -0
  8. package/dist/admin-operations.js.map +1 -0
  9. package/dist/admin-routes.d.ts +306 -0
  10. package/dist/admin-routes.d.ts.map +1 -0
  11. package/dist/admin-routes.js +383 -0
  12. package/dist/admin-routes.js.map +1 -0
  13. package/dist/api-user-manager.d.ts +72 -0
  14. package/dist/api-user-manager.d.ts.map +1 -0
  15. package/dist/api-user-manager.js +89 -0
  16. package/dist/api-user-manager.js.map +1 -0
  17. package/dist/auth.d.ts +67 -0
  18. package/dist/auth.d.ts.map +1 -0
  19. package/dist/auth.js +142 -0
  20. package/dist/auth.js.map +1 -0
  21. package/dist/collection-routes.d.ts +37 -0
  22. package/dist/collection-routes.d.ts.map +1 -0
  23. package/dist/collection-routes.js +43 -0
  24. package/dist/collection-routes.js.map +1 -0
  25. package/dist/compose.d.ts +52 -0
  26. package/dist/compose.d.ts.map +1 -0
  27. package/dist/compose.js +153 -0
  28. package/dist/compose.js.map +1 -0
  29. package/dist/configure.d.ts +87 -0
  30. package/dist/configure.d.ts.map +1 -0
  31. package/dist/configure.js +104 -0
  32. package/dist/configure.js.map +1 -0
  33. package/dist/deploy-to-gcp.d.ts +67 -0
  34. package/dist/deploy-to-gcp.d.ts.map +1 -0
  35. package/dist/deploy-to-gcp.js +268 -0
  36. package/dist/deploy-to-gcp.js.map +1 -0
  37. package/dist/deploy-to-runpod.d.ts +53 -0
  38. package/dist/deploy-to-runpod.d.ts.map +1 -0
  39. package/dist/deploy-to-runpod.js +207 -0
  40. package/dist/deploy-to-runpod.js.map +1 -0
  41. package/dist/deploy.d.ts +54 -0
  42. package/dist/deploy.d.ts.map +1 -0
  43. package/dist/deploy.js +82 -0
  44. package/dist/deploy.js.map +1 -0
  45. package/dist/deployment-config.d.ts +1073 -0
  46. package/dist/deployment-config.d.ts.map +1 -0
  47. package/dist/deployment-config.js +536 -0
  48. package/dist/deployment-config.js.map +1 -0
  49. package/dist/docker-run.d.ts +85 -0
  50. package/dist/docker-run.d.ts.map +1 -0
  51. package/dist/docker-run.js +202 -0
  52. package/dist/docker-run.js.map +1 -0
  53. package/dist/docker.d.ts +98 -0
  54. package/dist/docker.d.ts.map +1 -0
  55. package/dist/docker.js +396 -0
  56. package/dist/docker.js.map +1 -0
  57. package/dist/fly.d.ts +40 -0
  58. package/dist/fly.d.ts.map +1 -0
  59. package/dist/fly.js +291 -0
  60. package/dist/fly.js.map +1 -0
  61. package/dist/gcp.d.ts +59 -0
  62. package/dist/gcp.d.ts.map +1 -0
  63. package/dist/gcp.js +339 -0
  64. package/dist/gcp.js.map +1 -0
  65. package/dist/google-cloud-run-api.d.ts +134 -0
  66. package/dist/google-cloud-run-api.d.ts.map +1 -0
  67. package/dist/google-cloud-run-api.js +532 -0
  68. package/dist/google-cloud-run-api.js.map +1 -0
  69. package/dist/huggingface.d.ts +69 -0
  70. package/dist/huggingface.d.ts.map +1 -0
  71. package/dist/huggingface.js +346 -0
  72. package/dist/huggingface.js.map +1 -0
  73. package/dist/image-builder.d.ts +35 -0
  74. package/dist/image-builder.d.ts.map +1 -0
  75. package/dist/image-builder.js +157 -0
  76. package/dist/image-builder.js.map +1 -0
  77. package/dist/image-spec.d.ts +41 -0
  78. package/dist/image-spec.d.ts.map +1 -0
  79. package/dist/image-spec.js +49 -0
  80. package/dist/image-spec.js.map +1 -0
  81. package/dist/index.d.ts +33 -0
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +45 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/manager.d.ts +121 -0
  86. package/dist/manager.d.ts.map +1 -0
  87. package/dist/manager.js +225 -0
  88. package/dist/manager.js.map +1 -0
  89. package/dist/progress.d.ts +91 -0
  90. package/dist/progress.d.ts.map +1 -0
  91. package/dist/progress.js +262 -0
  92. package/dist/progress.js.map +1 -0
  93. package/dist/railway.d.ts +65 -0
  94. package/dist/railway.d.ts.map +1 -0
  95. package/dist/railway.js +284 -0
  96. package/dist/railway.js.map +1 -0
  97. package/dist/remote-users.d.ts +74 -0
  98. package/dist/remote-users.d.ts.map +1 -0
  99. package/dist/remote-users.js +172 -0
  100. package/dist/remote-users.js.map +1 -0
  101. package/dist/runpod-api.d.ts +206 -0
  102. package/dist/runpod-api.d.ts.map +1 -0
  103. package/dist/runpod-api.js +703 -0
  104. package/dist/runpod-api.js.map +1 -0
  105. package/dist/runpod.d.ts +82 -0
  106. package/dist/runpod.d.ts.map +1 -0
  107. package/dist/runpod.js +188 -0
  108. package/dist/runpod.js.map +1 -0
  109. package/dist/self-hosted.d.ts +157 -0
  110. package/dist/self-hosted.d.ts.map +1 -0
  111. package/dist/self-hosted.js +799 -0
  112. package/dist/self-hosted.js.map +1 -0
  113. package/dist/ssh.d.ts +166 -0
  114. package/dist/ssh.d.ts.map +1 -0
  115. package/dist/ssh.js +430 -0
  116. package/dist/ssh.js.map +1 -0
  117. package/dist/state.d.ts +83 -0
  118. package/dist/state.d.ts.map +1 -0
  119. package/dist/state.js +368 -0
  120. package/dist/state.js.map +1 -0
  121. package/dist/storage-routes.d.ts +55 -0
  122. package/dist/storage-routes.d.ts.map +1 -0
  123. package/dist/storage-routes.js +160 -0
  124. package/dist/storage-routes.js.map +1 -0
  125. package/dist/sync.d.ts +38 -0
  126. package/dist/sync.d.ts.map +1 -0
  127. package/dist/sync.js +130 -0
  128. package/dist/sync.js.map +1 -0
  129. package/dist/workflow-syncer.d.ts +51 -0
  130. package/dist/workflow-syncer.d.ts.map +1 -0
  131. package/dist/workflow-syncer.js +192 -0
  132. package/dist/workflow-syncer.js.map +1 -0
  133. package/package.json +58 -0
@@ -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"}
@@ -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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"}