@tachyon-gg/railway-deploy 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.
Files changed (3) hide show
  1. package/README.md +18 -2
  2. package/dist/index.js +27 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -209,11 +209,26 @@ variables:
209
209
  | `${ENV_VAR}` | At config load time | Reads from local environment (or `--env-file`) |
210
210
  | `${{service.VAR}}` | At Railway runtime | Railway reference variable (cross-service) |
211
211
  | `%{param}` | At config load time | Template parameter substitution |
212
+ | `%{service_name}` | At config load time | Built-in: the service's config key |
212
213
  | `null` | N/A | Marks a variable for deletion |
213
214
 
215
+ `%{param}` is expanded first, so it can be used inside `${{}}` Railway references. This is useful for templates that need to reference their own or other services' variables:
216
+
217
+ ```yaml
218
+ variables:
219
+ # Reference own service's variable (resolves %{service_name} at config time,
220
+ # Railway resolves the ${{}} reference at runtime)
221
+ DATABASE_URL: ${{%{service_name}.DATABASE_URL}}
222
+
223
+ # Reference another service by param
224
+ REDIS_URL: ${{%{cache_service}.REDIS_URL}}
225
+ ```
226
+
214
227
  ### Service templates
215
228
 
216
- Templates extract reusable service definitions with parameterized values:
229
+ Templates extract reusable service definitions with parameterized values.
230
+
231
+ The built-in `%{service_name}` param is always available and resolves to the service's key in the config (e.g., `web`, `api`). It cannot be overridden.
217
232
 
218
233
  ```yaml
219
234
  # services/web.yaml
@@ -228,10 +243,11 @@ source:
228
243
 
229
244
  variables:
230
245
  APP_VERSION: "%{tag}"
246
+ SERVICE_NAME: "%{service_name}"
231
247
  DATABASE_URL: ${{Postgres.DATABASE_URL}}
232
248
 
233
249
  domains:
234
- - "%{tag}.example.com"
250
+ - "%{service_name}.example.com"
235
251
 
236
252
  healthcheck:
237
253
  path: /health
package/dist/index.js CHANGED
@@ -23805,6 +23805,7 @@ var {
23805
23805
 
23806
23806
  // src/index.ts
23807
23807
  import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
23808
+ import { createRequire as createRequire2 } from "module";
23808
23809
  import { resolve as resolve2 } from "path";
23809
23810
  import { createInterface } from "readline";
23810
23811
 
@@ -37708,9 +37709,12 @@ function resolveService(name, entry, envDir, lenient = false) {
37708
37709
  validateServiceTemplate(parsed, templatePath);
37709
37710
  template = parsed;
37710
37711
  }
37711
- let params = {};
37712
+ if ("service_name" in (entry.params ?? {}) || "service_name" in (template?.params ?? {})) {
37713
+ throw new Error(`"service_name" is a built-in parameter and cannot be overridden (service "${name}")`);
37714
+ }
37715
+ let params = { service_name: name };
37712
37716
  if (template?.params) {
37713
- params = resolveParams(template.params, entry.params || {});
37717
+ params = { ...resolveParams(template.params, entry.params || {}), service_name: name };
37714
37718
  }
37715
37719
  let source = template?.source ? expandParamsDeep(template.source, params) : entry.source;
37716
37720
  const volume = template?.volume ? expandParamsDeep(template.volume, params) : entry.volume;
@@ -37739,9 +37743,8 @@ function resolveService(name, entry, envDir, lenient = false) {
37739
37743
  const railwayConfigFile = template?.railway_config_file ? expandParamsDeep(template.railway_config_file, params) : entry.railway_config_file;
37740
37744
  const staticOutboundIps = template?.static_outbound_ips ?? entry.static_outbound_ips;
37741
37745
  let templateDomains = [];
37742
- if (template) {
37743
- const tplDomains = template.domains ? expandParamsDeep(template.domains, params) : undefined;
37744
- templateDomains = normalizeDomains(tplDomains);
37746
+ if (template?.domains) {
37747
+ templateDomains = normalizeDomains(expandParamsDeep(template.domains, params));
37745
37748
  }
37746
37749
  const entryDomains = normalizeDomains(entry.domains);
37747
37750
  if (entry.source)
@@ -39658,7 +39661,7 @@ function diffDomains(serviceName, desired, current, currentDomains, changes) {
39658
39661
  domain: domainName,
39659
39662
  ...desiredDomain.targetPort !== undefined ? { targetPort: desiredDomain.targetPort } : {}
39660
39663
  });
39661
- } else if (desiredDomain.targetPort !== existing.targetPort) {
39664
+ } else if (desiredDomain.targetPort !== undefined && desiredDomain.targetPort !== existing.targetPort) {
39662
39665
  changes.push({
39663
39666
  type: "delete-domain",
39664
39667
  serviceName,
@@ -39835,6 +39838,8 @@ function diffStaticOutboundIps(serviceName, desired, current, changes) {
39835
39838
  }
39836
39839
 
39837
39840
  // src/index.ts
39841
+ var require2 = createRequire2(import.meta.url);
39842
+ var { version: version2 } = require2("../package.json");
39838
39843
  async function confirm(message) {
39839
39844
  const rl = createInterface({ input: process.stdin, output: process.stdout });
39840
39845
  return new Promise((res) => {
@@ -39844,7 +39849,21 @@ async function confirm(message) {
39844
39849
  });
39845
39850
  });
39846
39851
  }
39847
- var program2 = new Command().name("railway-deploy").description("Declarative Railway infrastructure management").version("0.1.0").argument("<config>", "Path to environment YAML config file").option("--apply", "Execute changes (default: dry-run)").option("-y, --yes", "Skip confirmation prompts for destructive operations").option("--env-file <path>", "Load .env file for ${VAR} resolution").option("-v, --verbose", "Show detailed diffs (old → new values)").option("--no-color", "Disable ANSI color output").option("--validate", "Validate config without connecting to Railway").action(async (configPath, opts) => {
39852
+ var program2 = new Command().name("railway-deploy").description(`Declarative Railway infrastructure management.
39853
+
39854
+ Define your Railway services, variables, domains, volumes, and more in YAML,
39855
+ and railway-deploy will diff against the live state and apply changes.
39856
+
39857
+ Examples:
39858
+ $ railway-deploy environments/production.yaml
39859
+ $ railway-deploy --apply -y environments/staging.yaml
39860
+ $ railway-deploy --validate environments/production.yaml
39861
+ $ railway-deploy --env-file .env --apply environments/production.yaml
39862
+
39863
+ Environment:
39864
+ RAILWAY_TOKEN Railway API token (required for all operations except --validate)
39865
+
39866
+ Docs: https://github.com/tachyon-gg/railway-deploy`).version(version2).argument("<config>", "path to environment YAML config file").option("--apply", "execute changes (default is dry-run)").option("--env-file <path>", "load .env file for ${VAR} resolution").option("--no-color", "disable colored output").option("--validate", "validate config without connecting to Railway").option("-v, --verbose", "show detailed diffs with old and new values").option("-y, --yes", "skip confirmation prompts for destructive operations").action(async (configPath, opts) => {
39848
39867
  try {
39849
39868
  await run(configPath, opts);
39850
39869
  } catch (err) {
@@ -39906,7 +39925,7 @@ Fetching current state from Railway...`);
39906
39925
  } = await fetchCurrentState(client, projectId, environmentId);
39907
39926
  console.log(`Found ${Object.keys(currentState.services).length} existing service(s)`);
39908
39927
  const changeset = computeChangeset(desiredState, currentState, deletedVars, deletedSharedVars, domainMap, volumeMap, serviceDomainMap, tcpProxyMap);
39909
- const noColor = opts.noColor ?? false;
39928
+ const noColor = opts.color === false;
39910
39929
  const verbose = opts.verbose ?? false;
39911
39930
  printChangeset(changeset, {
39912
39931
  verbose,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tachyon-gg/railway-deploy",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",