Skip to content
Kumar edited this page Sep 9, 2026 · 12 revisions

General hooks usage is described in movefile.yml configurations explained. This is a sort of F.A.Q. before any question has been made.

wordmove-ng supports running arbitrary commands during deploy operations. This is how they are represented in movefile.yml:

  hooks:
    push:
      before:
        - command: 'echo "do something"'
          where: local
          raise: false # raise is true by default
      after:
        - command: 'echo "do something"'
          where: remote
    pull:
      before:
        - command: 'echo "do something"'
          where: local
          raise: false
      after:
        - command: 'echo "do something"'
          where: remote

Hooks are optional. Remove the entire hooks key or configure just the hooks you need.

Each hook wants a sequence (the YAML representation of an array) of command objects.

Commands must be quoted. Prefer single quotes, since double quotes are often used inside the command itself.

Hooks are validated by wordmove-ng doctor.

Execution path

Both remote and local hooks run inside wordpress_path as per your movefile.yml. You can naturally change directory by chaining commands, e.g. cd other_dir && pwd.

How remote hooks are executed

Remote hooks use the same ssh settings as everything else (ssh.host, user, port, password, gateway) through the system ssh binary, and run inside sh -c. This means:

  • key authentication, agent and ~/.ssh/config work exactly as for rsync;
  • the command is interpreted by a POSIX sh regardless of the remote login shell;
  • programs must be in the $PATH of a non interactive login. If wp is not found, add its directory to PATH in ~/.bashrc or ~/.profile on the remote, or use an absolute path.

The output of a remote hook is logged with movefile secrets (passwords, hosts, vhosts, paths) masked as [secret].

Execution order

Hooks are executed in order and synchronously. What you read is what you get.

Error handling

By default a failing command (exit status > 0) raises and interrupts any further operation. Set raise: false on commands that may fail without mattering:

hooks:
  push:
    before:
      - command: 'exit 1'
        where: remote
        raise: false
      - command: 'echo "Still working"'
        where: local

The first command fails, the second is executed, and since these are before-push hooks the push happens too. The error is logged anyway.

Where to execute the command

where accepts local and remote. remote is always the environment given with -e, or the only remote when there is one. You cannot execute commands on other environments than the one you are pushing to or pulling from.

Why hooks, by examples

Feel free to populate this section with yours.

hooks:
  push:
    before:
      - command: 'npx webpack' # run webpack to build frontend
        where: local
      - command: 'rm -rf ./tmp/*' # blank local temp directory
        where: local
    after:
      - command: 'bash ./scripts/slack_notify.sh' # notify colleagues/customers on Slack
        where: local
      - command: 'wp rewrite flush' # you know that :)
        where: remote
      - command: 'wp cache flush'
        where: remote
      - command: 'wp option set blog_public 0' # hide WP from search engines on staging
        where: remote
      - command: 'find . -type f -exec chmod 664 {} +' # fix permissions
        where: remote
      - command: 'find . -type d -exec chmod 755 {} +'
        where: remote

Since wp maintenance-mode is handled by global.maintenance_mode, you no longer need hooks for that.

Credits

All started a long time ago in the feature request welaika/wordmove#143, opened by @joeguilmette. Thank you Joe!

Clone this wiki locally