@tachyon-gg/railway-deploy 0.2.9 → 0.2.10

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 CHANGED
@@ -130,8 +130,11 @@ watch_patterns: # File patterns that trigger deploys
130
130
  - /packages/api/src/**
131
131
  - /packages/shared/**
132
132
  railway_config_file: railway.toml # Path to railway.json/toml for config-as-code
133
+ metal: true # Enable Railway Metal builds (service-level, see note below)
133
134
  ```
134
135
 
136
+ **Note:** Some settings are **service-level** in Railway (applied globally, not per-environment): `metal`, service creation, and service deletion. If you manage multiple environments for the same project, these settings will affect all environments regardless of which YAML file sets them.
137
+
135
138
  #### Deploy
136
139
 
137
140
  ```yaml
package/dist/index.js CHANGED
@@ -37508,7 +37508,8 @@ var ServiceTemplateSchema = exports_external.object({
37508
37508
  tcp_proxies: exports_external.array(exports_external.number().int().positive()).optional(),
37509
37509
  limits: LimitsConfigSchema,
37510
37510
  railway_config_file: exports_external.string().optional(),
37511
- static_outbound_ips: exports_external.boolean().optional()
37511
+ static_outbound_ips: exports_external.boolean().optional(),
37512
+ metal: exports_external.boolean().optional()
37512
37513
  }).strict();
37513
37514
  var ServiceEntrySchema = exports_external.object({
37514
37515
  template: exports_external.string().optional(),
@@ -37540,7 +37541,8 @@ var ServiceEntrySchema = exports_external.object({
37540
37541
  tcp_proxies: exports_external.array(exports_external.number().int().positive()).optional(),
37541
37542
  limits: LimitsConfigSchema,
37542
37543
  railway_config_file: exports_external.string().optional(),
37543
- static_outbound_ips: exports_external.boolean().optional()
37544
+ static_outbound_ips: exports_external.boolean().optional(),
37545
+ metal: exports_external.boolean().optional()
37544
37546
  }).strict();
37545
37547
  var EnvironmentConfigSchema = exports_external.object({
37546
37548
  project: exports_external.string().min(1, "project name is required"),
@@ -37761,6 +37763,7 @@ function resolveService(name, entry, envDir, lenient = false) {
37761
37763
  const limits = template?.limits ?? entry.limits;
37762
37764
  const railwayConfigFile = template?.railway_config_file ? expandParamsDeep(template.railway_config_file, params) : entry.railway_config_file;
37763
37765
  const staticOutboundIps = template?.static_outbound_ips ?? entry.static_outbound_ips;
37766
+ const metal = template?.metal ?? entry.metal;
37764
37767
  let templateDomains = [];
37765
37768
  if (template?.domains) {
37766
37769
  templateDomains = normalizeDomains(expandParamsDeep(template.domains, params));
@@ -37866,6 +37869,8 @@ function resolveService(name, entry, envDir, lenient = false) {
37866
37869
  service.railwayConfigFile = railwayConfigFile;
37867
37870
  if (staticOutboundIps !== undefined)
37868
37871
  service.staticOutboundIps = staticOutboundIps;
37872
+ if (metal !== undefined)
37873
+ service.metal = metal;
37869
37874
  validateResolvedService(name, service);
37870
37875
  return { service, deleted };
37871
37876
  }
@@ -38469,8 +38474,10 @@ var ServiceInstanceLimitsUpdateDocument = { kind: "Document", definitions: [{ ki
38469
38474
  var DeploymentTriggerUpdateDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "mutation", name: { kind: "Name", value: "DeploymentTriggerUpdate" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "id" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }, { kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "DeploymentTriggerUpdateInput" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "deploymentTriggerUpdate" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "id" }, value: { kind: "Variable", name: { kind: "Name", value: "id" } } }, { kind: "Argument", name: { kind: "Name", value: "input" }, value: { kind: "Variable", name: { kind: "Name", value: "input" } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "branch" } }] } }] } }] };
38470
38475
  var EgressGatewayAssociationCreateDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "mutation", name: { kind: "Name", value: "EgressGatewayAssociationCreate" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "EgressGatewayCreateInput" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "egressGatewayAssociationCreate" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "input" }, value: { kind: "Variable", name: { kind: "Name", value: "input" } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "ipv4" } }, { kind: "Field", name: { kind: "Name", value: "region" } }] } }] } }] };
38471
38476
  var EgressGatewayAssociationsClearDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "mutation", name: { kind: "Name", value: "EgressGatewayAssociationsClear" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "EgressGatewayServiceTargetInput" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "egressGatewayAssociationsClear" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "input" }, value: { kind: "Variable", name: { kind: "Name", value: "input" } } }] }] } }] };
38477
+ var ServiceFeatureFlagAddDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "mutation", name: { kind: "Name", value: "ServiceFeatureFlagAdd" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "ServiceFeatureFlagToggleInput" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "serviceFeatureFlagAdd" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "input" }, value: { kind: "Variable", name: { kind: "Name", value: "input" } } }] }] } }] };
38478
+ var ServiceFeatureFlagRemoveDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "mutation", name: { kind: "Name", value: "ServiceFeatureFlagRemove" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "input" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "ServiceFeatureFlagToggleInput" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "serviceFeatureFlagRemove" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "input" }, value: { kind: "Variable", name: { kind: "Name", value: "input" } } }] }] } }] };
38472
38479
  var ListProjectsDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "ListProjects" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "projects" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }] } }] } }] } }] } }] };
38473
- var GetProjectDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "GetProject" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "id" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "project" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "id" }, value: { kind: "Variable", name: { kind: "Name", value: "id" } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "environments" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "deploymentTriggers" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "branch" } }, { kind: "Field", name: { kind: "Name", value: "checkSuites" } }, { kind: "Field", name: { kind: "Name", value: "serviceId" } }, { kind: "Field", name: { kind: "Name", value: "repository" } }] } }] } }] } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "services" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "serviceInstances" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "environmentId" } }, { kind: "Field", name: { kind: "Name", value: "source" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "image" } }, { kind: "Field", name: { kind: "Name", value: "repo" } }] } }, { kind: "Field", name: { kind: "Name", value: "domains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "customDomains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "domain" } }, { kind: "Field", name: { kind: "Name", value: "targetPort" } }] } }, { kind: "Field", name: { kind: "Name", value: "serviceDomains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "domain" } }, { kind: "Field", name: { kind: "Name", value: "targetPort" } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "region" } }, { kind: "Field", name: { kind: "Name", value: "numReplicas" } }, { kind: "Field", name: { kind: "Name", value: "restartPolicyType" } }, { kind: "Field", name: { kind: "Name", value: "restartPolicyMaxRetries" } }, { kind: "Field", name: { kind: "Name", value: "healthcheckPath" } }, { kind: "Field", name: { kind: "Name", value: "healthcheckTimeout" } }, { kind: "Field", name: { kind: "Name", value: "cronSchedule" } }, { kind: "Field", name: { kind: "Name", value: "startCommand" } }, { kind: "Field", name: { kind: "Name", value: "buildCommand" } }, { kind: "Field", name: { kind: "Name", value: "rootDirectory" } }, { kind: "Field", name: { kind: "Name", value: "dockerfilePath" } }, { kind: "Field", name: { kind: "Name", value: "preDeployCommand" } }, { kind: "Field", name: { kind: "Name", value: "sleepApplication" } }, { kind: "Field", name: { kind: "Name", value: "builder" } }, { kind: "Field", name: { kind: "Name", value: "watchPatterns" } }, { kind: "Field", name: { kind: "Name", value: "drainingSeconds" } }, { kind: "Field", name: { kind: "Name", value: "overlapSeconds" } }, { kind: "Field", name: { kind: "Name", value: "ipv6EgressEnabled" } }, { kind: "Field", name: { kind: "Name", value: "railwayConfigFile" } }] } }] } }] } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "buckets" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "volumes" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "volumeInstances" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "mountPath" } }, { kind: "Field", name: { kind: "Name", value: "environmentId" } }, { kind: "Field", name: { kind: "Name", value: "serviceId" } }] } }] } }] } }] } }] } }] } }] } }] } }] };
38480
+ var GetProjectDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "GetProject" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "id" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "project" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "id" }, value: { kind: "Variable", name: { kind: "Name", value: "id" } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "environments" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "deploymentTriggers" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "branch" } }, { kind: "Field", name: { kind: "Name", value: "checkSuites" } }, { kind: "Field", name: { kind: "Name", value: "serviceId" } }, { kind: "Field", name: { kind: "Name", value: "repository" } }] } }] } }] } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "services" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "featureFlags" } }, { kind: "Field", name: { kind: "Name", value: "serviceInstances" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "environmentId" } }, { kind: "Field", name: { kind: "Name", value: "source" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "image" } }, { kind: "Field", name: { kind: "Name", value: "repo" } }] } }, { kind: "Field", name: { kind: "Name", value: "domains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "customDomains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "domain" } }, { kind: "Field", name: { kind: "Name", value: "targetPort" } }] } }, { kind: "Field", name: { kind: "Name", value: "serviceDomains" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "domain" } }, { kind: "Field", name: { kind: "Name", value: "targetPort" } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "region" } }, { kind: "Field", name: { kind: "Name", value: "numReplicas" } }, { kind: "Field", name: { kind: "Name", value: "restartPolicyType" } }, { kind: "Field", name: { kind: "Name", value: "restartPolicyMaxRetries" } }, { kind: "Field", name: { kind: "Name", value: "healthcheckPath" } }, { kind: "Field", name: { kind: "Name", value: "healthcheckTimeout" } }, { kind: "Field", name: { kind: "Name", value: "cronSchedule" } }, { kind: "Field", name: { kind: "Name", value: "startCommand" } }, { kind: "Field", name: { kind: "Name", value: "buildCommand" } }, { kind: "Field", name: { kind: "Name", value: "rootDirectory" } }, { kind: "Field", name: { kind: "Name", value: "dockerfilePath" } }, { kind: "Field", name: { kind: "Name", value: "preDeployCommand" } }, { kind: "Field", name: { kind: "Name", value: "sleepApplication" } }, { kind: "Field", name: { kind: "Name", value: "builder" } }, { kind: "Field", name: { kind: "Name", value: "watchPatterns" } }, { kind: "Field", name: { kind: "Name", value: "drainingSeconds" } }, { kind: "Field", name: { kind: "Name", value: "overlapSeconds" } }, { kind: "Field", name: { kind: "Name", value: "ipv6EgressEnabled" } }, { kind: "Field", name: { kind: "Name", value: "railwayConfigFile" } }] } }] } }] } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "buckets" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }] } }] } }] } }, { kind: "Field", name: { kind: "Name", value: "volumes" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "name" } }, { kind: "Field", name: { kind: "Name", value: "volumeInstances" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "edges" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "node" }, selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "mountPath" } }, { kind: "Field", name: { kind: "Name", value: "environmentId" } }, { kind: "Field", name: { kind: "Name", value: "serviceId" } }] } }] } }] } }] } }] } }] } }] } }] } }] };
38474
38481
  var GetVariablesDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "GetVariables" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "projectId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }, { kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "environmentId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }, { kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "serviceId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "variables" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "projectId" }, value: { kind: "Variable", name: { kind: "Name", value: "projectId" } } }, { kind: "Argument", name: { kind: "Name", value: "environmentId" }, value: { kind: "Variable", name: { kind: "Name", value: "environmentId" } } }, { kind: "Argument", name: { kind: "Name", value: "serviceId" }, value: { kind: "Variable", name: { kind: "Name", value: "serviceId" } } }, { kind: "Argument", name: { kind: "Name", value: "unrendered" }, value: { kind: "BooleanValue", value: true } }] }] } }] };
38475
38482
  var GetSharedVariablesDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "GetSharedVariables" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "projectId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }, { kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "environmentId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "variables" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "projectId" }, value: { kind: "Variable", name: { kind: "Name", value: "projectId" } } }, { kind: "Argument", name: { kind: "Name", value: "environmentId" }, value: { kind: "Variable", name: { kind: "Name", value: "environmentId" } } }, { kind: "Argument", name: { kind: "Name", value: "unrendered" }, value: { kind: "BooleanValue", value: true } }] }] } }] };
38476
38483
  var GetTcpProxiesDocument = { kind: "Document", definitions: [{ kind: "OperationDefinition", operation: "query", name: { kind: "Name", value: "GetTcpProxies" }, variableDefinitions: [{ kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "serviceId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }, { kind: "VariableDefinition", variable: { kind: "Variable", name: { kind: "Name", value: "environmentId" } }, type: { kind: "NonNullType", type: { kind: "NamedType", name: { kind: "Name", value: "String" } } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "tcpProxies" }, arguments: [{ kind: "Argument", name: { kind: "Name", value: "serviceId" }, value: { kind: "Variable", name: { kind: "Name", value: "serviceId" } } }, { kind: "Argument", name: { kind: "Name", value: "environmentId" }, value: { kind: "Variable", name: { kind: "Name", value: "environmentId" } } }], selectionSet: { kind: "SelectionSet", selections: [{ kind: "Field", name: { kind: "Name", value: "id" } }, { kind: "Field", name: { kind: "Name", value: "applicationPort" } }, { kind: "Field", name: { kind: "Name", value: "proxyPort" } }, { kind: "Field", name: { kind: "Name", value: "domain" } }] } }] } }] };
@@ -38638,6 +38645,9 @@ async function fetchCurrentState(client, projectId, environmentId) {
38638
38645
  if (egressLookup.get(svc.id)) {
38639
38646
  services[svc.name].staticOutboundIps = true;
38640
38647
  }
38648
+ if (svc.featureFlags.includes("USE_VM_RUNTIME")) {
38649
+ services[svc.name].metal = true;
38650
+ }
38641
38651
  if (vol) {
38642
38652
  volumeMap[svc.name] = vol;
38643
38653
  }
@@ -38895,6 +38905,16 @@ async function clearEgressGateways(client, serviceId, environmentId) {
38895
38905
  input: { serviceId, environmentId }
38896
38906
  });
38897
38907
  }
38908
+ async function addServiceFeatureFlag(client, serviceId, flag) {
38909
+ await client.request(ServiceFeatureFlagAddDocument, {
38910
+ input: { serviceId, flag }
38911
+ });
38912
+ }
38913
+ async function removeServiceFeatureFlag(client, serviceId, flag) {
38914
+ await client.request(ServiceFeatureFlagRemoveDocument, {
38915
+ input: { serviceId, flag }
38916
+ });
38917
+ }
38898
38918
  async function createBucket(client, projectId, name) {
38899
38919
  const data = await client.request(BucketCreateDocument, {
38900
38920
  input: { projectId, name }
@@ -39095,6 +39115,24 @@ function describeChange(change) {
39095
39115
  serviceName: change.serviceName,
39096
39116
  summary: "static outbound IPs: disable"
39097
39117
  };
39118
+ case "enable-service-feature-flag": {
39119
+ const flagName = change.flag === "USE_VM_RUNTIME" ? "metal" : change.flag;
39120
+ return {
39121
+ category: "Feature flags",
39122
+ action: "create",
39123
+ serviceName: change.serviceName,
39124
+ summary: `${flagName}: enable`
39125
+ };
39126
+ }
39127
+ case "disable-service-feature-flag": {
39128
+ const flagName = change.flag === "USE_VM_RUNTIME" ? "metal" : change.flag;
39129
+ return {
39130
+ category: "Feature flags",
39131
+ action: "delete",
39132
+ serviceName: change.serviceName,
39133
+ summary: `${flagName}: disable`
39134
+ };
39135
+ }
39098
39136
  case "create-bucket":
39099
39137
  return {
39100
39138
  category: "Buckets",
@@ -39479,6 +39517,22 @@ async function applyChange(client, change, projectId, environmentId, createdServ
39479
39517
  await clearEgressGateways(client, serviceId, environmentId);
39480
39518
  break;
39481
39519
  }
39520
+ case "enable-service-feature-flag": {
39521
+ const serviceId = change.serviceId || createdServiceIds.get(change.serviceName);
39522
+ if (!serviceId) {
39523
+ throw new Error(`No service ID for "${change.serviceName}"`);
39524
+ }
39525
+ await addServiceFeatureFlag(client, serviceId, change.flag);
39526
+ break;
39527
+ }
39528
+ case "disable-service-feature-flag": {
39529
+ const serviceId = change.serviceId || createdServiceIds.get(change.serviceName);
39530
+ if (!serviceId) {
39531
+ throw new Error(`No service ID for "${change.serviceName}"`);
39532
+ }
39533
+ await removeServiceFeatureFlag(client, serviceId, change.flag);
39534
+ break;
39535
+ }
39482
39536
  case "delete-bucket":
39483
39537
  throw new Error("Bucket deletion is not supported by the Railway API — delete manually");
39484
39538
  default: {
@@ -39596,6 +39650,15 @@ function computeChangeset(desired, current, deletedVars, deletedSharedVars, doma
39596
39650
  serviceId: ""
39597
39651
  });
39598
39652
  }
39653
+ if (desiredSvc.metal) {
39654
+ console.warn(` Warning: "${name}" metal flag is service-level — applies across all Railway environments`);
39655
+ changes.push({
39656
+ type: "enable-service-feature-flag",
39657
+ serviceName: name,
39658
+ serviceId: "",
39659
+ flag: "USE_VM_RUNTIME"
39660
+ });
39661
+ }
39599
39662
  if (Object.keys(newSvcSettings).length > 0) {
39600
39663
  changes.push({
39601
39664
  type: "update-service-settings",
@@ -39627,6 +39690,7 @@ function computeChangeset(desired, current, deletedVars, deletedSharedVars, doma
39627
39690
  }
39628
39691
  }
39629
39692
  diffStaticOutboundIps(name, desiredSvc, currentSvc, changes);
39693
+ diffMetal(name, desiredSvc, currentSvc, changes);
39630
39694
  }
39631
39695
  }
39632
39696
  for (const name of currentNames) {
@@ -39936,6 +40000,27 @@ function diffServiceLimits(serviceName, desired, current, changes) {
39936
40000
  });
39937
40001
  }
39938
40002
  }
40003
+ function diffMetal(serviceName, desired, current, changes) {
40004
+ if (!current.id)
40005
+ return;
40006
+ if (desired.metal === true && !current.metal) {
40007
+ console.warn(` Warning: "${serviceName}" metal flag is service-level — applies across all Railway environments`);
40008
+ changes.push({
40009
+ type: "enable-service-feature-flag",
40010
+ serviceName,
40011
+ serviceId: current.id,
40012
+ flag: "USE_VM_RUNTIME"
40013
+ });
40014
+ } else if (desired.metal === false && current.metal) {
40015
+ console.warn(` Warning: "${serviceName}" metal flag is service-level — applies across all Railway environments`);
40016
+ changes.push({
40017
+ type: "disable-service-feature-flag",
40018
+ serviceName,
40019
+ serviceId: current.id,
40020
+ flag: "USE_VM_RUNTIME"
40021
+ });
40022
+ }
40023
+ }
39939
40024
  function diffStaticOutboundIps(serviceName, desired, current, changes) {
39940
40025
  if (!current.id)
39941
40026
  return;
@@ -40054,7 +40139,7 @@ Fetching current state from Railway...`);
40054
40139
  console.log("Nothing to apply.");
40055
40140
  process.exit(0);
40056
40141
  }
40057
- const hasDestructive = changeset.changes.some((c) => c.type === "delete-service" || c.type === "delete-volume" || c.type === "delete-bucket" || c.type === "delete-domain" || c.type === "delete-variables" || c.type === "delete-shared-variables" || c.type === "delete-service-domain" || c.type === "delete-tcp-proxy" || c.type === "disable-static-ips");
40142
+ const hasDestructive = changeset.changes.some((c) => c.type === "delete-service" || c.type === "delete-volume" || c.type === "delete-bucket" || c.type === "delete-domain" || c.type === "delete-variables" || c.type === "delete-shared-variables" || c.type === "delete-service-domain" || c.type === "delete-tcp-proxy" || c.type === "disable-static-ips" || c.type === "disable-service-feature-flag");
40058
40143
  if (hasDestructive && !opts.yes) {
40059
40144
  const ok = await confirm("This changeset includes destructive operations (deletions). Continue?");
40060
40145
  if (!ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tachyon-gg/railway-deploy",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",