Repository navigation
fix(deploy): railway-apply never deletes or overwrites hand-set variables - #104
Merged
Merged
Conversation
…bles Rebased onto main, which already has per_environment manual values and make deploy-vars (#111). What was still missing: - check-fast and CI ran the deploy/ vet, lint and names but not deploy-vars, and a change to .env.example or the Makefile (its inputs) did not trigger the deploy checks. Both now do. - That check fails on main: sign-in with Google/Apple and object storage added names an apply would delete. Their secrets are web live secrets, so they join web's Doppler-owned names (seeded only when set on Railway); the graph now ignores every Doppler-owned copy; the non-secret halves (GOOGLE_CLIENT_ID, APPLE_CLIENT_ID, APPLE_TEAM_ID, STORAGE_S3_REGION, STORAGE_S3_PATH_STYLE) are unmanaged_variables. Dropped from the original: per_environment TODO values (main has manual) and the example-sender guard (main does not refuse an example FROM_EMAIL at boot). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jayleaton
force-pushed
the
fix/railway-apply-keeps-hand-set-vars
branch
from
October 23, 2026 12:05
f86ff05 to
a73a73a
Compare
Owner
Author
|
Rebased onto main (00206f3) and cut down to what main is still missing. Most of this PR shipped in #111 (b728c98): per_environment values (as Kept (new head a73a73a):
Dropped: the TODO values (main has |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
The Railway project's variables are managed (
variables: {managed: true, ignore: [...]}), somake railway-applydeletes every variable the IaC graph neither sets nor ignores, and resets every variable it does set. On main:TRUSTED_ORIGINS,INTERNAL_URL,APP_NAME,AUTH_SECRET_GRACE,SECRETS_REFRESH_INTERVAL/SECRETS_MAX_STALENESS,ADMIN_TRUSTED_ORIGINS,ADMIN_REQUIRE_2FA, ...) are neither set nor ignored, so a value set in the dashboard is deleted on the next apply.PUBLIC_URL/ADMIN_PUBLIC_URLare always the Railway domain andFROM_EMAILis alwaysemail.from, so a custom domain or a per-environment sender gets reset by every apply.A derived project found this before its first production apply.
Reproduction
The new offline checker, run against main's graph code (TODO handling stubbed out, since main has no
per_environment):Fix
unmanaged_variablesindeploy/platform.yamlnow lists the template's optional settings. Withoutadmin_bootstrap_email,admin/ADMIN_BOOTSTRAP_EMAILis ignored, and so isbackup/ADMIN_DATABASE_URLwhen the graph doesn't wire it.per_environment.<env>.public_urlandadmin_public_urltakerailway(the default) or an https origin, andfrom_emaildefaults toemail.from. A value starting withTODOis left out of the graph and added tovariables.ignore, so apply neither sets nor resets it. Plan and apply printleft as it is (TODO ...). Bad values fail validation.make deploy-vars(deploy/cmd/check-vars, a command, not a test) builds every environment's graph exactly as the CLI receives it, once as configured and once with admin and backups on. It fails when a.env.examplevariable that a service reads (per-service-readsin the Makefile) is neither set nor ignored, or is both set and ignored, or when a TODO would be set.make deploy-check,make check-fastand CI's deploy task run it, and.env.exampleandMakefilechanges now trigger the deploy checks.unmanaged_variables.Not included (per-project, not template): any project's own variable list.
Verified
per_environment.production.public_url/from_emailset to TODO values: web sets 4 (noPUBLIC_URL/FROM_EMAIL), both are listed as left unset and ignored, and the check is ok.http://…/pathas public_url,from_email: nope, and an environment that isn't configured are all rejected.web/PUBLIC_URLinunmanaged_variablesfails with "set by the graph and also ignored".make check-fast(full run, since the Makefile changed): ok.make generate lint test deploy-check: 0 issues,-racetests on Postgres pass, coverage floors met.make actionlint: ok.Also: refuse the example sender before deploying (second commit)
deploy/platform.yamldefaultsemail.fromtonoreply@example.com, and every Railway service runs withAPP_ENV=production. With #103 (production refuses an unset or reserved-domainFROM_EMAIL), a freshrailway-applywould therefore deploy services that refuse to boot. Now:railway-planandrailway-applyfail before any Railway call when an environment's effective sender (per_environment.<env>.from_email, elseemail.from) is on a reserved domain. This uses the same rule as fix(config): production refuses an unset or example FROM_EMAIL #103:example.com/.net/.org,.example,.test,.invalid,.localhostand their subdomains, ina@borName <a@b>form. ATODOfrom_email isn't checked, because apply leaves that variable alone.railway-doctorreports it as a failingemail.fromcheck, with the fix, ahead of the login check.Proof, using a fake
railwayCLI (RAILWAY_BIN) that logs every call:make check-fastandmake deploy-check(includingdeploy-vars): ok.Risk
The first
railway-applyafter merging plans nothing new for a default config: the same variables are set, and the ignore list only grows. Someone who relied on apply deleting one of the newly ignored names would have to delete it by hand now. A project that adds settings must list them;make deploy-varstells them which ones.🤖 Generated with Claude Code