Add railway changes commands and route bucket/TCP proxy edits through staged changes#1000
Open
m-abdelwahab wants to merge 7 commits into
Open
Add railway changes commands and route bucket/TCP proxy edits through staged changes#1000m-abdelwahab wants to merge 7 commits into
m-abdelwahab wants to merge 7 commits into
Conversation
New command family (aliases: staged-changes, change) to review, deploy, and discard an environment's staged patch: - status: dashboard-style labels, --path filtering (subtree prefixes, * wildcards, escaped dots), --show-values, --json, --detailed-exit-code - deploy (alias apply): commits via environmentPatchCommitStaged, polls apply progress, warns on resource deletions, enforces 2FA for deletions and volume region moves - discard: --all, repeated --path, or interactive multi-select; partial discard re-stages the remaining patch as raw JSON so fields staged by other clients are preserved Adds an ExitCode sentinel error so --detailed-exit-code can exit 2 without printing an error while still running end-of-process work. The EnvironmentStagedChanges query gains createdAt/updatedAt/ lastAppliedError and decryptVariables.
staged_changes_status, staged_changes_deploy, and staged_changes_discard mirror the CLI commands. Variable values are masked by default in tool output (opt in via show_values); deletions requiring two-factor verification are refused over token auth. Also updates the create_bucket, remove_bucket, and create_tcp_proxy tool descriptions ahead of those operations moving to the staged workflow.
bucket create/delete and tcp-proxy create previously decided between committing immediately and staging based on unmergedChangesCount, which is no longer populated — so they always committed. They now always stage into the environment patch, matching the dashboard, and take effect on railway changes deploy. Deleting a live TCP proxy still applies immediately, also matching the dashboard. bucket delete and tcp-proxy delete additionally detect targets that only exist as staged creations and remove the pending change instead: proxies by staging null over the port entry, buckets by dropping the pending buckets.<id> subtree from the patch (the bucket itself remains at the project level). Applies to the equivalent MCP tools; scale keeps committing immediately as its help documents. Spinners in tcp-proxy create/delete are now only created when stdout is a terminal so success messages print in scripts.
Two fixes on the staging entry path: - CLI flags (--service-config) are now checked before piped stdin. Previously a non-terminal stdin was read first, so scripts passing flags silently staged nothing and exited 0. The 'No changes to apply' message also prints in non-interactive mode now. - Stdin JSON keyed by service name is resolved to the service ID before staging. Previously the patch was staged under the name key, which rendered as a duplicate resource group and produced a patch other clients don't recognize. Unknown services error with the available list; configuring one service by both name and ID is rejected. Staging output now points at railway changes for review and deploy.
Flows that stage changes (outbound IPv6, config apply) printed 'commit with railway environment edit' style hints. They now emit the shared staged-changes notice pointing at railway changes status/deploy.
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.
This PR gives the CLI first-class support for Railway's staged-changes workflow: a new
railway changescommand family to review, deploy, and discard the environment's staged patch, and parity with how the dashboard handles the operations that stage into it.Command surface
What the experience looks like
Changes staged from anywhere — the dashboard,
environment edit --stage, bucket/TCP-proxy commands, MCP agents — accumulate in one patch per environment. Every staging command tells you where to go next:Review renders the patch the way the dashboard's changes panel does, grouped by resource:
Deploy is all-or-nothing, so
discardis the pruning tool — drop what you don't want, then ship the rest as one commit:Destructive deploys warn first (on stderr), and 2FA is enforced when enabled:
For automation, everything speaks JSON and exit codes:
New command:
railway changes(aliases:staged-changes,change)status— staged changes with dashboard-style labels, raw dot paths, current/new values. Supports--pathfiltering (prefix matches a subtree,*matches one segment, literal dots escape as\.),--show-values(variables are masked by default),--json, and--detailed-exit-code(exit 2 when changes are pending).deploy(aliasapply) — commits the staged patch and polls apply progress.--yes,--message,--skip-deploys,--2fa-code. Warns on stderr before deploys that delete resources; 2FA is enforced for deletions and volume region moves. An accepted-but-still-applying commit reports as pending, not as a failure.discard—--all, repeated--path(subtree prefixes work), or an interactive multi-select. Partial discard re-stages the remaining patch as raw JSON so fields staged by other clients are never silently dropped.All subcommands are automation-safe:
--jsoneverywhere, and prompts are refused in non-interactive contexts with instructions instead.MCP tools
staged_changes_status,staged_changes_deploy,staged_changes_discardmirror the CLI. Variable values are masked by default in MCP output (opt in viashow_values); CLI--jsonreturns full values.Bucket and TCP proxy edits now go through staged changes⚠️ behavior change
The dashboard routes bucket create/delete and TCP proxy creation through the staged-changes workflow; the CLI committed them immediately. The CLI's existing "stage only when the environment has pending changes" heuristic keyed off
unmergedChangesCount, which is no longer populated — so the staging branch was unreachable and the CLI always committed. Rather than patch the heuristic, these operations now match the dashboard:bucket create— still creates the bucket immediately at the project level, but its appearance in the environment is now always staged.bucket delete— always stages the deletion.tcp-proxy create— always stages the networking change. Deleting a live proxy still takes effect immediately, same as the dashboard.scalestays commit-immediately, as its help documents.Migration: scripts that ran
railway bucket create/deleteorrailway tcp-proxy createand expected immediate effect must now follow withrailway changes deploy --yes. Every staging command prints a notice saying exactly that.Staged-resource deletion
tcp-proxy delete <port>andbucket deletedetect targets that exist only as staged (not yet deployed) creations and remove the pending change instead — same outcome as discarding the change in the dashboard. The bucket itself remains at the project level, consistent with dashboard behavior. No 2FA for these, since nothing deployed is destroyed.environment editfixes (staging entry path)--service-configflags and exited 0 doing nothing. "No changes to apply" also prints non-interactively now.Supporting changes
EnvironmentPatchCommitStagedand raw-configEnvironmentStageChangesRawmutations; theEnvironmentStagedChangesquery gainscreatedAt/updatedAt/lastAppliedErroranddecryptVariables.errors::ExitCodesentinel so--detailed-exit-codecan exit non-zero without printing an error while still running end-of-process work.railway changesinstead of "userailway environment editto commit".Testing
changes deploy; staged deletions warn and delete; staged-resource removal nets the patch to empty; all three MCP tools exercised over stdio.🤖 Generated with Claude Code