Skip to content

Add railway changes commands - #1000

Open
m-abdelwahab wants to merge 9 commits into
masterfrom
staged-changes
Open

Add railway changes commands#1000
m-abdelwahab wants to merge 9 commits into
masterfrom
staged-changes

Conversation

@m-abdelwahab

@m-abdelwahab m-abdelwahab commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

This PR gives the CLI first-class support for Railway's staged-changes workflow through a new railway changes command family to review, deploy, and discard an environment's staged patch.

Command surface

railway changes                                  # help (aliases: railway staged-changes, railway change)

railway changes status                           # show staged changes
    [--path <dot-path>]...                       # prefix matches a subtree, * matches one segment, \. escapes dots
    [--show-values]                              # show variable values instead of masking them
    [--detailed-exit-code]                       # exit 2 when changes are pending, 0 when none
    [--json]

railway changes deploy                           # deploy all staged changes (alias: apply)
    [-y | --yes]
    [-m | --message <message>]
    [--skip-deploys]
    [--2fa-code <code>]
    [--json]

railway changes discard                          # discard staged changes
    [--all]
    [--path <dot-path>]...
    [-y | --yes]
    [--json]

Global on all subcommands: -p/--project and -e/--environment, defaulting to the linked project and environment.

Behavior

  • status renders staged changes with dashboard-style labels, raw dot paths, and current/new values. It supports subtree and wildcard path filtering, masked variables by default, JSON output, and Terraform-style detailed exit codes.
  • deploy commits the complete staged patch and polls its apply progress. It supports custom messages, skipping deploys, destructive-change warnings, and 2FA when required.
  • discard can remove the whole patch, selected paths, or an interactive multi-selection. Partial discard re-stages the remaining raw JSON patch so fields created by other clients are preserved.
  • Prompts are refused in non-interactive contexts with actionable instructions, and every subcommand supports automation-friendly JSON output.

Supporting changes

  • Add the EnvironmentPatchCommitStaged and raw-config EnvironmentStageChangesRaw mutations.
  • Extend EnvironmentStagedChanges with timestamps, apply errors, and optional variable decryption.
  • Add an errors::ExitCode sentinel so --detailed-exit-code can return a non-zero status without printing an error or skipping end-of-process work.

Follow-up

This PR intentionally defers the following work to follow-up PRs:

  • Migrating existing bucket and networking commands to use staged changes.
  • Adding MCP tools for reviewing, deploying, and discarding staged changes.

Validation

  • cargo fmt --all -- --check
  • cargo check
  • cargo test — 420 passed
  • Verified help output for railway changes and its status, deploy, and discard subcommands.
  • Live E2E: staged → reviewed → filtered → partially discarded → deployed, with variables verified after apply.

🤖 Generated with Claude Code

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.
@m-abdelwahab m-abdelwahab added the release/minor Author minor release label Jul 7, 2026
@m-abdelwahab m-abdelwahab changed the title Add railway changes commands and route bucket/TCP proxy edits through staged changes Add railway changes commands Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release/minor Author minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant