Files
blackroad-operating-system/scripts/deployService.ts
Alexa Amundson 40341c3e0c fix: resolve TypeScript and pip build errors
- tsconfig.json: remove duplicate target, add missing comma
- requirements.txt: fix boto3/botocore version conflict
- deployAll.ts, deployService.ts: remove duplicate concatenated code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

RoadChain-SHA2048: f3e2c6a6f3c323b4
RoadChain-Identity: alexa@sovereign
RoadChain-Full: f3e2c6a6f3c323b4d200ae278824975d0b102ec0ee1708560ccae57bf0f31819f19805317aa33b967b58b06750443394fafd250e40985dc35d2d89c12f369ef2083bcd4b0496043e87bfa1ef7ec7d307065d63190fa31461367dc3f2d76410326c1bd9602aac1587084f3d7ec068b6abffb94ff1bf18ce5408a4cd7523ff9a078c60c6f0050434c562b18b9f9ac81af72a23590e6d8e2ed79ea7de61cf2b9a1e1e44051ee2a151cb0c57f23b04db771944889473eb0ec2bf5d42bbd3727422c6e28987af96fb6006ee55604dfbded15a70cbe196da844945f373d838d446f33c0465e463f244992bc506e4ca6b414cc8b935e7d5fe993297444805dddb9af436
2026-03-10 20:54:56 -05:00

87 lines
2.3 KiB
TypeScript

import { spawn } from "child_process";
import fs from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
import { ServiceConfig } from "./types.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const rootDir = path.resolve(__dirname, "..", "");
const servicesPath = path.join(rootDir, "infra", "services.json");
async function loadServices(): Promise<ServiceConfig[]> {
const data = await fs.readFile(servicesPath, "utf-8");
return JSON.parse(data) as ServiceConfig[];
}
function runRailwayDeploy(service: ServiceConfig): Promise<number> {
return new Promise((resolve, reject) => {
const args = [
"up",
"--project",
service.railwayProject,
"--service",
service.railwayService,
];
console.log(`\n🚀 Deploying ${service.name} (${service.id})`);
console.log(` Command: railway ${args.join(" ")}`);
const child = spawn("railway", args, {
stdio: "inherit",
shell: process.platform === "win32",
env: {
...process.env,
NODE_ENV: process.env.NODE_ENV ?? "production",
},
});
child.on("error", (error) => {
reject(error);
});
child.on("close", (code) => {
if (code === null) {
reject(new Error("Railway command terminated unexpectedly"));
return;
}
console.log(`✅ Finished ${service.id} with exit code ${code}`);
resolve(code);
});
});
}
export async function deployServiceById(serviceId: string): Promise<void> {
const services = await loadServices();
const service = services.find((entry) => entry.id === serviceId);
if (!service) {
console.error(`Service with id "${serviceId}" not found.`);
console.error("Available service ids:", services.map((s) => s.id).join(", "));
process.exitCode = 1;
return;
}
try {
const exitCode = await runRailwayDeploy(service);
if (exitCode !== 0) {
process.exitCode = exitCode;
}
} catch (error) {
console.error(`Deployment failed for ${serviceId}:`, error);
process.exitCode = 1;
}
}
async function main(): Promise<void> {
const serviceId = process.argv[2];
if (!serviceId) {
console.error("Usage: ts-node deployService.ts <serviceId>");
process.exit(1);
}
await deployServiceById(serviceId);
}
main();