wordmove-ng 6.0.0 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/pages.yml +52 -0
- data/.github/workflows/release.yml +15 -2
- data/.gitignore +2 -0
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +15 -1
- data/CLAUDE.md +9 -1
- data/README.md +26 -9
- data/contrib/wordmove-sync.sh +73 -0
- data/docs/Gemfile +4 -0
- data/docs/README.md +10 -0
- data/docs/_config.yml +47 -0
- data/docs/assets/images/wordmove-ng.png +0 -0
- data/docs/automation.md +166 -0
- data/docs/configuration.md +345 -0
- data/docs/contributing.md +55 -0
- data/docs/database-sync.md +91 -0
- data/docs/environments.md +65 -0
- data/docs/hooks.md +103 -0
- data/docs/index.md +59 -0
- data/docs/installation.md +104 -0
- data/docs/quick-start.md +81 -0
- data/docs/troubleshooting.md +141 -0
- data/docs/upgrading.md +61 -0
- data/docs/usage.md +129 -0
- data/lib/wordmove/version.rb +1 -1
- data/wordmove-ng.gemspec +1 -1
- metadata +20 -2
data/docs/index.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction
|
|
3
|
+
nav_order: 1
|
|
4
|
+
permalink: /
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# wordmove-ng
|
|
8
|
+
{: .fs-9 }
|
|
9
|
+
|
|
10
|
+
Move WordPress sites between environments with one command: files and database, in both directions, over SSH.
|
|
11
|
+
{: .fs-6 .fw-300 }
|
|
12
|
+
|
|
13
|
+
[Install]({{ site.baseurl }}/installation/){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
|
14
|
+
[Quick start]({{ site.baseurl }}/quick-start/){: .btn .fs-5 .mb-4 .mb-md-0 .mr-2 }
|
|
15
|
+
[Upgrading from 5.x]({{ site.baseurl }}/upgrading/){: .btn .fs-5 .mb-4 .mb-md-0 }
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
wordmove-ng pushes or pulls the WordPress core, uploads, themes, plugins, mu-plugins, languages and the database between a local install and any number of remote hosts. Files travel with `rsync`; the database is dumped at the source, imported at the target and adapted there with `wp search-replace`, so URLs and paths always match the destination.
|
|
20
|
+
|
|
21
|
+
It is the maintained, independent successor of [Wordmove](https://github.com/welaika/wordmove) by weLaika, continued through the [kokiddp fork](https://github.com/kokiddp/wordmove). The `movefile.yml` format, the commands and the flags are unchanged; the internals were modernised and a few unsafe behaviours removed. If you come from either project, read [Upgrading from wordmove 5.x]({{ site.baseurl }}/upgrading/).
|
|
22
|
+
|
|
23
|
+
## How it works
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
push ───────────────▶
|
|
27
|
+
local ┌────────────┐ ┌────────────┐ remote
|
|
28
|
+
│ wordpress │ rsync │ wordpress │
|
|
29
|
+
│ wp-content │ ─────────▶ │ wp-content │
|
|
30
|
+
│ │ ◀───────── │ │
|
|
31
|
+
│ database │ dump/scp │ database │
|
|
32
|
+
└────────────┘ └────────────┘
|
|
33
|
+
◀─────────────── pull
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Every remote operation uses the system `ssh`, `scp` and `rsync`. Your ssh-agent, `~/.ssh/config`, jump hosts and modern key types all work exactly as on the command line, and nothing breaks on a new OpenSSL or Ruby release.
|
|
37
|
+
- The **source** database is only ever read. Both directions dump the source, import on the target, then run `wp search-replace` on the target. A backup of the target database is taken first.
|
|
38
|
+
- Prerequisites on both sides are probed before any backup, dump or import, so a misconfigured host fails before it can do harm. `wordmove-ng doctor` performs the same checks on demand.
|
|
39
|
+
- Optional [maintenance mode]({{ site.baseurl }}/database-sync/#maintenance-mode) hides the database replacement from visitors.
|
|
40
|
+
- MariaDB and MySQL are both supported, with sandbox-header handling, collation and charset normalisation, socket and port support.
|
|
41
|
+
- Runs on Ruby 3.0 through 4.0.
|
|
42
|
+
|
|
43
|
+
## Where to go next
|
|
44
|
+
|
|
45
|
+
| I want to… | Read |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| install it | [Installation]({{ site.baseurl }}/installation/) |
|
|
48
|
+
| sync my first site | [Quick start]({{ site.baseurl }}/quick-start/) |
|
|
49
|
+
| move from `wordmove` 5.x | [Upgrading]({{ site.baseurl }}/upgrading/) |
|
|
50
|
+
| understand every `movefile.yml` key | [Configuration]({{ site.baseurl }}/configuration/) |
|
|
51
|
+
| know what each flag does | [Usage and flags]({{ site.baseurl }}/usage/) |
|
|
52
|
+
| know exactly what happens to my database | [Database sync]({{ site.baseurl }}/database-sync/) |
|
|
53
|
+
| run commands before or after a deploy | [Hooks]({{ site.baseurl }}/hooks/) |
|
|
54
|
+
| schedule syncs from cron or CI | [Automation and cron]({{ site.baseurl }}/automation/) |
|
|
55
|
+
| fix a problem | [Troubleshooting]({{ site.baseurl }}/troubleshooting/) |
|
|
56
|
+
|
|
57
|
+
## Credits
|
|
58
|
+
|
|
59
|
+
Wordmove was created and maintained for a decade by [weLaika](https://dev.welaika.com): Stefano Verna, Ju Liu, Fabrizio Monti, Alessandro Fazzi, Filippo Gangi Dino and [many contributors](https://github.com/welaika/wordmove/graphs/contributors). The workflow, the movefile format and most of the code are theirs. [kokiddp](https://github.com/kokiddp/wordmove) kept it running on modern Ruby, OpenSSL 3 and MariaDB. wordmove-ng is maintained by [tekgnosis.net](https://github.com/tekgnosis-net) under the MIT licence.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Installation
|
|
3
|
+
nav_order: 2
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Installation
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
1. TOC
|
|
10
|
+
{:toc}
|
|
11
|
+
|
|
12
|
+
## Ruby
|
|
13
|
+
|
|
14
|
+
wordmove-ng needs **Ruby 3.0 or newer**. Check with `ruby --version`. If your system Ruby is older or missing, use a version manager:
|
|
15
|
+
|
|
16
|
+
- [rbenv](https://github.com/rbenv/rbenv#installation)
|
|
17
|
+
- [RVM](https://rvm.io/)
|
|
18
|
+
- [mise](https://mise.jdx.dev/) (`mise use -g ruby@3.4`)
|
|
19
|
+
|
|
20
|
+
## The gem
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
gem install wordmove-ng
|
|
24
|
+
wordmove-ng --version
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To run the latest `master` instead of a release:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
gem install specific_install
|
|
31
|
+
gem specific_install https://github.com/tekgnosis-net/wordmove-ng.git
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
From a checkout, for development:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/tekgnosis-net/wordmove-ng.git
|
|
38
|
+
cd wordmove-ng
|
|
39
|
+
bundle install
|
|
40
|
+
bin/wordmove-ng --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The legacy `wordmove` 5.x gem can stay installed alongside: the executables have different names.
|
|
44
|
+
|
|
45
|
+
## Peer dependencies
|
|
46
|
+
|
|
47
|
+
wordmove-ng is orchestration glue around standard tools. `wordmove-ng doctor` reports exactly what is missing on which side, and every database operation re-checks before doing anything.
|
|
48
|
+
|
|
49
|
+
### Locally
|
|
50
|
+
|
|
51
|
+
| Program | Needed for |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `ssh`, `scp`, `rsync` | every remote operation |
|
|
54
|
+
| `sshpass` | only when `ssh.password` is set in the movefile |
|
|
55
|
+
| `gzip` | database sync |
|
|
56
|
+
| `mysqldump` or `mariadb-dump` | `push -d` (dumping the local database) |
|
|
57
|
+
| `mysql` or `mariadb` | `pull -d` (importing into the local database) and `doctor` |
|
|
58
|
+
| `wp` ([WP-CLI](https://wp-cli.org)) | `pull -d` (adapting the local database) |
|
|
59
|
+
|
|
60
|
+
### On each remote
|
|
61
|
+
|
|
62
|
+
In the `$PATH` of a **non interactive** login. Check with `ssh host 'echo $PATH'`.
|
|
63
|
+
|
|
64
|
+
| Program | Needed for |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `rsync`, `gzip` | file and database sync |
|
|
67
|
+
| `mysqldump` or `mariadb-dump` | `pull -d` |
|
|
68
|
+
| `mysql` or `mariadb`, `wp` | `push -d` |
|
|
69
|
+
|
|
70
|
+
WP-CLI is a single PHAR file. If your host does not ship it, put it in `~/bin` and add that directory to `PATH` in `~/.bashrc` or `~/.profile`: [installing WP-CLI](https://wp-cli.org/#installing).
|
|
71
|
+
|
|
72
|
+
## Platform notes
|
|
73
|
+
|
|
74
|
+
### macOS
|
|
75
|
+
|
|
76
|
+
Install [Homebrew](https://brew.sh), then `brew install rsync`. Local database tools come with your MySQL/MariaDB or with tools such as MAMP or Local; make sure their `bin` directory is in your `PATH` (see [Troubleshooting]({{ site.baseurl }}/troubleshooting/#mysqldump-command-not-found-locally)). `sshpass` is only needed for password authentication (`brew install hudochenkov/sshpass/sshpass`); prefer keys.
|
|
77
|
+
|
|
78
|
+
### Linux
|
|
79
|
+
|
|
80
|
+
Everything comes from your distribution: for Debian and Ubuntu `sudo apt install rsync gzip openssh-client mariadb-client`, then WP-CLI as above.
|
|
81
|
+
|
|
82
|
+
### Windows
|
|
83
|
+
|
|
84
|
+
Use WSL (Windows Subsystem for Linux) and run wordmove-ng inside the Linux distribution. Native Windows is not supported.
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
wsl --install
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Then, inside the Ubuntu shell:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
sudo apt update
|
|
94
|
+
sudo apt install -y ruby-full build-essential rsync gzip openssh-client mariadb-client
|
|
95
|
+
sudo gem install wordmove-ng
|
|
96
|
+
ssh-keygen -t ed25519
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Add `~/.ssh/id_ed25519.pub` to your host. In `movefile.yml` use Linux paths (`C:\` becomes `/mnt/c/`) and `127.0.0.1` rather than `localhost` for a MySQL server running on Windows. Files under `/mnt/c` all appear with permissions `777`; to get sane permissions on the server add
|
|
100
|
+
|
|
101
|
+
```yaml
|
|
102
|
+
ssh:
|
|
103
|
+
rsync_options: "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r"
|
|
104
|
+
```
|
data/docs/quick-start.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quick start
|
|
3
|
+
nav_order: 3
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quick start
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
1. TOC
|
|
10
|
+
{:toc}
|
|
11
|
+
|
|
12
|
+
## 1. Create the movefile
|
|
13
|
+
|
|
14
|
+
Run `init` from the directory that contains `wp-config.php`:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cd /path/to/your/wordpress
|
|
18
|
+
wordmove-ng init
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
It writes `movefile.yml`, pre-filled with the local database credentials, socket or port from `wp-config.php` and the local URL from `WP_HOME`/`WP_SITEURL` or `wp option get home`. Open the file and fill in the `production` section (rename it as you like): the remote `vhost`, `wordpress_path`, database credentials **as seen from the remote host**, and the `ssh` block.
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
production:
|
|
25
|
+
vhost: https://example.com
|
|
26
|
+
wordpress_path: /var/www/example
|
|
27
|
+
database:
|
|
28
|
+
name: example
|
|
29
|
+
user: example
|
|
30
|
+
password: "<%= ENV['PROD_DB_PASS'] %>"
|
|
31
|
+
host: localhost
|
|
32
|
+
ssh:
|
|
33
|
+
host: example.com
|
|
34
|
+
user: deploy
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The full reference is in [Configuration]({{ site.baseurl }}/configuration/).
|
|
38
|
+
|
|
39
|
+
## 2. Check everything
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
wordmove-ng doctor
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The doctor validates the movefile, checks the local tools and database connection, then for each SSH remote tries a non interactive login and probes for `rsync`, `gzip`, `mysql`, `mysqldump` and `wp`. Fix what it reports before going on.
|
|
46
|
+
|
|
47
|
+
## 3. Pull the site down
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
wordmove-ng pull -e production --all
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Files are mirrored into your local install, the remote database is dumped, imported locally and rewritten to your local URL and path. Your previous local database is saved as `wp-content/local-backup-<timestamp>.sql.gz` first.
|
|
54
|
+
|
|
55
|
+
## 4. Push changes up
|
|
56
|
+
|
|
57
|
+
Simulate first: `-s` runs rsync with `--dry-run` and skips the database steps after logging what would happen.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
wordmove-ng push -e production -t -p -s # themes and plugins, dry run
|
|
61
|
+
wordmove-ng push -e production -t -p # for real
|
|
62
|
+
wordmove-ng push -e production -d # database only
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
A push of the database backs up the remote database to `wp-content/production-backup-<timestamp>.sql.gz` locally, dumps your local database, imports it on the remote and runs `wp search-replace` there. Your local database is never modified.
|
|
66
|
+
|
|
67
|
+
## Everyday commands
|
|
68
|
+
|
|
69
|
+
| Command | Effect |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `wordmove-ng pull -e staging -u` | fetch the uploads folder from staging |
|
|
72
|
+
| `wordmove-ng push -e production --all --no-db` | mirror every folder, keep the production database |
|
|
73
|
+
| `wordmove-ng push -e production --all --no-uploads` | everything but uploads |
|
|
74
|
+
| `wordmove-ng pull -e production -d --no-adapt` | import the production database without rewriting URLs |
|
|
75
|
+
| `wordmove-ng list` | show every environment and its vhost |
|
|
76
|
+
| `wordmove-ng help push` | all flags |
|
|
77
|
+
|
|
78
|
+
With a single remote environment `-e` can be omitted. Every flag is explained in [Usage and flags]({{ site.baseurl }}/usage/).
|
|
79
|
+
|
|
80
|
+
{: .warning }
|
|
81
|
+
File sync **mirrors** the source: files missing at the source are deleted at the destination. Anything you need to keep on one side only goes in `exclude`.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Troubleshooting
|
|
3
|
+
nav_order: 11
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Troubleshooting and FAQ
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
Start with `wordmove-ng doctor`: it reproduces most problems below and names the failing command.
|
|
10
|
+
|
|
11
|
+
1. TOC
|
|
12
|
+
{:toc}
|
|
13
|
+
|
|
14
|
+
## SSH
|
|
15
|
+
|
|
16
|
+
### Non interactive SSH authentication failed
|
|
17
|
+
{: .no_toc }
|
|
18
|
+
|
|
19
|
+
wordmove-ng runs `ssh` with `BatchMode=yes` when no `ssh.password` is configured, so it never prompts. The doctor prints the exact command, for example `ssh -o BatchMode=yes -p 22 deploy@example.com true`; run it yourself to see what OpenSSH says. Usual causes: the key is not loaded in the agent (`ssh-add -l`), the host expects a different user, or the key is not in the remote `authorized_keys`. Anything you fix in `~/.ssh/config` applies to wordmove-ng automatically.
|
|
20
|
+
|
|
21
|
+
### It worked with wordmove 5.x and rsync still works, but the database step asked for a password
|
|
22
|
+
{: .no_toc }
|
|
23
|
+
|
|
24
|
+
That was the old Net::SSH library, which could not sign RSA keys with SHA-2 and silently fell back to a prompt on modern servers. wordmove-ng no longer contains it. See [Upgrading]({{ site.baseurl }}/upgrading/#7-ssh-behaves-like-rsync-did).
|
|
25
|
+
|
|
26
|
+
### Gateway / jump host
|
|
27
|
+
{: .no_toc }
|
|
28
|
+
|
|
29
|
+
`ssh.gateway` is passed as `ssh -J`; the bastion must accept your key or agent. `gateway.password` cannot be used. Alternatively configure `ProxyJump` in `~/.ssh/config` and only set `ssh.host`.
|
|
30
|
+
|
|
31
|
+
### Password authentication
|
|
32
|
+
{: .no_toc }
|
|
33
|
+
|
|
34
|
+
`ssh.password` requires `sshpass` installed locally and exposes the password in the process list. Keys are strongly recommended.
|
|
35
|
+
|
|
36
|
+
## Missing programs
|
|
37
|
+
|
|
38
|
+
### `Missing programs required for the database sync (on "production": wp)`
|
|
39
|
+
{: .no_toc }
|
|
40
|
+
|
|
41
|
+
The remote needs `wp` (for push) in the `$PATH` of a **non interactive** login, which usually only reads `~/.bashrc` or `~/.profile`. Check with `ssh host 'command -v wp'`. Install WP-CLI as a PHAR in `~/bin` and add it to `PATH` in one of those files. The same applies to `gzip`, `mysql`/`mariadb` and `mysqldump`/`mariadb-dump`.
|
|
42
|
+
|
|
43
|
+
### `mysqldump: command not found` locally
|
|
44
|
+
{: .no_toc }
|
|
45
|
+
|
|
46
|
+
Bundled stacks such as MAMP, XAMPP or Local keep the MySQL binaries out of your `PATH`. Find them (`sudo find /Applications -type f -name mysqldump` on macOS) and add the directory to your shell profile:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
echo 'export PATH="/Applications/MAMP/Library/bin:$PATH"' >> ~/.zshrc
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Reopen the terminal; `wordmove-ng doctor` should now find them.
|
|
53
|
+
|
|
54
|
+
## Database
|
|
55
|
+
|
|
56
|
+
### Import fails with a collation or charset error
|
|
57
|
+
{: .no_toc }
|
|
58
|
+
|
|
59
|
+
Newer `utf8mb3` collations are rewritten automatically before import. If your dump uses another collation the target does not know, add it to `global.collation_fallbacks`; see [Database sync]({{ site.baseurl }}/database-sync/#mariadb-and-mysql-compatibility).
|
|
60
|
+
|
|
61
|
+
### `invalid byte sequence in UTF-8`
|
|
62
|
+
{: .no_toc }
|
|
63
|
+
|
|
64
|
+
wordmove-ng no longer rewrites dumps as text for URL adaptation, so this error from older versions should not occur. Binary or `latin1` data can still upset a transfer between servers with different defaults: add `--hex-blob` to `mysqldump_options` (thanks @360Zen), make sure your columns are `utf8mb4`, and use a UTF-8 locale in your shell (`export LC_ALL=en_US.UTF-8`). Tables of third party plugins can be skipped with `--ignore-table=db.table`.
|
|
65
|
+
|
|
66
|
+
### `wordmove-ng init` fails with `invalid byte sequence in UTF-8`
|
|
67
|
+
{: .no_toc }
|
|
68
|
+
|
|
69
|
+
Some localized WordPress packages ship a `wp-config-sample.php` encoded in `iso-8859-1`, and people copy it to `wp-config.php`. Convert the file:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
iconv -f ISO-8859-1 -t UTF-8 wp-config.php > wp-config.utf8.php && mv wp-config.utf8.php wp-config.php
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### The remote site shows my local URLs after a push
|
|
76
|
+
{: .no_toc }
|
|
77
|
+
|
|
78
|
+
The import succeeded but `wp search-replace` on the remote failed; the log names the backup file. Run the search-replace by hand or restore, see [Backups and recovery]({{ site.baseurl }}/database-sync/#backups-and-recovery). Enable `global.maintenance_mode` to hide this window from visitors.
|
|
79
|
+
|
|
80
|
+
### Different table prefixes
|
|
81
|
+
{: .no_toc }
|
|
82
|
+
|
|
83
|
+
Not supported: local and remote must use the same `$table_prefix`.
|
|
84
|
+
|
|
85
|
+
### Large databases time out
|
|
86
|
+
{: .no_toc }
|
|
87
|
+
|
|
88
|
+
Raise `max_allowed_packet` and use `--single-transaction --quick` through `mysqldump_options` and `mysql_options`; see [Large databases]({{ site.baseurl }}/database-sync/#large-databases).
|
|
89
|
+
|
|
90
|
+
## Files
|
|
91
|
+
|
|
92
|
+
### Files I need were deleted
|
|
93
|
+
{: .no_toc }
|
|
94
|
+
|
|
95
|
+
Sync mirrors the source. Anything that must survive on one side only (uploads created on production, `.env`, caches) belongs in `exclude`. Backups of the database are never deleted by a sync, but add `wp-content/*.sql.gz` to `exclude` so they are not copied either.
|
|
96
|
+
|
|
97
|
+
### Permissions are wrong on the server
|
|
98
|
+
{: .no_toc }
|
|
99
|
+
|
|
100
|
+
Use `rsync_options: "--chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r"` (or a post-push hook with `find … -exec chmod`) and consider `--no-perms` from a CI runner; see [Usage]({{ site.baseurl }}/usage/#rsync-options-in-a-continuous-delivery-context).
|
|
101
|
+
|
|
102
|
+
### Security plugins
|
|
103
|
+
{: .no_toc }
|
|
104
|
+
|
|
105
|
+
Plugins such as Wordfence write `.user.ini` and firewall files into the WordPress root that are specific to one host. Exclude them, or deactivate the plugin locally with a pull hook.
|
|
106
|
+
|
|
107
|
+
## Movefile
|
|
108
|
+
|
|
109
|
+
### `This remote is configured with ftp`
|
|
110
|
+
{: .no_toc }
|
|
111
|
+
|
|
112
|
+
FTP was removed in 6.0. Move the host to SSH or keep the legacy `wordmove` 5.x gem for it.
|
|
113
|
+
|
|
114
|
+
### `global.sql_adapter … is ignored`
|
|
115
|
+
{: .no_toc }
|
|
116
|
+
|
|
117
|
+
Harmless leftover from 5.x; delete the key.
|
|
118
|
+
|
|
119
|
+
### `"…" is a prefix of "…"`
|
|
120
|
+
{: .no_toc }
|
|
121
|
+
|
|
122
|
+
Two of the four search terms overlap; use distinct vhosts and paths, see [Prefix collisions]({{ site.baseurl }}/database-sync/#prefix-collisions).
|
|
123
|
+
|
|
124
|
+
### YAML errors
|
|
125
|
+
{: .no_toc }
|
|
126
|
+
|
|
127
|
+
Indentation is the structure: two spaces, no tabs. Quote values containing `:` or `#`. The doctor prints the path of the offending key.
|
|
128
|
+
|
|
129
|
+
## FAQ
|
|
130
|
+
|
|
131
|
+
**Which transport is used?** SSH only: `rsync -e ssh` for directories, `ssh` for commands and hooks, `scp` for dump files. There is no Ruby-side SSH implementation.
|
|
132
|
+
|
|
133
|
+
**Is the source database ever modified?** No. It is dumped; the import and the URL rewriting happen on the target.
|
|
134
|
+
|
|
135
|
+
**Is there a rollback?** Backups of the target database are written to the local `wp-content` before every import; restore them by hand.
|
|
136
|
+
|
|
137
|
+
**Is it transactional?** No. Prerequisites are checked before anything happens, and each step is logged, but an interruption in the middle can leave a `dump.sql` or `dump.sql.gz` in a `wp-content` folder, or the target with the source's URLs. Re-run the command or restore the backup.
|
|
138
|
+
|
|
139
|
+
**What is left on my server?** Nothing but the site itself. Temporary dumps are removed after each run.
|
|
140
|
+
|
|
141
|
+
**Windows?** Through WSL only; see [Installation]({{ site.baseurl }}/installation/#windows).
|
data/docs/upgrading.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Upgrading from 5.x
|
|
3
|
+
nav_order: 4
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Upgrading from wordmove 5.x
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
This applies to both the original `wordmove` gem by weLaika and the kokiddp fork. Your `movefile.yml` keeps working with the exceptions below.
|
|
10
|
+
|
|
11
|
+
1. TOC
|
|
12
|
+
{:toc}
|
|
13
|
+
|
|
14
|
+
## 1. Install the new gem, use the new command
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
gem install wordmove-ng
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Call `wordmove-ng` instead of `wordmove`. Both gems can stay installed side by side; the executable was renamed on purpose, because both tools read the same `movefile.yml` while their push semantics differ.
|
|
21
|
+
|
|
22
|
+
## 2. Ruby 3.0 or newer
|
|
23
|
+
|
|
24
|
+
Ruby 2.6 and 2.7 are no longer supported. See [Installation]({{ site.baseurl }}/installation/#ruby).
|
|
25
|
+
|
|
26
|
+
## 3. Put `wp` on your remotes
|
|
27
|
+
|
|
28
|
+
`push -d` now adapts the database **on the remote**, so WP-CLI must be installed there and be in the `$PATH` of a non interactive login. It is a single PHAR file ([installing WP-CLI](https://wp-cli.org/#installing)). Run `wordmove-ng doctor` to confirm; a push refuses to start until it is found.
|
|
29
|
+
|
|
30
|
+
## 4. FTP and SFTP are gone
|
|
31
|
+
|
|
32
|
+
A movefile with an `ftp` block fails with a clear error. FTP only ever existed for shell-less shared hosts, where the database had to be handled by uploading temporary PHP scripts and URLs were rewritten in the dump with a regex. Keep the legacy `wordmove` 5.x gem for such hosts, or move them to SSH.
|
|
33
|
+
|
|
34
|
+
## 5. `global.sql_adapter` is ignored
|
|
35
|
+
|
|
36
|
+
URL and path adaptation always uses `wp search-replace` on the target; the regex-based `default` adapter no longer exists. The key is still accepted, with a warning, so old movefiles validate. Remove it when convenient. `database.charset`, removed in 3.0, is no longer accepted by the schema either. The `global` section is now optional.
|
|
37
|
+
|
|
38
|
+
## 6. Push no longer touches your local database
|
|
39
|
+
|
|
40
|
+
Old versions ran `wp search-replace` on the live local database during a push and restored it afterwards, which left the local site pointing at production if anything failed in between. That is gone: the local database is dumped, and the dump is adapted after import on the remote.
|
|
41
|
+
|
|
42
|
+
## 7. SSH behaves like rsync did
|
|
43
|
+
|
|
44
|
+
If rsync worked but the database step asked for a password, the cause was the old Net::SSH library, which could not sign RSA keys with SHA-2 and silently fell back to a prompt. That code path no longer exists: everything uses the system `ssh` client. If key authentication fails now, you get an error naming the failed command instead of a prompt. `ssh.gateway` is passed as `ssh -J`; `ssh.gateway.password` cannot be honoured and is ignored.
|
|
45
|
+
|
|
46
|
+
## 8. Remote programs are checked up front
|
|
47
|
+
|
|
48
|
+
Missing `gzip`, `mysql`, `mysqldump` or `wp` on either side aborts before any backup or dump, listing what is missing.
|
|
49
|
+
|
|
50
|
+
## 9. New, optional: maintenance mode
|
|
51
|
+
|
|
52
|
+
`global.maintenance_mode: true` wraps the target's import and search-replace in `wp maintenance-mode activate` / `deactivate`. See [Database sync]({{ site.baseurl }}/database-sync/#maintenance-mode).
|
|
53
|
+
|
|
54
|
+
## Checklist
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
gem install wordmove-ng
|
|
58
|
+
sed -i '/sql_adapter/d' movefile.yml # optional tidy-up
|
|
59
|
+
wordmove-ng doctor # fix anything it reports
|
|
60
|
+
wordmove-ng push -e production -d -s # dry run
|
|
61
|
+
```
|
data/docs/usage.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Usage and flags
|
|
3
|
+
nav_order: 6
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Usage and flags
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
1. TOC
|
|
10
|
+
{:toc}
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
wordmove-ng --version, -v # Print the version
|
|
16
|
+
wordmove-ng doctor # Do some local configuration and environment checks
|
|
17
|
+
wordmove-ng help [COMMAND] # Describe available commands or one specific command
|
|
18
|
+
wordmove-ng init # Generates a brand new movefile.yml
|
|
19
|
+
wordmove-ng list # List all environments and vhosts
|
|
20
|
+
wordmove-ng pull # Pulls WP data from remote host to the local machine
|
|
21
|
+
wordmove-ng push # Pushes WP data from local machine to remote host
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### `init`
|
|
25
|
+
{: .no_toc }
|
|
26
|
+
|
|
27
|
+
Writes `movefile.yml` in the current directory, reading `wp-config.php` for the local database credentials (splitting `DB_HOST` values that carry a port or a socket) and the local URL from `WP_HOME`, `WP_SITEURL` or `wp option get home`.
|
|
28
|
+
|
|
29
|
+
### `doctor`
|
|
30
|
+
{: .no_toc }
|
|
31
|
+
|
|
32
|
+
Checks, in order: movefile schema (rejecting `ftp` blocks and reporting prefix collisions), local `mysql`/`mysqldump` and a connection with the local credentials, local `wp` presence and freshness, `rsync`, `ssh`, then for each SSH remote a non interactive login followed by a probe for `rsync`, `gzip`, `mysql`/`mariadb`, `mysqldump`/`mariadb-dump` and `wp`. It also warns about `ssh.gateway.password`. Run it before opening an issue and paste the output.
|
|
33
|
+
|
|
34
|
+
### `list`
|
|
35
|
+
{: .no_toc }
|
|
36
|
+
|
|
37
|
+
Prints every environment with its `vhost`.
|
|
38
|
+
|
|
39
|
+
### `push` and `pull`
|
|
40
|
+
{: .no_toc }
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Options:
|
|
44
|
+
-w, [--wordpress], [--no-wordpress]
|
|
45
|
+
-u, [--uploads], [--no-uploads]
|
|
46
|
+
-t, [--themes], [--no-themes]
|
|
47
|
+
-p, [--plugins], [--no-plugins]
|
|
48
|
+
-m, [--mu-plugins], [--no-mu-plugins]
|
|
49
|
+
-l, [--languages], [--no-languages]
|
|
50
|
+
-d, [--db], [--no-db]
|
|
51
|
+
-v, [--verbose], [--no-verbose]
|
|
52
|
+
-s, [--simulate], [--no-simulate]
|
|
53
|
+
-e, [--environment=ENVIRONMENT]
|
|
54
|
+
-c, [--config=CONFIG]
|
|
55
|
+
[--debug], [--no-debug]
|
|
56
|
+
[--no-adapt], [--no-no-adapt]
|
|
57
|
+
[--all], [--no-all]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`pull` copies from the remote given with `-e` to `local`; `push` copies from `local` to that remote. At least one component flag (or `--all`) is required.
|
|
61
|
+
|
|
62
|
+
## Flags
|
|
63
|
+
|
|
64
|
+
| Flag | Meaning |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `-w`, `--wordpress` | the WordPress core, ignoring `wp-content` |
|
|
67
|
+
| `-u`, `--uploads` | `wp-content/uploads` |
|
|
68
|
+
| `-t`, `--themes` | `wp-content/themes` |
|
|
69
|
+
| `-p`, `--plugins` | `wp-content/plugins` |
|
|
70
|
+
| `-m`, `--mu-plugins` | `wp-content/mu-plugins` |
|
|
71
|
+
| `-l`, `--languages` | `wp-content/languages` |
|
|
72
|
+
| `-d`, `--db` | the database; see [Database sync]({{ site.baseurl }}/database-sync/) |
|
|
73
|
+
| `--all` | every component; combine with `--no-*` to leave some out |
|
|
74
|
+
| `--no-<component>` | exclude one component, usually with `--all` |
|
|
75
|
+
| `-s`, `--simulate` | rsync runs with `--dry-run`; database steps are logged and skipped |
|
|
76
|
+
| `-e ENV`, `--environment` | which remote to use; optional with a single remote |
|
|
77
|
+
| `-c FILE`, `--config` | alternate movefile inside the project |
|
|
78
|
+
| `--no-adapt` | import the database without running `wp search-replace` |
|
|
79
|
+
| `-v`, `--verbose` | more output |
|
|
80
|
+
| `--debug` | accepted for compatibility; had an effect only with the removed FTP deployer |
|
|
81
|
+
|
|
82
|
+
Component paths respect the `paths` section of each environment.
|
|
83
|
+
|
|
84
|
+
## Examples
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
wordmove-ng pull -e staging --all # everything from staging
|
|
88
|
+
wordmove-ng push -e production --all --no-db # every folder, keep the production database
|
|
89
|
+
wordmove-ng push -e production --all --no-db --no-uploads
|
|
90
|
+
wordmove-ng push -e production -t -p -s # dry run of themes and plugins
|
|
91
|
+
wordmove-ng pull -e production -d --no-adapt # database without URL rewriting
|
|
92
|
+
wordmove-ng push -c movefile.client.yml -e live -u
|
|
93
|
+
WORDMOVE_MAINTENANCE_MODE=1 wordmove-ng push -e production -d
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Mirroring
|
|
97
|
+
|
|
98
|
+
File sync mirrors the source: files missing at the source are **deleted** at the destination. Use `exclude` for anything that must survive on one side only (uploads produced on production, `.env` files, caches).
|
|
99
|
+
|
|
100
|
+
## Work only on specific plugins or themes
|
|
101
|
+
|
|
102
|
+
`-p` considers the whole `plugins` folder. rsync patterns starting with `+ ` are inclusions, so you can exclude everything but one plugin:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
exclude:
|
|
106
|
+
- "+ wp-content/plugins/plugin_1/"
|
|
107
|
+
- "wp-content/plugins/*"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The same works for themes and any other folder.
|
|
111
|
+
|
|
112
|
+
## Running unattended
|
|
113
|
+
|
|
114
|
+
wordmove-ng never prompts, so it can run from cron, systemd timers or CI. The environment those give you is the only difference; see [Automation and cron]({{ site.baseurl }}/automation/) for a ready-made script and the SSH key setup.
|
|
115
|
+
|
|
116
|
+
## Rsync options in a continuous delivery context
|
|
117
|
+
|
|
118
|
+
The default rsync flags are `-rlpt`. On a CI runner every file is freshly checked out, so `--times` triggers a full transfer every time and `--perms` may not be what you want:
|
|
119
|
+
|
|
120
|
+
```yaml
|
|
121
|
+
ssh:
|
|
122
|
+
rsync_options: "--itemize-changes --chmod=D775,F664 --no-perms --no-times --checksum"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`--no-perms` and `--no-times` disable the defaults, `--checksum` compares content instead of timestamps (slower, but transfers only real changes), and `--chmod` gives you control over what lands on the server.
|
|
126
|
+
|
|
127
|
+
## Logging
|
|
128
|
+
|
|
129
|
+
Long generated shell scripts are summarised into intent lines such as `dump database my_db to ./wp-content/dump.sql`, `compress ./wp-content/dump.sql`, `wp search-replace old.test -> new.test in /var/www/site` and `import SQL dump … (strip sandbox header, append COMMIT)`. Passwords, hosts, vhosts and paths from the movefile are masked as `[secret]` in all output, including hook output.
|
data/lib/wordmove/version.rb
CHANGED
data/wordmove-ng.gemspec
CHANGED
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
"source_code_uri" => spec.homepage,
|
|
27
27
|
"changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md",
|
|
28
28
|
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
|
29
|
-
"documentation_uri" => "
|
|
29
|
+
"documentation_uri" => "https://tekgnosis-net.github.io/wordmove-ng/",
|
|
30
30
|
"rubygems_mfa_required" => "true"
|
|
31
31
|
}
|
|
32
32
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wordmove-ng
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.
|
|
4
|
+
version: 6.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kumar
|
|
@@ -214,6 +214,7 @@ files:
|
|
|
214
214
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
215
215
|
- ".github/ISSUE_TEMPLATE/config.yml"
|
|
216
216
|
- ".github/stale.yml"
|
|
217
|
+
- ".github/workflows/pages.yml"
|
|
217
218
|
- ".github/workflows/release.yml"
|
|
218
219
|
- ".github/workflows/ruby.yml"
|
|
219
220
|
- ".gitignore"
|
|
@@ -250,7 +251,24 @@ files:
|
|
|
250
251
|
- bin/setup
|
|
251
252
|
- bin/thor
|
|
252
253
|
- bin/wordmove-ng
|
|
254
|
+
- contrib/wordmove-sync.sh
|
|
253
255
|
- deploy/deploy.sh
|
|
256
|
+
- docs/Gemfile
|
|
257
|
+
- docs/README.md
|
|
258
|
+
- docs/_config.yml
|
|
259
|
+
- docs/assets/images/wordmove-ng.png
|
|
260
|
+
- docs/automation.md
|
|
261
|
+
- docs/configuration.md
|
|
262
|
+
- docs/contributing.md
|
|
263
|
+
- docs/database-sync.md
|
|
264
|
+
- docs/environments.md
|
|
265
|
+
- docs/hooks.md
|
|
266
|
+
- docs/index.md
|
|
267
|
+
- docs/installation.md
|
|
268
|
+
- docs/quick-start.md
|
|
269
|
+
- docs/troubleshooting.md
|
|
270
|
+
- docs/upgrading.md
|
|
271
|
+
- docs/usage.md
|
|
254
272
|
- exe/wordmove-ng
|
|
255
273
|
- lib/wordmove-ng.rb
|
|
256
274
|
- lib/wordmove.rb
|
|
@@ -291,7 +309,7 @@ metadata:
|
|
|
291
309
|
source_code_uri: https://github.com/tekgnosis-net/wordmove-ng
|
|
292
310
|
changelog_uri: https://github.com/tekgnosis-net/wordmove-ng/blob/master/CHANGELOG.md
|
|
293
311
|
bug_tracker_uri: https://github.com/tekgnosis-net/wordmove-ng/issues
|
|
294
|
-
documentation_uri: https://
|
|
312
|
+
documentation_uri: https://tekgnosis-net.github.io/wordmove-ng/
|
|
295
313
|
rubygems_mfa_required: 'true'
|
|
296
314
|
post_install_message: |2
|
|
297
315
|
wordmove-ng 6.0 is a breaking release compared to wordmove 5.x:
|