create-asaje-go-vue 0.2.2 → 0.2.4
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/README.md +3 -1
- package/bin/create-asaje-go-vue.js +309 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,7 +95,9 @@ npx -p create-asaje-go-vue@latest asaje sync-railway-env ./my-app --dry-run
|
|
|
95
95
|
- checks that the Railway CLI is installed and authenticated
|
|
96
96
|
- reads the linked Railway project context
|
|
97
97
|
- provisions PostgreSQL, RabbitMQ, and S3-compatible object storage on Railway
|
|
98
|
-
-
|
|
98
|
+
- creates missing Railway app services for `api`, `realtime-gateway`, and `admin`
|
|
99
|
+
- wires Railway variables for `api`, `realtime-gateway`, and `admin`
|
|
100
|
+
- triggers the first Railway deployment for each app service using the service-local `Dockerfile` and `railway.json`
|
|
99
101
|
- generates missing app secrets such as `JWT_SECRET` and `SWAGGER_PASSWORD`, while reusing existing Railway values when present
|
|
100
102
|
- supports `--dry-run` to preview provisioning and variable changes without applying them
|
|
101
103
|
- writes an `asaje.railway.json` manifest in the target project for future runs, including discovered Railway app service names
|
|
@@ -24,6 +24,28 @@ const EXCLUDED_TEMPLATE_PATHS = ["cli"];
|
|
|
24
24
|
const RAILWAY_GRAPHQL_ENDPOINT = "https://backboard.railway.com/graphql/v2";
|
|
25
25
|
const RAILWAY_MANIFEST_FILENAME = "asaje.railway.json";
|
|
26
26
|
const DEFAULT_RAILWAY_BUCKET = "boilerplate-files";
|
|
27
|
+
const RAILWAY_SERVICE_DISCOVERY_RETRY_DELAY_MS = 2000;
|
|
28
|
+
const RAILWAY_SERVICE_DISCOVERY_RETRY_COUNT = 5;
|
|
29
|
+
const RAILWAY_APP_SERVICE_SPECS = [
|
|
30
|
+
{
|
|
31
|
+
aliases: ["api", "backend", "server"],
|
|
32
|
+
directory: "api",
|
|
33
|
+
key: "api",
|
|
34
|
+
serviceName: "api",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
aliases: ["admin", "frontend", "web"],
|
|
38
|
+
directory: "admin",
|
|
39
|
+
key: "admin",
|
|
40
|
+
serviceName: "admin",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
aliases: ["realtime-gateway", "realtime"],
|
|
44
|
+
directory: "realtime-gateway",
|
|
45
|
+
key: "realtime",
|
|
46
|
+
serviceName: "realtime-gateway",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
27
49
|
const ENV_FILE_SPECS = [
|
|
28
50
|
{ envPath: "admin/.env", examplePath: "admin/.env.example" },
|
|
29
51
|
{ envPath: "api/.env", examplePath: "api/.env.example" },
|
|
@@ -897,13 +919,16 @@ async function runSetupRailway(argv) {
|
|
|
897
919
|
await ensureProjectStructure(projectDir);
|
|
898
920
|
await ensureRailwayCliInstalled();
|
|
899
921
|
await ensureRailwayAuthenticated(projectDir, answers.environment);
|
|
922
|
+
await ensureRailwayEnvironmentLinked(projectDir, answers.environment);
|
|
900
923
|
|
|
901
924
|
const manifest = await readRailwayManifest(projectDir);
|
|
902
925
|
manifest.resources ||= {};
|
|
903
926
|
const railwayContext = await loadRailwayContext(projectDir, answers.environment);
|
|
904
927
|
railwayContext.environmentRef = answers.environment || railwayContext.environmentId || railwayContext.environmentName;
|
|
905
928
|
const existingServices = await discoverRailwayServices(railwayContext, projectDir);
|
|
906
|
-
const
|
|
929
|
+
const resourceSummary = [];
|
|
930
|
+
const appServiceSummary = [];
|
|
931
|
+
const deploySummary = [];
|
|
907
932
|
const variableSummary = [];
|
|
908
933
|
|
|
909
934
|
console.log(pc.bold("\nProvisioning"));
|
|
@@ -918,11 +943,11 @@ async function runSetupRailway(argv) {
|
|
|
918
943
|
projectDir,
|
|
919
944
|
railwayContext,
|
|
920
945
|
});
|
|
921
|
-
|
|
946
|
+
resourceSummary.push(postgresResult);
|
|
922
947
|
|
|
923
948
|
const rabbitMqResult = await ensureRailwayResource({
|
|
924
949
|
aliases: ["rabbitmq"],
|
|
925
|
-
commandArgs: ["deploy", "--template", "
|
|
950
|
+
commandArgs: ["deploy", "--template", "RabbitMQ"],
|
|
926
951
|
dryRun: answers.dryRun,
|
|
927
952
|
existingServices,
|
|
928
953
|
key: "rabbitmq",
|
|
@@ -930,7 +955,7 @@ async function runSetupRailway(argv) {
|
|
|
930
955
|
projectDir,
|
|
931
956
|
railwayContext,
|
|
932
957
|
});
|
|
933
|
-
|
|
958
|
+
resourceSummary.push(rabbitMqResult);
|
|
934
959
|
|
|
935
960
|
const objectStorageResult = await ensureRailwayResource({
|
|
936
961
|
aliases: ["object-storage", "storage", "simple-s3", "minio"],
|
|
@@ -949,10 +974,25 @@ async function runSetupRailway(argv) {
|
|
|
949
974
|
projectDir,
|
|
950
975
|
railwayContext,
|
|
951
976
|
});
|
|
952
|
-
|
|
977
|
+
resourceSummary.push(objectStorageResult);
|
|
953
978
|
|
|
954
|
-
|
|
979
|
+
console.log(pc.bold("\nApplication services"));
|
|
955
980
|
manifest.appServices ||= {};
|
|
981
|
+
for (const spec of RAILWAY_APP_SERVICE_SPECS) {
|
|
982
|
+
const serviceResult = await ensureRailwayAppService({
|
|
983
|
+
aliases: spec.aliases,
|
|
984
|
+
dryRun: answers.dryRun,
|
|
985
|
+
existingServices,
|
|
986
|
+
key: spec.key,
|
|
987
|
+
manifest,
|
|
988
|
+
projectDir,
|
|
989
|
+
railwayContext,
|
|
990
|
+
serviceName: spec.serviceName,
|
|
991
|
+
});
|
|
992
|
+
appServiceSummary.push(serviceResult);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
manifest.bucket = answers.bucket;
|
|
956
996
|
manifest.environmentId = railwayContext.environmentId || manifest.environmentId || null;
|
|
957
997
|
manifest.environmentName = railwayContext.environmentName || manifest.environmentName || null;
|
|
958
998
|
manifest.projectId = railwayContext.projectId || manifest.projectId || null;
|
|
@@ -969,11 +1009,28 @@ async function runSetupRailway(argv) {
|
|
|
969
1009
|
services: servicesAfterProvision,
|
|
970
1010
|
summary: variableSummary,
|
|
971
1011
|
});
|
|
1012
|
+
const deploymentResults = await deployRailwayAppServices({
|
|
1013
|
+
dryRun: answers.dryRun,
|
|
1014
|
+
manifest,
|
|
1015
|
+
projectDir,
|
|
1016
|
+
railwayContext,
|
|
1017
|
+
services: servicesAfterProvision,
|
|
1018
|
+
});
|
|
1019
|
+
deploySummary.push(...deploymentResults);
|
|
972
1020
|
|
|
973
1021
|
if (!answers.dryRun) {
|
|
974
1022
|
await writeRailwayManifest(projectDir, manifest);
|
|
975
1023
|
}
|
|
976
|
-
printRailwaySetupSummary(
|
|
1024
|
+
printRailwaySetupSummary({
|
|
1025
|
+
appServiceSummary,
|
|
1026
|
+
bucket: answers.bucket,
|
|
1027
|
+
deploySummary,
|
|
1028
|
+
dryRun: answers.dryRun,
|
|
1029
|
+
projectDir,
|
|
1030
|
+
railwayContext,
|
|
1031
|
+
resourceSummary,
|
|
1032
|
+
variableSummary,
|
|
1033
|
+
});
|
|
977
1034
|
}
|
|
978
1035
|
|
|
979
1036
|
async function runSyncRailwayEnv(argv) {
|
|
@@ -984,6 +1041,7 @@ async function runSyncRailwayEnv(argv) {
|
|
|
984
1041
|
await ensureProjectStructure(projectDir);
|
|
985
1042
|
await ensureRailwayCliInstalled();
|
|
986
1043
|
await ensureRailwayAuthenticated(projectDir, answers.environment);
|
|
1044
|
+
await ensureRailwayEnvironmentLinked(projectDir, answers.environment);
|
|
987
1045
|
|
|
988
1046
|
const manifest = await readRailwayManifest(projectDir);
|
|
989
1047
|
manifest.resources ||= {};
|
|
@@ -1015,14 +1073,16 @@ async function runSyncRailwayEnv(argv) {
|
|
|
1015
1073
|
await writeRailwayManifest(projectDir, manifest);
|
|
1016
1074
|
}
|
|
1017
1075
|
|
|
1018
|
-
printRailwaySetupSummary(
|
|
1076
|
+
printRailwaySetupSummary({
|
|
1077
|
+
appServiceSummary: [],
|
|
1078
|
+
bucket: manifest.bucket || answers.bucket,
|
|
1079
|
+
deploySummary: [],
|
|
1080
|
+
dryRun: answers.dryRun,
|
|
1019
1081
|
projectDir,
|
|
1020
1082
|
railwayContext,
|
|
1021
|
-
[],
|
|
1083
|
+
resourceSummary: [],
|
|
1022
1084
|
variableSummary,
|
|
1023
|
-
|
|
1024
|
-
answers.dryRun,
|
|
1025
|
-
);
|
|
1085
|
+
});
|
|
1026
1086
|
}
|
|
1027
1087
|
|
|
1028
1088
|
function parseDirectoryArgs(argv) {
|
|
@@ -1154,6 +1214,21 @@ async function ensureRailwayAuthenticated(projectDir, environment) {
|
|
|
1154
1214
|
}
|
|
1155
1215
|
}
|
|
1156
1216
|
|
|
1217
|
+
async function ensureRailwayEnvironmentLinked(projectDir, environment) {
|
|
1218
|
+
if (!environment) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
const result = await execa("railway", ["environment", "link", environment], {
|
|
1223
|
+
cwd: projectDir,
|
|
1224
|
+
reject: false,
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
if (result.exitCode !== 0) {
|
|
1228
|
+
throw new Error(`Unable to link Railway environment ${environment}. Make sure it exists and try again.`);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1157
1232
|
async function readRailwayManifest(projectDir) {
|
|
1158
1233
|
const manifestPath = path.join(projectDir, RAILWAY_MANIFEST_FILENAME);
|
|
1159
1234
|
if (!(await fs.pathExists(manifestPath))) {
|
|
@@ -1344,35 +1419,136 @@ async function ensureRailwayResource(config) {
|
|
|
1344
1419
|
}
|
|
1345
1420
|
|
|
1346
1421
|
if (manifestEntry?.status === "created" || manifestEntry?.status === "existing") {
|
|
1347
|
-
console.log(`- ${pc.
|
|
1348
|
-
return {
|
|
1349
|
-
key: config.key,
|
|
1350
|
-
serviceName: manifestEntry.serviceName || null,
|
|
1351
|
-
status: "tracked",
|
|
1352
|
-
};
|
|
1422
|
+
console.log(`- ${pc.yellow(config.key)} tracked in ${RAILWAY_MANIFEST_FILENAME} but not found remotely, recreating...`);
|
|
1353
1423
|
}
|
|
1354
1424
|
|
|
1355
1425
|
console.log(`- creating ${pc.cyan(config.key)}...`);
|
|
1426
|
+
const servicesBefore = normalizeRailwayServices(config.existingServices);
|
|
1356
1427
|
if (!config.dryRun) {
|
|
1357
1428
|
await runRailwayCommand(config.projectDir, config.railwayContext.environmentRef, config.commandArgs);
|
|
1358
1429
|
}
|
|
1359
1430
|
|
|
1431
|
+
let createdService = null;
|
|
1432
|
+
if (!config.dryRun) {
|
|
1433
|
+
createdService = await waitForCreatedRailwayService({
|
|
1434
|
+
aliases: config.aliases,
|
|
1435
|
+
beforeServices: servicesBefore,
|
|
1436
|
+
key: config.key,
|
|
1437
|
+
manifestEntry,
|
|
1438
|
+
projectDir: config.projectDir,
|
|
1439
|
+
railwayContext: config.railwayContext,
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1360
1443
|
config.manifest.resources[config.key] = {
|
|
1361
1444
|
bucket: config.metadata?.bucket || null,
|
|
1362
1445
|
detectedAt: new Date().toISOString(),
|
|
1363
|
-
serviceId: null,
|
|
1364
|
-
serviceName: null,
|
|
1446
|
+
serviceId: createdService?.id || null,
|
|
1447
|
+
serviceName: createdService?.name || null,
|
|
1365
1448
|
source: "cli",
|
|
1366
1449
|
status: "created",
|
|
1367
1450
|
};
|
|
1368
1451
|
|
|
1369
1452
|
return {
|
|
1370
1453
|
key: config.key,
|
|
1371
|
-
serviceName: null,
|
|
1454
|
+
serviceName: createdService?.name || null,
|
|
1372
1455
|
status: config.dryRun ? "dry-run" : "created",
|
|
1373
1456
|
};
|
|
1374
1457
|
}
|
|
1375
1458
|
|
|
1459
|
+
async function ensureRailwayAppService(config) {
|
|
1460
|
+
const manifestEntry = config.manifest.appServices?.[config.key];
|
|
1461
|
+
const existingService = findRailwayService(
|
|
1462
|
+
config.existingServices,
|
|
1463
|
+
config.aliases,
|
|
1464
|
+
manifestEntry?.serviceName || config.serviceName,
|
|
1465
|
+
);
|
|
1466
|
+
|
|
1467
|
+
if (existingService) {
|
|
1468
|
+
config.manifest.appServices[config.key] = {
|
|
1469
|
+
serviceId: existingService.id || manifestEntry?.serviceId || null,
|
|
1470
|
+
serviceName: existingService.name || manifestEntry?.serviceName || config.serviceName,
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
console.log(`- ${pc.cyan(config.serviceName)} already present${existingService.name ? ` (${existingService.name})` : ""}`);
|
|
1474
|
+
return {
|
|
1475
|
+
key: config.serviceName,
|
|
1476
|
+
serviceName: existingService.name || config.serviceName,
|
|
1477
|
+
status: "existing",
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
if (manifestEntry?.serviceName) {
|
|
1482
|
+
console.log(`- ${pc.yellow(config.serviceName)} tracked in ${RAILWAY_MANIFEST_FILENAME} but not found remotely, recreating...`);
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
console.log(`- creating ${pc.cyan(config.serviceName)} service...`);
|
|
1486
|
+
const servicesBefore = normalizeRailwayServices(config.existingServices);
|
|
1487
|
+
if (!config.dryRun) {
|
|
1488
|
+
await runRailwayCommand(config.projectDir, config.railwayContext.environmentRef, ["add", "--service", config.serviceName]);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
let createdService = null;
|
|
1492
|
+
if (!config.dryRun) {
|
|
1493
|
+
createdService = await waitForCreatedRailwayService({
|
|
1494
|
+
aliases: config.aliases,
|
|
1495
|
+
beforeServices: servicesBefore,
|
|
1496
|
+
key: config.serviceName,
|
|
1497
|
+
manifestEntry,
|
|
1498
|
+
projectDir: config.projectDir,
|
|
1499
|
+
railwayContext: config.railwayContext,
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
config.manifest.appServices[config.key] = {
|
|
1504
|
+
serviceId: createdService?.id || null,
|
|
1505
|
+
serviceName: createdService?.name || config.serviceName,
|
|
1506
|
+
};
|
|
1507
|
+
|
|
1508
|
+
return {
|
|
1509
|
+
key: config.serviceName,
|
|
1510
|
+
serviceName: createdService?.name || config.serviceName,
|
|
1511
|
+
status: config.dryRun ? "dry-run" : "created",
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
async function deployRailwayAppServices(config) {
|
|
1516
|
+
console.log(pc.bold("\nDeployments"));
|
|
1517
|
+
|
|
1518
|
+
const summary = [];
|
|
1519
|
+
for (const spec of RAILWAY_APP_SERVICE_SPECS) {
|
|
1520
|
+
const manifestEntry = config.manifest.appServices?.[spec.key];
|
|
1521
|
+
const service = findRailwayService(config.services, spec.aliases, manifestEntry?.serviceName || spec.serviceName);
|
|
1522
|
+
const targetServiceName = service?.name || manifestEntry?.serviceName || spec.serviceName;
|
|
1523
|
+
|
|
1524
|
+
if (!service && !config.dryRun) {
|
|
1525
|
+
console.log(`- ${pc.yellow(spec.serviceName)} service not found, skipping deployment`);
|
|
1526
|
+
continue;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
if (config.dryRun) {
|
|
1530
|
+
console.log(`- would deploy ${pc.cyan(targetServiceName)} from ${spec.directory}/`);
|
|
1531
|
+
summary.push({ directory: spec.directory, serviceName: targetServiceName, status: "dry-run" });
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
console.log(`- deploying ${pc.cyan(targetServiceName)} from ${spec.directory}/...`);
|
|
1536
|
+
await runRailwayCommand(config.projectDir, config.railwayContext.environmentRef, [
|
|
1537
|
+
"up",
|
|
1538
|
+
spec.directory,
|
|
1539
|
+
"--service",
|
|
1540
|
+
targetServiceName,
|
|
1541
|
+
"--path-as-root",
|
|
1542
|
+
"--detach",
|
|
1543
|
+
"--message",
|
|
1544
|
+
`asaje setup-railway: deploy ${targetServiceName}`,
|
|
1545
|
+
]);
|
|
1546
|
+
summary.push({ directory: spec.directory, serviceName: targetServiceName, status: "deployed" });
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
return summary;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1376
1552
|
async function wireRailwayVariables(config) {
|
|
1377
1553
|
console.log(pc.bold("\nVariables"));
|
|
1378
1554
|
|
|
@@ -1416,6 +1592,15 @@ async function wireRailwayVariables(config) {
|
|
|
1416
1592
|
if (!appServices.admin) {
|
|
1417
1593
|
console.log(`- ${pc.yellow("admin")} service not found, skipping admin variable wiring`);
|
|
1418
1594
|
}
|
|
1595
|
+
if (!infra.postgres) {
|
|
1596
|
+
console.log(`- ${pc.yellow("postgres")} resource not found, DATABASE_URL wiring will be skipped`);
|
|
1597
|
+
}
|
|
1598
|
+
if (!infra.rabbitmq) {
|
|
1599
|
+
console.log(`- ${pc.yellow("rabbitmq")} resource not found, RABBITMQ_URL wiring will be skipped`);
|
|
1600
|
+
}
|
|
1601
|
+
if (!infra.objectStorage) {
|
|
1602
|
+
console.log(`- ${pc.yellow("object-storage")} resource not found, S3 variable wiring will be skipped`);
|
|
1603
|
+
}
|
|
1419
1604
|
|
|
1420
1605
|
if (appServices.api) {
|
|
1421
1606
|
const existingApiVariables = await loadRailwayServiceVariables(
|
|
@@ -1648,6 +1833,30 @@ async function loadRailwayServiceVariables(projectDir, environment, serviceName)
|
|
|
1648
1833
|
}
|
|
1649
1834
|
}
|
|
1650
1835
|
|
|
1836
|
+
async function waitForCreatedRailwayService(config) {
|
|
1837
|
+
for (let attempt = 0; attempt < RAILWAY_SERVICE_DISCOVERY_RETRY_COUNT; attempt += 1) {
|
|
1838
|
+
const servicesAfter = await discoverRailwayServices(config.railwayContext, config.projectDir);
|
|
1839
|
+
const createdService = findCreatedRailwayService({
|
|
1840
|
+
aliases: config.aliases,
|
|
1841
|
+
beforeServices: config.beforeServices,
|
|
1842
|
+
manifestServiceName: config.manifestEntry?.serviceName,
|
|
1843
|
+
servicesAfter,
|
|
1844
|
+
});
|
|
1845
|
+
|
|
1846
|
+
if (createdService) {
|
|
1847
|
+
return createdService;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
if (attempt < RAILWAY_SERVICE_DISCOVERY_RETRY_COUNT - 1) {
|
|
1851
|
+
await sleep(RAILWAY_SERVICE_DISCOVERY_RETRY_DELAY_MS);
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
throw new Error(
|
|
1856
|
+
`Railway command for ${config.key} finished but the new service was not detected afterwards. Check the Railway dashboard/logs, then rerun \`asaje setup-railway\` or \`asaje sync-railway-env\` once the service appears.`,
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1651
1860
|
function findRailwayService(services, aliases, preferredName) {
|
|
1652
1861
|
if (preferredName) {
|
|
1653
1862
|
const exact = services.find(
|
|
@@ -1696,6 +1905,32 @@ function normalizeRailwayServices(services) {
|
|
|
1696
1905
|
return normalized;
|
|
1697
1906
|
}
|
|
1698
1907
|
|
|
1908
|
+
function findCreatedRailwayService(config) {
|
|
1909
|
+
const beforeServices = normalizeRailwayServices(config.beforeServices);
|
|
1910
|
+
const afterServices = normalizeRailwayServices(config.servicesAfter);
|
|
1911
|
+
const beforeKeys = new Set(beforeServices.map(createRailwayServiceIdentity));
|
|
1912
|
+
const newServices = afterServices.filter((service) => !beforeKeys.has(createRailwayServiceIdentity(service)));
|
|
1913
|
+
|
|
1914
|
+
if (newServices.length === 1) {
|
|
1915
|
+
return newServices[0];
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
const aliasMatch = findRailwayService(newServices, config.aliases, config.manifestServiceName);
|
|
1919
|
+
if (aliasMatch) {
|
|
1920
|
+
return aliasMatch;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1923
|
+
return null;
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
function createRailwayServiceIdentity(service) {
|
|
1927
|
+
if (service?.id) {
|
|
1928
|
+
return `id:${service.id}`;
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
return `name:${normalizeRailwayServiceName(service?.name)}`;
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1699
1934
|
function normalizeRailwayVariables(input) {
|
|
1700
1935
|
const normalized = {};
|
|
1701
1936
|
|
|
@@ -1778,6 +2013,12 @@ function visitRailwayJson(input, visitor) {
|
|
|
1778
2013
|
}
|
|
1779
2014
|
}
|
|
1780
2015
|
|
|
2016
|
+
function sleep(delayMs) {
|
|
2017
|
+
return new Promise((resolve) => {
|
|
2018
|
+
setTimeout(resolve, delayMs);
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
|
|
1781
2022
|
async function runRailwayCommand(projectDir, environment, args) {
|
|
1782
2023
|
const result = await execa("railway", buildRailwayArgs(args, environment), {
|
|
1783
2024
|
cwd: projectDir,
|
|
@@ -1796,6 +2037,17 @@ function buildRailwayArgs(args, environment) {
|
|
|
1796
2037
|
return args;
|
|
1797
2038
|
}
|
|
1798
2039
|
|
|
2040
|
+
const commandKey = args.slice(0, 2).join(" ");
|
|
2041
|
+
const supportsEnvironmentFlag =
|
|
2042
|
+
commandKey === "service status" ||
|
|
2043
|
+
commandKey === "variable list" ||
|
|
2044
|
+
commandKey === "variable set" ||
|
|
2045
|
+
args[0] === "up";
|
|
2046
|
+
|
|
2047
|
+
if (!supportsEnvironmentFlag) {
|
|
2048
|
+
return args;
|
|
2049
|
+
}
|
|
2050
|
+
|
|
1799
2051
|
return [...args, "--environment", environment];
|
|
1800
2052
|
}
|
|
1801
2053
|
|
|
@@ -1840,33 +2092,56 @@ function findFirstNestedValue(input, key) {
|
|
|
1840
2092
|
return null;
|
|
1841
2093
|
}
|
|
1842
2094
|
|
|
1843
|
-
function printRailwaySetupSummary(
|
|
2095
|
+
function printRailwaySetupSummary(config) {
|
|
1844
2096
|
console.log(pc.bold("\nRailway"));
|
|
1845
|
-
console.log(`- Directory: ${pc.bold(projectDir)}`);
|
|
1846
|
-
if (railwayContext.projectName || railwayContext.projectId) {
|
|
1847
|
-
console.log(`- Project: ${pc.bold(railwayContext.projectName || railwayContext.projectId)}`);
|
|
2097
|
+
console.log(`- Directory: ${pc.bold(config.projectDir)}`);
|
|
2098
|
+
if (config.railwayContext.projectName || config.railwayContext.projectId) {
|
|
2099
|
+
console.log(`- Project: ${pc.bold(config.railwayContext.projectName || config.railwayContext.projectId)}`);
|
|
1848
2100
|
}
|
|
1849
|
-
if (railwayContext.environmentName || railwayContext.environmentId) {
|
|
1850
|
-
console.log(`- Environment: ${pc.bold(railwayContext.environmentName || railwayContext.environmentId)}`);
|
|
2101
|
+
if (config.railwayContext.environmentName || config.railwayContext.environmentId) {
|
|
2102
|
+
console.log(`- Environment: ${pc.bold(config.railwayContext.environmentName || config.railwayContext.environmentId)}`);
|
|
1851
2103
|
}
|
|
1852
|
-
console.log(`- Bucket: ${pc.bold(bucket)}`);
|
|
2104
|
+
console.log(`- Bucket: ${pc.bold(config.bucket)}`);
|
|
1853
2105
|
|
|
1854
2106
|
console.log(pc.bold("\nResources"));
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
2107
|
+
if (config.resourceSummary.length === 0) {
|
|
2108
|
+
console.log("- No infrastructure resources were changed");
|
|
2109
|
+
} else {
|
|
2110
|
+
for (const item of config.resourceSummary) {
|
|
2111
|
+
const detail = item.serviceName ? ` (${item.serviceName})` : "";
|
|
2112
|
+
console.log(`- ${pc.bold(item.key)}: ${item.status}${detail}`);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
console.log(pc.bold("\nApplication services"));
|
|
2117
|
+
if (config.appServiceSummary.length === 0) {
|
|
2118
|
+
console.log("- No application services were changed");
|
|
2119
|
+
} else {
|
|
2120
|
+
for (const item of config.appServiceSummary) {
|
|
2121
|
+
const detail = item.serviceName ? ` (${item.serviceName})` : "";
|
|
2122
|
+
console.log(`- ${pc.bold(item.key)}: ${item.status}${detail}`);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
console.log(pc.bold("\nDeployments"));
|
|
2127
|
+
if (config.deploySummary.length === 0) {
|
|
2128
|
+
console.log("- No application deployments were triggered");
|
|
2129
|
+
} else {
|
|
2130
|
+
for (const item of config.deploySummary) {
|
|
2131
|
+
console.log(`- ${pc.bold(item.serviceName)}: ${item.status} from ${item.directory}/`);
|
|
2132
|
+
}
|
|
1858
2133
|
}
|
|
1859
2134
|
|
|
1860
2135
|
console.log(pc.bold("\nVariables"));
|
|
1861
|
-
if (variableSummary.length === 0) {
|
|
2136
|
+
if (config.variableSummary.length === 0) {
|
|
1862
2137
|
console.log("- No application variables were updated");
|
|
1863
2138
|
} else {
|
|
1864
|
-
for (const item of variableSummary) {
|
|
2139
|
+
for (const item of config.variableSummary) {
|
|
1865
2140
|
console.log(`- ${pc.bold(item.serviceName)}: ${item.status} ${item.keys.join(", ")}`);
|
|
1866
2141
|
}
|
|
1867
2142
|
}
|
|
1868
2143
|
|
|
1869
|
-
if (dryRun) {
|
|
2144
|
+
if (config.dryRun) {
|
|
1870
2145
|
console.log(`- Dry run only, ${pc.bold(RAILWAY_MANIFEST_FILENAME)} was not written`);
|
|
1871
2146
|
} else {
|
|
1872
2147
|
console.log(`- Manifest written to ${pc.bold(RAILWAY_MANIFEST_FILENAME)} for future runs`);
|