@tachyon-gg/railway-deploy 0.1.0

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 (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +353 -0
  3. package/dist/index.js +39977 -0
  4. package/package.json +48 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tachyon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,353 @@
1
+ # railway-deploy
2
+
3
+ [![CI](https://github.com/tachyon-gg/railway-deploy/actions/workflows/ci.yml/badge.svg)](https://github.com/tachyon-gg/railway-deploy/actions/workflows/ci.yml)
4
+ [![Integration Tests](https://github.com/tachyon-gg/railway-deploy/actions/workflows/integration.yml/badge.svg)](https://github.com/tachyon-gg/railway-deploy/actions/workflows/integration.yml)
5
+ [![codecov](https://codecov.io/gh/tachyon-gg/railway-deploy/graph/badge.svg)](https://codecov.io/gh/tachyon-gg/railway-deploy)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](https://www.typescriptlang.org/)
7
+ [![Bun](https://img.shields.io/badge/runtime-Bun-f9f1e1)](https://bun.sh/)
8
+ [![Biome](https://img.shields.io/badge/linter-Biome-60a5fa)](https://biomejs.dev/)
9
+
10
+ Declarative infrastructure management for [Railway](https://railway.com). Define your Railway project's services, variables, domains, volumes, and buckets in YAML, and `railway-deploy` will diff against the live state and apply changes -- like Terraform, but purpose-built for Railway.
11
+
12
+ ## Quick start
13
+
14
+ ```bash
15
+ # Install
16
+ npx @tachyon-gg/railway-deploy --help
17
+
18
+ # Validate a config file
19
+ npx @tachyon-gg/railway-deploy --validate environments/production.yaml
20
+
21
+ # Dry-run (show what would change)
22
+ npx @tachyon-gg/railway-deploy environments/production.yaml
23
+
24
+ # Apply changes
25
+ npx @tachyon-gg/railway-deploy --apply environments/production.yaml
26
+ ```
27
+
28
+ ## CLI flags
29
+
30
+ | Flag | Description |
31
+ |------|-------------|
32
+ | `--apply` | Execute changes (default: dry-run) |
33
+ | `-y, --yes` | Skip confirmation for destructive ops |
34
+ | `--env-file <path>` | Load `.env` file for `${VAR}` resolution |
35
+ | `-v, --verbose` | Show detailed diffs (old -> new values) |
36
+ | `--no-color` | Disable ANSI color output |
37
+ | `--validate` | Validate config without connecting to Railway |
38
+
39
+ ## Environment variables
40
+
41
+ | Variable | Description |
42
+ |----------|-------------|
43
+ | `RAILWAY_TOKEN` | Railway API token (required for all API operations) |
44
+
45
+ ---
46
+
47
+ ## Config reference
48
+
49
+ Environment configs are YAML files describing the desired state of a Railway environment. Add schema support to your editor:
50
+
51
+ ```yaml
52
+ # yaml-language-server: $schema=./schemas/environment.schema.json
53
+ ```
54
+
55
+ ### Top-level fields
56
+
57
+ ```yaml
58
+ project: My Project # Railway project name (must match exactly)
59
+ environment: production # Railway environment name
60
+
61
+ shared_variables: # Variables shared across all services
62
+ APP_ENV: production
63
+ DATABASE_URL: ${{Postgres.DATABASE_URL}}
64
+
65
+ services: # Map of service name -> config
66
+ web: { ... }
67
+ worker: { ... }
68
+
69
+ buckets: # S3-compatible buckets
70
+ media:
71
+ name: media-uploads
72
+ ```
73
+
74
+ ### Service configuration
75
+
76
+ Each service can be defined inline or via a template:
77
+
78
+ ```yaml
79
+ services:
80
+ # Inline service (Docker image)
81
+ redis:
82
+ source:
83
+ image: redis:7
84
+ variables:
85
+ ALLOW_EMPTY_PASSWORD: "yes"
86
+
87
+ # Inline service (GitHub repo)
88
+ api:
89
+ source:
90
+ repo: myorg/my-api
91
+ branch: main
92
+
93
+ # Template-based service
94
+ web:
95
+ template: ../services/web.yaml
96
+ params:
97
+ tag: v1.2.3
98
+ variables:
99
+ EXTRA_VAR: override-value
100
+ ```
101
+
102
+ ### Full service options
103
+
104
+ Every option below can be used on both inline services and service templates.
105
+
106
+ #### Source
107
+
108
+ ```yaml
109
+ source:
110
+ image: nginx:latest # Docker image (Docker Hub, GHCR, etc.)
111
+ # OR
112
+ repo: myorg/my-repo # GitHub repository
113
+
114
+ branch: main # Branch to deploy from (GitHub repos)
115
+ check_suites: true # Wait for GitHub Actions to pass before deploying
116
+
117
+ registry_credentials: # For private container registries
118
+ username: ${REGISTRY_USER}
119
+ password: ${REGISTRY_PASS}
120
+ ```
121
+
122
+ #### Build
123
+
124
+ ```yaml
125
+ builder: NIXPACKS # RAILPACK (default), DOCKERFILE, NIXPACKS, HEROKU, PAKETO
126
+ build_command: npm run build # Custom build command
127
+ dockerfile_path: Dockerfile.prod # Path to Dockerfile (when builder is DOCKERFILE)
128
+ root_directory: /packages/api # Root directory (monorepo support)
129
+ watch_patterns: # File patterns that trigger deploys
130
+ - /packages/api/src/**
131
+ - /packages/shared/**
132
+ railway_config_file: railway.toml # Path to railway.json/toml for config-as-code
133
+ ```
134
+
135
+ #### Deploy
136
+
137
+ ```yaml
138
+ start_command: npm start # Custom start command
139
+ pre_deploy_command: # Run before deployment (e.g., migrations)
140
+ - npm run migrate
141
+ - npm run seed
142
+ cron_schedule: "*/5 * * * *" # Cron schedule (for scheduled jobs)
143
+ healthcheck: # HTTP healthcheck
144
+ path: /health
145
+ timeout: 300 # Timeout in seconds (default: 300)
146
+ restart_policy: ON_FAILURE # ALWAYS, NEVER, or ON_FAILURE
147
+ restart_policy_max_retries: 10 # Max retries (only with ON_FAILURE)
148
+ sleep_application: true # Enable serverless sleeping
149
+ draining_seconds: 30 # Graceful shutdown timeout (seconds between SIGTERM and SIGKILL)
150
+ overlap_seconds: 10 # Blue-green deploy overlap duration
151
+ ```
152
+
153
+ #### Networking
154
+
155
+ ```yaml
156
+ # Custom domains
157
+ domains:
158
+ - app.example.com # Simple domain
159
+ - domain: api.example.com # Domain with target port
160
+ target_port: 8080
161
+ domain: simple.example.com # Shorthand for a single domain
162
+
163
+ # Railway-provided domain
164
+ railway_domain: true # Generate a .up.railway.app domain
165
+ railway_domain: # ...with a specific target port
166
+ target_port: 3000
167
+
168
+ # TCP proxies (for non-HTTP services like databases)
169
+ tcp_proxy: 5432 # Single port
170
+ tcp_proxies: [5432, 6379] # Multiple ports
171
+
172
+ # Outbound networking
173
+ ipv6_egress: true # Enable IPv6 outbound traffic
174
+ static_outbound_ips: true # Assign permanent outbound IP addresses
175
+ ```
176
+
177
+ #### Scaling
178
+
179
+ ```yaml
180
+ region: # Deployment region
181
+ region: us-east-1
182
+ num_replicas: 3 # Horizontal replicas (default: 1)
183
+
184
+ limits: # Resource limits per replica
185
+ memory_gb: 8
186
+ vcpus: 4
187
+ ```
188
+
189
+ #### Storage
190
+
191
+ ```yaml
192
+ volume: # Persistent volume
193
+ mount: /data # Mount path (must be absolute)
194
+ name: my-data
195
+ ```
196
+
197
+ #### Variables
198
+
199
+ ```yaml
200
+ variables:
201
+ PORT: "3000"
202
+ DATABASE_URL: ${{Postgres.DATABASE_URL}} # Railway runtime reference
203
+ API_KEY: ${LOCAL_API_KEY} # Resolved from local env at config time
204
+ OLD_VAR: null # Marks for deletion
205
+ ```
206
+
207
+ ### Variable syntax
208
+
209
+ | Syntax | Resolved | Description |
210
+ |--------|----------|-------------|
211
+ | `${ENV_VAR}` | At config load time | Reads from local environment (or `--env-file`) |
212
+ | `${{service.VAR}}` | At Railway runtime | Railway reference variable (cross-service) |
213
+ | `%{param}` | At config load time | Template parameter substitution |
214
+ | `null` | N/A | Marks a variable for deletion |
215
+
216
+ ### Service templates
217
+
218
+ Templates extract reusable service definitions with parameterized values:
219
+
220
+ ```yaml
221
+ # services/web.yaml
222
+ params:
223
+ tag:
224
+ required: true
225
+ replicas:
226
+ default: "1"
227
+
228
+ source:
229
+ image: ghcr.io/org/app:%{tag}
230
+
231
+ variables:
232
+ APP_VERSION: "%{tag}"
233
+ DATABASE_URL: ${{Postgres.DATABASE_URL}}
234
+
235
+ domain: "%{tag}.example.com"
236
+
237
+ healthcheck:
238
+ path: /health
239
+ timeout: 300
240
+
241
+ region:
242
+ region: us-east-1
243
+ num_replicas: 1
244
+ ```
245
+
246
+ Referenced from an environment config:
247
+
248
+ ```yaml
249
+ services:
250
+ web:
251
+ template: ../services/web.yaml
252
+ params:
253
+ tag: v2.0.0
254
+ replicas: "3"
255
+ variables:
256
+ EXTRA: added-by-env # Merged with template variables
257
+ APP_VERSION: null # Deletes the template-defined variable
258
+ domains:
259
+ - production.example.com # Overrides template domain
260
+ ```
261
+
262
+ Template override precedence: environment config values override template values for `source`, `domains`, and `variables`.
263
+
264
+ ### Complete example
265
+
266
+ ```yaml
267
+ # yaml-language-server: $schema=./schemas/environment.schema.json
268
+ project: My SaaS App
269
+ environment: production
270
+
271
+ shared_variables:
272
+ APP_ENV: production
273
+ SENTRY_DSN: ${SENTRY_DSN}
274
+
275
+ services:
276
+ web:
277
+ source:
278
+ repo: myorg/web-app
279
+ branch: main
280
+ check_suites: true
281
+ builder: NIXPACKS
282
+ build_command: npm run build
283
+ start_command: npm start
284
+ root_directory: /packages/web
285
+ pre_deploy_command: npm run migrate
286
+ healthcheck:
287
+ path: /health
288
+ timeout: 60
289
+ restart_policy: ON_FAILURE
290
+ restart_policy_max_retries: 5
291
+ domains:
292
+ - app.example.com
293
+ - domain: api.example.com
294
+ target_port: 8080
295
+ railway_domain: true
296
+ region:
297
+ region: us-east-1
298
+ num_replicas: 2
299
+ limits:
300
+ memory_gb: 4
301
+ vcpus: 2
302
+ variables:
303
+ PORT: "3000"
304
+ DATABASE_URL: ${{Postgres.DATABASE_URL}}
305
+
306
+ postgres:
307
+ source:
308
+ image: postgres:16
309
+ volume:
310
+ mount: /var/lib/postgresql/data
311
+ name: pg-data
312
+ tcp_proxy: 5432
313
+ variables:
314
+ POSTGRES_DB: myapp
315
+
316
+ redis:
317
+ source:
318
+ image: redis:7-alpine
319
+ volume:
320
+ mount: /data
321
+ name: redis-data
322
+ tcp_proxy: 6379
323
+
324
+ worker:
325
+ template: ../services/worker.yaml
326
+ params:
327
+ queue: default
328
+ sleep_application: false
329
+
330
+ buckets:
331
+ uploads:
332
+ name: user-uploads
333
+ ```
334
+
335
+ ## JSON schemas
336
+
337
+ Editor support (autocompletion, validation) is available via JSON schemas:
338
+
339
+ - `schemas/environment.schema.json` -- environment config files
340
+ - `schemas/service-template.schema.json` -- service template files
341
+
342
+ ## Development
343
+
344
+ ```bash
345
+ bun install # Install dependencies
346
+ bun run test # Run unit tests
347
+ bun run test:integration # Run integration tests (requires RAILWAY_TOKEN)
348
+ bun run typecheck # Type check
349
+ bun run lint # Lint (Biome)
350
+ bun run lint:fix # Auto-fix lint issues
351
+ bun run codegen # Regenerate GraphQL types
352
+ bun run build # Build for distribution
353
+ ```