Features
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.
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 GitHub context that will be attached to the deployment
- the lock file path Rudel uses to prevent overlapping destructive operations
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
- copies sandbox DB and
wp-contentinto the app - rewrites runtime identifiers back to the app domain
- records a deployment ledger entry
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
- GitHub repo, 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.
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.