cwp content push
shipped 1.0.0cwp content push [env] [flags]
Acts on the local site unless an environment is named.
| Argument | What it is | Default |
|---|---|---|
[env] | environment to write (omit for the local site) |
| Flag | What it does | Default |
|---|---|---|
--post <selector...> | slug, post id or URL — repeatable | |
--type <post_type> | restrict to one post type | |
--all | every post in scope | off |
--force | override the protected-environment refusal | off |
--no-backup | skip the remote backup taken before the write | on |
--yes | skip the confirmation prompt | off |
--overwrite-conflicts | overwrite posts that changed on the target since cwp last saw them | off |
--publish | publish a post that does not exist on the target yet | off |
--status <status> | set the status of every pushed post, new or existing | |
--media <mode> | attachments the target lacks: upload them, or require them to be there already | upload |
Plus the shared flags --json, --verbose and --dry-run.
What it does
Sends named posts from the committed tree to a site. Selection is explicit —
--post, --type or --all — and every affected post is listed before anything
happens.
What it refuses, and why each refusal is the point
A page changed on the target since cwp last saw it. Every transfer records
_cwp_sync, the hash of the item as cwp left that site, so a push can tell “the
tree moved” from “the site moved”. The second refuses with exit 5:
✗ 1 post(s) changed on "dev" since cwp last saw them
→ take their version with `cwp content pull dev --all`, or overwrite it with
--overwrite-conflicts — the changed ones are listed above
--force does not override this, and that is deliberate. The two questions
are unrelated: “yes, write to production” does not imply “yes, discard whatever an
editor changed there”. Until 1.0 one flag answered both, so anyone forced to
answer the first — which every push to a protected environment is — answered the
second by accident.
A reference the target does not have. An element tree names element types and global class and component ids, none of which travel with the page, and all of which fail the same silent way: the page saves, the markup renders, and what you built is not what appears.
Each kind gets its own line because the fixes differ: an element type is code
and travels with cwp deploy; a class or component is
design-system state and travels with cwp bricks push.
! 3 components are not on "dev": 3c9e7c, b38830, c72701
— send the design system first (`cwp bricks push dev`)
var(--x) is deliberately not checked. A CSS custom property is either a
Bricks global variable or a plain declaration in the theme stylesheet, and the
reference reads identically. On the first real page all five that an earlier
version flagged were theme CSS, while every genuine Bricks variable was already
on the target. A check that refuses correct pushes is worse than no check.
An attachment that is on neither side. --media upload, the default, sends
files the target lacks and names every one in the confirmation; --media require
refuses instead. Uploads go as base64 — Bricks’ upload ability rejects loopback
URLs by design, so “let the remote fetch it from my DDEV site” has no working
form. Files above 24 MB are refused with a measurement rather than a PHP memory
error.
Defaults that are guards
- A post that does not exist on the target is created as
draft.--publishor--statussays otherwise. An existing post’s status is not touched unless--statusis given: pushing a layout fix must not publish a page somebody parked, and must not unpublish a live one. - Nothing is ever deleted on the target, and there is no
--prune. - Meta cwp manages is replaced, not merged — a key the item no longer carries
disappears — but only keys the group’s own
includepatterns claim. A plugin’s meta cwp never carried is none of its business. - The usual set:
protectedrefuses without--force, a remote backup is taken first, the confirmation lists every affected post, and--dry-runruns every read-only preflight for real so the plan is truthful.
The rollback is per page
Bricks takes a revision before every element write, so each pushed page has an undo that costs nothing and undoes exactly that page — where the remote backup restores the whole app to fix one paragraph. The summary prints it:
push summary:
about-us → dev (post 12783) — roll back:
cwp ability bricks/restore-revision '{"revisionId":12791}' dev
Example
cwp content push dev --post about-us
cwp content push dev --all --dry-run
cwp content push prod --post about-us --force --publish
What it does not do
It deletes nothing on the target, pushes no media that exists on neither side, and merges nothing — a conflict is refused, not resolved.
It transfers no post type that no content group claims.