Deploy History
Apps are long-lived deploy targets. Sandboxes are where you prepare change. The deploy history layer is what connects those two sides safely.
That history matters because deployment is not just a file copy. It is an operational decision that should leave behind a trail: what moved, when it moved, what backup was created, and what source environment supplied the new state.
Dry-run first
Before replacing an app, generate a deploy plan:
wp rudel app deploy client-a-com-a1b2 --from=client-a-feature-a1b2 --backup=before-launch --dry-runThat shows:
- which app and sandbox are involved
- the backup name that will be created
- the tracked Git context that will be attached to the deployment
- the lock file path Rudel uses to prevent overlapping destructive operations
Dry-run is not a nice-to-have here. It is the moment where operators can confirm that the right sandbox is about to affect the right app before anything destructive happens.
Real deploy
wp rudel app deploy client-a-com-a1b2 --from=client-a-feature-a1b2 --backup=before-launch --label="Launch candidate" --notes="Approved after QA sign-off" --forceEvery deploy:
- creates or uses an app backup
- replaces the app with the sandbox's site state and tracked content
- rewrites runtime identifiers back to the app domain
- records a deployment ledger entry
That ledger entry is what turns deploys into an understandable history instead of a series of undocumented replacements.
Inspect history
wp rudel app deployments client-a-com-a1b2Each deployment record stores:
- deployment ID
- deployed sandbox ID and name
- deploy timestamp
- backup name for rollback
- copied table count
- label and notes
- Git remote, base branch, and directory context
Roll back
Rudel now exposes rollback as a first-class app operation:
wp rudel app rollback client-a-com-a1b2 --deployment=deploy-20260330-123456 --forceRollback restores the backup referenced by that deployment record. You can still restore directly from a named backup if you want, but rollback is cleaner when operators are reasoning from deploy history rather than filesystem names.
In practice, that is what makes the feature valuable: you can reason from "the deploy that introduced this issue" instead of from "the backup name somebody probably typed before a release."
API
use Rudel\Rudel;
$plan = Rudel::plan_app_deploy( $app_id, $sandbox_id, 'before-launch' );
$result = Rudel::deploy_sandbox_to_app( $app_id, $sandbox_id, 'before-launch', [
'label' => 'Launch candidate',
] );
$rollback = Rudel::rollback_app_deployment( $app_id, $result['deployment']['id'] );That API is intentionally explicit: plan, deploy, inspect history, roll back.