Skip to content

cwp push

shipped 1.0.0
cwp push [env] [flags]

Acts on dev unless another environment is named.

ArgumentWhat it isDefault
[env]environment to write todev
FlagWhat it doesDefault
--forceoverride the protected-environment refusaloff
--no-backupskip the remote backup taken before the transferon
--deletemirror: also remove remote files that are absent locallyoff
--yesskip the confirmation promptoff

Plus the shared flags --json, --verbose and --dry-run.

What it does

Transfers the tracked paths from .cwp.yml up to an environment. Every step is a guard, in this order:

  1. Refuse if the environment is protected and --force was not given — exit 5.
  2. Resolve tracked. An empty list, a missing path or one outside the docroot is refused, never interpreted.
  3. Show what would move and ask for confirmation, unless --yes. Exit 6 when cwp cannot prompt.
  4. Run pre-push.sh. A non-zero exit aborts.
  5. Take a remote backup, unless --no-backup.
  6. Transfer, hand the files to the user WordPress runs as, then verify every file by digest.

Nothing happens at all until the confirmation passes: a refused push takes no backup and does not run your hook.

cwp deploy is this command plus the remote post-steps and the post-deploy hook. They share one implementation, so their flags and guards cannot drift apart.

Additive by default, mirror with --delete

cloudron sync push only ever adds and overwrites. A file you delete locally stays on the remote — and in a plugin directory it keeps being loaded, so a file you think you removed can still be running. That is the default, because deleting live files as a side effect of a routine deploy is exactly the surprise this tool exists to prevent.

The default is not silent about it. When the remote holds files your tracked path does not, cwp says so and names the count. --delete mirrors instead, and it sits behind every guard above: protected environments still refuse, the confirmation still runs and says outright that files will be deleted, and the backup is still taken first. cwp push --delete --dry-run lists the exact files it would remove and changes nothing.

Verification, and why it is per file

After the transfer, cwp compares an md5sum of every remote file against your local tree. A file that never arrived, or arrived with different contents, fails the push and is named.

This matters because cloudron sync decides what to send by size and mtime. A remote file corrupted to the same length with its mtime intact is reported as Already up to date and never resent — so re-running the push does not repair it. Force a resend by touching the local file, or delete the remote copy. The error says so.

If the remote image has no md5sum, cwp warns and falls back to comparing file counts: weaker, but it does not fail a good push.

What the dry run can and cannot tell you

The plan is the tracked paths, their local file counts and their remote targets. It is not a file-level diff — the Cloudron provider has no transfer dry run, so what differs is only knowable by sending it, and the dry run says that in as many words rather than leaving it to be inferred. On the ssh provider it is a file-level diff, because rsync has one.

With --delete the deletion set is listed exactly, because that one can be computed from a remote listing.

--json records which guards ran

Every push and deploy carries a guards object saying what each guard decided — whether the protected-environment refusal applied, whether a restore point was taken or waived, and whether the change had a committed source:

{ "guards": { "protectedEnvironment": "passed-with-force",
              "restorePoint": "taken",
              "source": "present" } }

A guard that silently did not run is a missing line there, rather than something only a reading of the source would reveal.

Example

cwp push dev --dry-run           # see what would be sent
cwp push dev --delete --dry-run  # see what would be sent *and removed*
cwp push prod --force            # prod is protected; --force is required

What it does not do

It does not push the database. There is no upward database command in cwp, and cwp deploy is not one — it moves the tracked files. Moving a whole database upward was designed and then deferred; see Safety for what that decision was and why.

It does not push anything outside the tracked list, run hooks during a dry run, or delete anything remotely unless you pass --delete.