Files
ServerKit/builtin-extensions
Juan DenisandClaude Opus 5 3c84d152ea feat(wordpress): run environment promotions as watchable deployments
Promoting between WordPress environments ran in the request thread: no
console, no log stream, no retry, and a progress bar the pipeline page had
to keep alive itself. It now runs as a registered deployment kind, so it
inherits the Deploy Console, live logs, retry and a row in Deploy Activity.
POST /promote returns 202 with a job_id instead of blocking, and the UI
opens the console with it.

PromotionJob is kept, not replaced. It carries pre_promotion_snapshot_id,
the rollback pointer, which is WordPress domain a generic DeploymentJob has
no business holding — so the deployment records which promotion rows it
produced instead. They are collected by id watermark rather than from the
service's return value, because promote_* only reports the job on success
and a failed promotion is exactly when someone needs the snapshot.

A full promotion runs two five-step halves and restarts its own numbering
at 1 for the second, so the progress bridge carries an offset across the
reset — otherwise the console's step strip walks backwards halfway through.

Two gaps this exposed in the SDK, both fixed here:

- Plugin kinds never closed their log stream, so they got no per-step
  timings, no failure tail and no hint, and no terminal status push. The
  handler and the runner also built separate streams, so the timings one
  recorded were dropped by the other's close; they now share one per job.
- A handler that reported failure by return value logged nothing, leaving
  a failed run with no reason visible in the console.

The console now titles a run from plan.title, so a contributed kind names
itself without a branch per kind in the frontend.

A locked environment is refused by the endpoint rather than by the job:
queueing first would send the user to a console that fails a second later.
The pipeline service still re-checks, since a lock can be taken in between.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 13:29:12 -04:00
..