@tachyon-gg/railway-deploy 0.1.0 → 0.2.1
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 +5 -6
- package/dist/index.js +90 -44
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -158,7 +158,6 @@ domains:
|
|
|
158
158
|
- app.example.com # Simple domain
|
|
159
159
|
- domain: api.example.com # Domain with target port
|
|
160
160
|
target_port: 8080
|
|
161
|
-
domain: simple.example.com # Shorthand for a single domain
|
|
162
161
|
|
|
163
162
|
# Railway-provided domain
|
|
164
163
|
railway_domain: true # Generate a .up.railway.app domain
|
|
@@ -166,8 +165,7 @@ railway_domain: # ...with a specific target port
|
|
|
166
165
|
target_port: 3000
|
|
167
166
|
|
|
168
167
|
# TCP proxies (for non-HTTP services like databases)
|
|
169
|
-
|
|
170
|
-
tcp_proxies: [5432, 6379] # Multiple ports
|
|
168
|
+
tcp_proxies: [5432, 6379] # One or more ports
|
|
171
169
|
|
|
172
170
|
# Outbound networking
|
|
173
171
|
ipv6_egress: true # Enable IPv6 outbound traffic
|
|
@@ -232,7 +230,8 @@ variables:
|
|
|
232
230
|
APP_VERSION: "%{tag}"
|
|
233
231
|
DATABASE_URL: ${{Postgres.DATABASE_URL}}
|
|
234
232
|
|
|
235
|
-
|
|
233
|
+
domains:
|
|
234
|
+
- "%{tag}.example.com"
|
|
236
235
|
|
|
237
236
|
healthcheck:
|
|
238
237
|
path: /health
|
|
@@ -309,7 +308,7 @@ services:
|
|
|
309
308
|
volume:
|
|
310
309
|
mount: /var/lib/postgresql/data
|
|
311
310
|
name: pg-data
|
|
312
|
-
|
|
311
|
+
tcp_proxies: [5432]
|
|
313
312
|
variables:
|
|
314
313
|
POSTGRES_DB: myapp
|
|
315
314
|
|
|
@@ -319,7 +318,7 @@ services:
|
|
|
319
318
|
volume:
|
|
320
319
|
mount: /data
|
|
321
320
|
name: redis-data
|
|
322
|
-
|
|
321
|
+
tcp_proxies: [6379]
|
|
323
322
|
|
|
324
323
|
worker:
|
|
325
324
|
template: ../services/worker.yaml
|
package/dist/index.js
CHANGED
|
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __returnValue = (v) => v;
|
|
35
|
+
function __exportSetter(name, newValue) {
|
|
36
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
+
}
|
|
20
38
|
var __export = (target, all) => {
|
|
21
39
|
for (var name in all)
|
|
22
40
|
__defProp(target, name, {
|
|
23
41
|
get: all[name],
|
|
24
42
|
enumerable: true,
|
|
25
43
|
configurable: true,
|
|
26
|
-
set: (
|
|
44
|
+
set: __exportSetter.bind(all, name)
|
|
27
45
|
});
|
|
28
46
|
};
|
|
29
47
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
@@ -10704,9 +10722,9 @@ var require_instanceOf = __commonJS((exports) => {
|
|
|
10704
10722
|
exports.instanceOf = undefined;
|
|
10705
10723
|
var _inspect = require_inspect();
|
|
10706
10724
|
var isProduction = globalThis.process && false;
|
|
10707
|
-
var instanceOf = isProduction ? function
|
|
10725
|
+
var instanceOf = isProduction ? function instanceOf2(value, constructor) {
|
|
10708
10726
|
return value instanceof constructor;
|
|
10709
|
-
} : function
|
|
10727
|
+
} : function instanceOf2(value, constructor) {
|
|
10710
10728
|
if (value instanceof constructor) {
|
|
10711
10729
|
return true;
|
|
10712
10730
|
}
|
|
@@ -23727,6 +23745,48 @@ var require_graphql2 = __commonJS((exports) => {
|
|
|
23727
23745
|
var _index6 = require_utilities();
|
|
23728
23746
|
});
|
|
23729
23747
|
|
|
23748
|
+
// node_modules/fast-deep-equal/index.js
|
|
23749
|
+
var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
23750
|
+
module.exports = function equal(a, b) {
|
|
23751
|
+
if (a === b)
|
|
23752
|
+
return true;
|
|
23753
|
+
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
23754
|
+
if (a.constructor !== b.constructor)
|
|
23755
|
+
return false;
|
|
23756
|
+
var length, i, keys;
|
|
23757
|
+
if (Array.isArray(a)) {
|
|
23758
|
+
length = a.length;
|
|
23759
|
+
if (length != b.length)
|
|
23760
|
+
return false;
|
|
23761
|
+
for (i = length;i-- !== 0; )
|
|
23762
|
+
if (!equal(a[i], b[i]))
|
|
23763
|
+
return false;
|
|
23764
|
+
return true;
|
|
23765
|
+
}
|
|
23766
|
+
if (a.constructor === RegExp)
|
|
23767
|
+
return a.source === b.source && a.flags === b.flags;
|
|
23768
|
+
if (a.valueOf !== Object.prototype.valueOf)
|
|
23769
|
+
return a.valueOf() === b.valueOf();
|
|
23770
|
+
if (a.toString !== Object.prototype.toString)
|
|
23771
|
+
return a.toString() === b.toString();
|
|
23772
|
+
keys = Object.keys(a);
|
|
23773
|
+
length = keys.length;
|
|
23774
|
+
if (length !== Object.keys(b).length)
|
|
23775
|
+
return false;
|
|
23776
|
+
for (i = length;i-- !== 0; )
|
|
23777
|
+
if (!Object.prototype.hasOwnProperty.call(b, keys[i]))
|
|
23778
|
+
return false;
|
|
23779
|
+
for (i = length;i-- !== 0; ) {
|
|
23780
|
+
var key = keys[i];
|
|
23781
|
+
if (!equal(a[key], b[key]))
|
|
23782
|
+
return false;
|
|
23783
|
+
}
|
|
23784
|
+
return true;
|
|
23785
|
+
}
|
|
23786
|
+
return a !== a && b !== b;
|
|
23787
|
+
};
|
|
23788
|
+
});
|
|
23789
|
+
|
|
23730
23790
|
// node_modules/commander/esm.mjs
|
|
23731
23791
|
var import__ = __toESM(require_commander(), 1);
|
|
23732
23792
|
var {
|
|
@@ -37437,7 +37497,6 @@ var ServiceTemplateSchema = exports_external.object({
|
|
|
37437
37497
|
params: exports_external.record(exports_external.string(), ParamDefSchema).optional(),
|
|
37438
37498
|
source: SourceConfigSchema.optional(),
|
|
37439
37499
|
variables: exports_external.record(exports_external.string(), exports_external.string().nullable()).optional(),
|
|
37440
|
-
domain: DomainEntrySchema.optional(),
|
|
37441
37500
|
domains: exports_external.array(DomainEntrySchema).optional(),
|
|
37442
37501
|
region: RegionConfigSchema.optional(),
|
|
37443
37502
|
restart_policy: RestartPolicySchema.optional(),
|
|
@@ -37460,7 +37519,6 @@ var ServiceTemplateSchema = exports_external.object({
|
|
|
37460
37519
|
check_suites: exports_external.boolean().optional(),
|
|
37461
37520
|
registry_credentials: RegistryCredentialsSchema.optional(),
|
|
37462
37521
|
railway_domain: RailwayDomainSchema,
|
|
37463
|
-
tcp_proxy: exports_external.number().int().positive().optional(),
|
|
37464
37522
|
tcp_proxies: exports_external.array(exports_external.number().int().positive()).optional(),
|
|
37465
37523
|
limits: LimitsConfigSchema,
|
|
37466
37524
|
railway_config_file: exports_external.string().optional(),
|
|
@@ -37471,7 +37529,6 @@ var ServiceEntrySchema = exports_external.object({
|
|
|
37471
37529
|
params: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
37472
37530
|
variables: exports_external.record(exports_external.string(), exports_external.string().nullable()).optional(),
|
|
37473
37531
|
source: SourceConfigSchema.optional(),
|
|
37474
|
-
domain: DomainEntrySchema.optional(),
|
|
37475
37532
|
domains: exports_external.array(DomainEntrySchema).optional(),
|
|
37476
37533
|
volume: VolumeConfigSchema.optional(),
|
|
37477
37534
|
region: RegionConfigSchema.optional(),
|
|
@@ -37494,7 +37551,6 @@ var ServiceEntrySchema = exports_external.object({
|
|
|
37494
37551
|
check_suites: exports_external.boolean().optional(),
|
|
37495
37552
|
registry_credentials: RegistryCredentialsSchema.optional(),
|
|
37496
37553
|
railway_domain: RailwayDomainSchema,
|
|
37497
|
-
tcp_proxy: exports_external.number().int().positive().optional(),
|
|
37498
37554
|
tcp_proxies: exports_external.array(exports_external.number().int().positive()).optional(),
|
|
37499
37555
|
limits: LimitsConfigSchema,
|
|
37500
37556
|
railway_config_file: exports_external.string().optional(),
|
|
@@ -37535,19 +37591,21 @@ ${issues}`);
|
|
|
37535
37591
|
// src/config/variables.ts
|
|
37536
37592
|
var import_dotenv = __toESM(require_main(), 1);
|
|
37537
37593
|
import { readFileSync } from "fs";
|
|
37538
|
-
function resolveEnvVars(variables, env = process.env) {
|
|
37594
|
+
function resolveEnvVars(variables, env = process.env, lenient = false) {
|
|
37539
37595
|
const resolved = {};
|
|
37540
37596
|
for (const [key, value] of Object.entries(variables)) {
|
|
37541
37597
|
if (value === null)
|
|
37542
37598
|
continue;
|
|
37543
|
-
resolved[key] = resolveEnvVarString(value, env);
|
|
37599
|
+
resolved[key] = resolveEnvVarString(value, env, lenient);
|
|
37544
37600
|
}
|
|
37545
37601
|
return resolved;
|
|
37546
37602
|
}
|
|
37547
|
-
function resolveEnvVarString(input, env = process.env) {
|
|
37548
|
-
return input.replace(/\$\{(?!\{)([^}]+)\}/g, (
|
|
37603
|
+
function resolveEnvVarString(input, env = process.env, lenient = false) {
|
|
37604
|
+
return input.replace(/\$\{(?!\{)([^}]+)\}/g, (match, name) => {
|
|
37549
37605
|
const value = env[name];
|
|
37550
37606
|
if (value === undefined) {
|
|
37607
|
+
if (lenient)
|
|
37608
|
+
return match;
|
|
37551
37609
|
throw new Error(`Environment variable "${name}" is not set (referenced as \${${name}})`);
|
|
37552
37610
|
}
|
|
37553
37611
|
return value;
|
|
@@ -37571,19 +37629,12 @@ function normalizeDomainEntry(entry) {
|
|
|
37571
37629
|
...entry.target_port !== undefined ? { targetPort: entry.target_port } : {}
|
|
37572
37630
|
};
|
|
37573
37631
|
}
|
|
37574
|
-
function normalizeDomains(
|
|
37575
|
-
|
|
37576
|
-
|
|
37577
|
-
|
|
37578
|
-
if (domain2) {
|
|
37579
|
-
const normalized = normalizeDomainEntry(domain2);
|
|
37580
|
-
if (!result.some((d) => d.domain === normalized.domain)) {
|
|
37581
|
-
result.push(normalized);
|
|
37582
|
-
}
|
|
37583
|
-
}
|
|
37584
|
-
return result;
|
|
37632
|
+
function normalizeDomains(domains) {
|
|
37633
|
+
if (!domains)
|
|
37634
|
+
return [];
|
|
37635
|
+
return domains.map(normalizeDomainEntry);
|
|
37585
37636
|
}
|
|
37586
|
-
function loadEnvironmentConfig(envFilePath) {
|
|
37637
|
+
function loadEnvironmentConfig(envFilePath, options) {
|
|
37587
37638
|
const absPath = resolve(envFilePath);
|
|
37588
37639
|
if (!existsSync(absPath)) {
|
|
37589
37640
|
throw new Error(`Config file not found: ${absPath}`);
|
|
@@ -37605,14 +37656,15 @@ function loadEnvironmentConfig(envFilePath) {
|
|
|
37605
37656
|
const config2 = parsed;
|
|
37606
37657
|
const services = {};
|
|
37607
37658
|
const deletedVars = {};
|
|
37659
|
+
const lenient = options?.lenient ?? false;
|
|
37608
37660
|
for (const [name, entry] of Object.entries(config2.services)) {
|
|
37609
|
-
const { service, deleted } = resolveService(name, entry, envDir);
|
|
37661
|
+
const { service, deleted } = resolveService(name, entry, envDir, lenient);
|
|
37610
37662
|
services[name] = service;
|
|
37611
37663
|
if (deleted.length > 0) {
|
|
37612
37664
|
deletedVars[name] = deleted;
|
|
37613
37665
|
}
|
|
37614
37666
|
}
|
|
37615
|
-
const resolvedSharedVars = config2.shared_variables ? resolveEnvVars(config2.shared_variables) : {};
|
|
37667
|
+
const resolvedSharedVars = config2.shared_variables ? resolveEnvVars(config2.shared_variables, process.env, lenient) : {};
|
|
37616
37668
|
const deletedSharedVars = config2.shared_variables ? getDeletedVariables(config2.shared_variables) : [];
|
|
37617
37669
|
const buckets = {};
|
|
37618
37670
|
if (config2.buckets) {
|
|
@@ -37634,7 +37686,7 @@ function loadEnvironmentConfig(envFilePath) {
|
|
|
37634
37686
|
environmentName: config2.environment
|
|
37635
37687
|
};
|
|
37636
37688
|
}
|
|
37637
|
-
function resolveService(name, entry, envDir) {
|
|
37689
|
+
function resolveService(name, entry, envDir, lenient = false) {
|
|
37638
37690
|
let template;
|
|
37639
37691
|
if (entry.template) {
|
|
37640
37692
|
const templatePath = resolve(envDir, entry.template);
|
|
@@ -37682,18 +37734,16 @@ function resolveService(name, entry, envDir) {
|
|
|
37682
37734
|
const checkSuites = template?.check_suites ?? entry.check_suites;
|
|
37683
37735
|
const registryCredentials = template?.registry_credentials ?? entry.registry_credentials;
|
|
37684
37736
|
const railwayDomain = template?.railway_domain ?? entry.railway_domain;
|
|
37685
|
-
const tcpProxy = template?.tcp_proxy ?? entry.tcp_proxy;
|
|
37686
37737
|
const tcpProxies = template?.tcp_proxies ?? entry.tcp_proxies;
|
|
37687
37738
|
const limits = template?.limits ?? entry.limits;
|
|
37688
37739
|
const railwayConfigFile = template?.railway_config_file ? expandParamsDeep(template.railway_config_file, params) : entry.railway_config_file;
|
|
37689
37740
|
const staticOutboundIps = template?.static_outbound_ips ?? entry.static_outbound_ips;
|
|
37690
37741
|
let templateDomains = [];
|
|
37691
37742
|
if (template) {
|
|
37692
|
-
const tplDomain = template.domain ? expandParamsDeep(template.domain, params) : undefined;
|
|
37693
37743
|
const tplDomains = template.domains ? expandParamsDeep(template.domains, params) : undefined;
|
|
37694
|
-
templateDomains = normalizeDomains(
|
|
37744
|
+
templateDomains = normalizeDomains(tplDomains);
|
|
37695
37745
|
}
|
|
37696
|
-
const entryDomains = normalizeDomains(entry.
|
|
37746
|
+
const entryDomains = normalizeDomains(entry.domains);
|
|
37697
37747
|
if (entry.source)
|
|
37698
37748
|
source = entry.source;
|
|
37699
37749
|
const domains = entryDomains.length > 0 ? entryDomains : templateDomains;
|
|
@@ -37703,9 +37753,9 @@ function resolveService(name, entry, envDir) {
|
|
|
37703
37753
|
...entry.variables || {}
|
|
37704
37754
|
};
|
|
37705
37755
|
const deleted = getDeletedVariables(mergedVars);
|
|
37706
|
-
const resolvedVars = resolveEnvVars(mergedVars);
|
|
37756
|
+
const resolvedVars = resolveEnvVars(mergedVars, process.env, lenient);
|
|
37707
37757
|
const resolvedDomainsRaw = domains.map((d) => ({
|
|
37708
|
-
domain: resolveEnvVarString(d.domain),
|
|
37758
|
+
domain: resolveEnvVarString(d.domain, process.env, lenient),
|
|
37709
37759
|
...d.targetPort !== undefined ? { targetPort: d.targetPort } : {}
|
|
37710
37760
|
}));
|
|
37711
37761
|
const seenDomains = new Set;
|
|
@@ -37771,8 +37821,8 @@ function resolveService(name, entry, envDir) {
|
|
|
37771
37821
|
service.checkSuites = checkSuites;
|
|
37772
37822
|
if (registryCredentials) {
|
|
37773
37823
|
service.registryCredentials = {
|
|
37774
|
-
username: resolveEnvVarString(registryCredentials.username),
|
|
37775
|
-
password: resolveEnvVarString(registryCredentials.password)
|
|
37824
|
+
username: resolveEnvVarString(registryCredentials.username, process.env, lenient),
|
|
37825
|
+
password: resolveEnvVarString(registryCredentials.password, process.env, lenient)
|
|
37776
37826
|
};
|
|
37777
37827
|
}
|
|
37778
37828
|
if (railwayDomain !== undefined) {
|
|
@@ -37782,13 +37832,8 @@ function resolveService(name, entry, envDir) {
|
|
|
37782
37832
|
service.railwayDomain = { targetPort: railwayDomain.target_port };
|
|
37783
37833
|
}
|
|
37784
37834
|
}
|
|
37785
|
-
|
|
37786
|
-
|
|
37787
|
-
allTcpPorts.push(...tcpProxies);
|
|
37788
|
-
if (tcpProxy !== undefined && !allTcpPorts.includes(tcpProxy))
|
|
37789
|
-
allTcpPorts.push(tcpProxy);
|
|
37790
|
-
if (allTcpPorts.length > 0)
|
|
37791
|
-
service.tcpProxies = allTcpPorts;
|
|
37835
|
+
if (tcpProxies && tcpProxies.length > 0)
|
|
37836
|
+
service.tcpProxies = tcpProxies;
|
|
37792
37837
|
if (limits) {
|
|
37793
37838
|
service.limits = {
|
|
37794
37839
|
...limits.memory_gb !== undefined ? { memoryGB: limits.memory_gb } : {},
|
|
@@ -39381,8 +39426,9 @@ async function applyChange(client, change, projectId, environmentId, createdServ
|
|
|
39381
39426
|
}
|
|
39382
39427
|
|
|
39383
39428
|
// src/util.ts
|
|
39429
|
+
var import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);
|
|
39384
39430
|
function deepEqual(a, b) {
|
|
39385
|
-
return
|
|
39431
|
+
return import_fast_deep_equal.default(a, b);
|
|
39386
39432
|
}
|
|
39387
39433
|
|
|
39388
39434
|
// src/reconcile/diff.ts
|
|
@@ -39868,7 +39914,7 @@ async function run(configPath, opts) {
|
|
|
39868
39914
|
const raw = readFileSync3(absPath, "utf-8");
|
|
39869
39915
|
const parsed = $parse(raw);
|
|
39870
39916
|
validateEnvironmentConfig(parsed);
|
|
39871
|
-
loadEnvironmentConfig(configPath);
|
|
39917
|
+
loadEnvironmentConfig(configPath, { lenient: true });
|
|
39872
39918
|
console.log("Config is valid.");
|
|
39873
39919
|
process.exit(0);
|
|
39874
39920
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tachyon-gg/railway-deploy",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/tachyon-gg/railway-deploy"
|
|
8
|
+
},
|
|
5
9
|
"main": "./dist/index.js",
|
|
6
10
|
"exports": {
|
|
7
11
|
".": "./dist/index.js"
|
|
@@ -31,6 +35,7 @@
|
|
|
31
35
|
"@graphql-typed-document-node/core": "^3.2.0",
|
|
32
36
|
"commander": "^14.0.3",
|
|
33
37
|
"dotenv": "^17.3.1",
|
|
38
|
+
"fast-deep-equal": "^3.1.3",
|
|
34
39
|
"graphql": "^16.10.0",
|
|
35
40
|
"graphql-request": "^7.1.2",
|
|
36
41
|
"yaml": "^2.7.0",
|