wordmove-ng 6.0.0 → 6.0.1
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 +6 -1
- data/.gitignore +2 -0
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +8 -1
- data/CLAUDE.md +7 -0
- data/README.md +16 -9
- 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/configuration.md +345 -0
- data/docs/contributing.md +53 -0
- data/docs/database-sync.md +91 -0
- data/docs/environments.md +65 -0
- data/docs/hooks.md +103 -0
- data/docs/index.md +58 -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 +125 -0
- data/lib/wordmove/version.rb +1 -1
- data/wordmove-ng.gemspec +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f35d0da6f7b15e8f492351b76ea90e096fe73b5c94cf55d9e8f10a0e93eb3802
|
|
4
|
+
data.tar.gz: cebf5ecc1de41bf581c5b07cdf4446e87ead5b73c891393b60cfa7a6d702c14c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dcb6cddeb0d95335204a1a40b2f429573ec114d0cffc7375e16af0eec4d2201df92c9c8f2040e809c610933853a1e71cf116ff3b3525a22f25d6b4da26366ac5
|
|
7
|
+
data.tar.gz: 35b2e3a3b29fb0e2ca9d6c128781cc0ca2feaa758b8efa49eeb71402c0ff2e683cb3bfcbbb8bf5d54d0d172ffd524a09579c7794b6da5a3da8638dc725c0bd8e
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Builds the docs/ site with Jekyll + just-the-docs and deploys it to GitHub
|
|
2
|
+
# Pages. Requires the repository's Pages source to be set to "GitHub Actions".
|
|
3
|
+
|
|
4
|
+
name: Docs
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [master]
|
|
9
|
+
paths:
|
|
10
|
+
- "docs/**"
|
|
11
|
+
- ".github/workflows/pages.yml"
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
pages: write
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: pages
|
|
21
|
+
cancel-in-progress: true
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
|
+
- uses: ruby/setup-ruby@v1
|
|
29
|
+
with:
|
|
30
|
+
ruby-version: "3.4"
|
|
31
|
+
bundler-cache: true
|
|
32
|
+
working-directory: docs
|
|
33
|
+
- uses: actions/configure-pages@v5
|
|
34
|
+
id: pages
|
|
35
|
+
- name: Build
|
|
36
|
+
working-directory: docs
|
|
37
|
+
env:
|
|
38
|
+
JEKYLL_ENV: production
|
|
39
|
+
run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
|
|
40
|
+
- uses: actions/upload-pages-artifact@v3
|
|
41
|
+
with:
|
|
42
|
+
path: docs/_site
|
|
43
|
+
|
|
44
|
+
deploy:
|
|
45
|
+
needs: build
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
environment:
|
|
48
|
+
name: github-pages
|
|
49
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/deploy-pages@v4
|
|
52
|
+
id: deployment
|
|
@@ -97,4 +97,9 @@ jobs:
|
|
|
97
97
|
env:
|
|
98
98
|
GH_TOKEN: ${{ github.token }}
|
|
99
99
|
TAG: ${{ needs.release-please.outputs.tag_name || github.ref_name }}
|
|
100
|
-
|
|
100
|
+
# release-please creates the release itself; a hand-pushed tag has none yet.
|
|
101
|
+
run: |
|
|
102
|
+
if ! gh release view "$TAG" >/dev/null 2>&1; then
|
|
103
|
+
gh release create "$TAG" --title "$TAG" --notes "See CHANGELOG.md for details."
|
|
104
|
+
fi
|
|
105
|
+
gh release upload "$TAG" pkg/*.gem --clobber
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,14 @@ All notable changes to wordmove-ng are documented here. The project follows
|
|
|
5
5
|
are listed at https://github.com/welaika/wordmove/releases; the kokiddp fork's changes
|
|
6
6
|
between 5.2.2 and this project are summarised under 6.0.0.
|
|
7
7
|
|
|
8
|
-
## 6.0.0 (
|
|
8
|
+
## [6.0.1](https://github.com/tekgnosis-net/wordmove-ng/compare/v6.0.0...v6.0.1) (2026-09-09)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* add the documentation site on GitHub Pages ([3b3e70a](https://github.com/tekgnosis-net/wordmove-ng/commit/3b3e70ae4ed548778634aa115cf0b64d53cfb727))
|
|
14
|
+
|
|
15
|
+
## 6.0.0 (2026-09-09)
|
|
9
16
|
|
|
10
17
|
First release as an independent project. Breaking changes are marked **breaking**.
|
|
11
18
|
|
data/CLAUDE.md
CHANGED
|
@@ -90,6 +90,13 @@ Key pieces:
|
|
|
90
90
|
`global.collation_fallbacks`, `global.charset_fallbacks`. Add new toggles as movefile keys
|
|
91
91
|
with an env override and document them in README + CHANGELOG in the same commit.
|
|
92
92
|
|
|
93
|
+
## Docs site
|
|
94
|
+
|
|
95
|
+
`docs/` is a Jekyll + just-the-docs site published to https://tekgnosis-net.github.io/wordmove-ng/
|
|
96
|
+
by `.github/workflows/pages.yml` on pushes to `master` that touch `docs/`. Internal links use
|
|
97
|
+
`{{ site.baseurl }}/<slug>/` (pretty permalinks). Preview: `cd docs && bundle exec jekyll serve`.
|
|
98
|
+
Update the relevant page in the same commit as any user-facing behaviour change.
|
|
99
|
+
|
|
93
100
|
## Conventions worth knowing
|
|
94
101
|
|
|
95
102
|
- **Commit messages are Conventional Commits** (`feat:`, `fix:`, `feat!:`/`BREAKING CHANGE:`,
|
data/README.md
CHANGED
|
@@ -12,7 +12,11 @@ by weLaika, continued through the [kokiddp fork](https://github.com/kokiddp/word
|
|
|
12
12
|
The movefile format, commands and flags are unchanged. What changed is under the hood, and
|
|
13
13
|
in a few places where the old behaviour was unsafe. See [Upgrading from wordmove 5.x](#upgrading-from-wordmove-5x).
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**Full documentation: <https://tekgnosis-net.github.io/wordmove-ng/>**
|
|
16
|
+
|
|
17
|
+
[](https://github.com/tekgnosis-net/wordmove-ng/actions/workflows/ruby.yml?query=branch%3Amaster)
|
|
18
|
+
[](https://rubygems.org/gems/wordmove-ng)
|
|
19
|
+
[](https://tekgnosis-net.github.io/wordmove-ng/)
|
|
16
20
|
|
|
17
21
|
## Highlights
|
|
18
22
|
|
|
@@ -37,7 +41,7 @@ Ruby 3.0 or newer is required.
|
|
|
37
41
|
gem install wordmove-ng
|
|
38
42
|
```
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
To run the latest master instead of a release:
|
|
41
45
|
|
|
42
46
|
```bash
|
|
43
47
|
gem install specific_install
|
|
@@ -242,12 +246,13 @@ production:
|
|
|
242
246
|
File sync mirrors the source: files missing on the source are deleted on the destination.
|
|
243
247
|
Put anything you need to keep in `exclude`, which is always relative to `wordpress_path`.
|
|
244
248
|
|
|
245
|
-
The
|
|
246
|
-
[
|
|
247
|
-
[Usage and flags
|
|
248
|
-
[
|
|
249
|
-
[Hooks](https://
|
|
250
|
-
|
|
249
|
+
The documentation site has the full reference:
|
|
250
|
+
[Configuration](https://tekgnosis-net.github.io/wordmove-ng/configuration/),
|
|
251
|
+
[Usage and flags](https://tekgnosis-net.github.io/wordmove-ng/usage/),
|
|
252
|
+
[Database sync](https://tekgnosis-net.github.io/wordmove-ng/database-sync/),
|
|
253
|
+
[Hooks](https://tekgnosis-net.github.io/wordmove-ng/hooks/),
|
|
254
|
+
[Multiple environments](https://tekgnosis-net.github.io/wordmove-ng/environments/),
|
|
255
|
+
[Troubleshooting](https://tekgnosis-net.github.io/wordmove-ng/troubleshooting/).
|
|
251
256
|
|
|
252
257
|
## Logging
|
|
253
258
|
|
|
@@ -315,7 +320,9 @@ stored anywhere.
|
|
|
315
320
|
the GitHub release.
|
|
316
321
|
|
|
317
322
|
Pushing a `v*` tag by hand at the head of `master` triggers the same publish job; that is
|
|
318
|
-
how 6.0.0
|
|
323
|
+
how 6.0.0 was cut. Merge the release PR only when there is something worth shipping:
|
|
324
|
+
release-please keeps proposing a patch release for any Conventional Commit, including
|
|
325
|
+
`ci:` and `docs:` ones.
|
|
319
326
|
|
|
320
327
|
One-time setup for a new maintainer or a fork:
|
|
321
328
|
|
data/docs/Gemfile
ADDED
data/docs/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Documentation site, published to https://tekgnosis-net.github.io/wordmove-ng/ by
|
|
2
|
+
`.github/workflows/pages.yml` on every push to `master`.
|
|
3
|
+
|
|
4
|
+
Preview locally:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
cd docs
|
|
8
|
+
bundle install
|
|
9
|
+
bundle exec jekyll serve # http://127.0.0.1:4000/wordmove-ng/
|
|
10
|
+
```
|
data/docs/_config.yml
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
title: wordmove-ng
|
|
2
|
+
description: Move WordPress sites between environments over SSH, database included.
|
|
3
|
+
url: https://tekgnosis-net.github.io
|
|
4
|
+
baseurl: /wordmove-ng
|
|
5
|
+
repository: tekgnosis-net/wordmove-ng
|
|
6
|
+
|
|
7
|
+
theme: just-the-docs
|
|
8
|
+
permalink: pretty
|
|
9
|
+
color_scheme: light
|
|
10
|
+
logo: /assets/images/wordmove-ng.png
|
|
11
|
+
favicon_ico: /assets/images/wordmove-ng.png
|
|
12
|
+
search_enabled: true
|
|
13
|
+
heading_anchors: true
|
|
14
|
+
|
|
15
|
+
aux_links:
|
|
16
|
+
GitHub: https://github.com/tekgnosis-net/wordmove-ng
|
|
17
|
+
RubyGems: https://rubygems.org/gems/wordmove-ng
|
|
18
|
+
aux_links_new_tab: true
|
|
19
|
+
|
|
20
|
+
nav_external_links:
|
|
21
|
+
- title: Changelog
|
|
22
|
+
url: https://github.com/tekgnosis-net/wordmove-ng/blob/master/CHANGELOG.md
|
|
23
|
+
|
|
24
|
+
footer_content: 'Copyright © 2013-2019 weLaika Soc. Coop. (Wordmove), 2026 tekgnosis.net (wordmove-ng). Distributed under the <a href="https://github.com/tekgnosis-net/wordmove-ng/blob/master/LICENSE">MIT license</a>.'
|
|
25
|
+
|
|
26
|
+
callouts:
|
|
27
|
+
note:
|
|
28
|
+
title: Note
|
|
29
|
+
color: blue
|
|
30
|
+
warning:
|
|
31
|
+
title: Warning
|
|
32
|
+
color: yellow
|
|
33
|
+
danger:
|
|
34
|
+
title: Danger
|
|
35
|
+
color: red
|
|
36
|
+
|
|
37
|
+
exclude:
|
|
38
|
+
- Gemfile
|
|
39
|
+
- Gemfile.lock
|
|
40
|
+
- vendor/
|
|
41
|
+
- README.md
|
|
42
|
+
|
|
43
|
+
defaults:
|
|
44
|
+
- scope:
|
|
45
|
+
path: ""
|
|
46
|
+
values:
|
|
47
|
+
layout: default
|
|
Binary file
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Configuration
|
|
3
|
+
nav_order: 5
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Configuration
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
`movefile.yml` describes your local install and every remote. It is a YAML file, evaluated as an ERB template first, so it can read environment variables.
|
|
10
|
+
|
|
11
|
+
1. TOC
|
|
12
|
+
{:toc}
|
|
13
|
+
|
|
14
|
+
## File name and location
|
|
15
|
+
|
|
16
|
+
wordmove-ng looks for `movefile.yml`, `movefile.yaml`, `movefile` or `Movefile` in the current directory and then in each parent up to the one containing `wp-config.php`. `-c other.yml` selects another file inside the project.
|
|
17
|
+
|
|
18
|
+
{: .note }
|
|
19
|
+
Indentation defines the structure. Two spaces per level, no tabs. `wordmove-ng doctor` validates the file against a schema and tells you what is wrong.
|
|
20
|
+
|
|
21
|
+
## Complete example
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
global:
|
|
25
|
+
maintenance_mode: false
|
|
26
|
+
|
|
27
|
+
local:
|
|
28
|
+
vhost: http://site.test
|
|
29
|
+
wordpress_path: /home/john/sites/site
|
|
30
|
+
database:
|
|
31
|
+
name: site
|
|
32
|
+
user: root
|
|
33
|
+
password: root
|
|
34
|
+
host: 127.0.0.1
|
|
35
|
+
# port: 3306
|
|
36
|
+
# socket: /path/to/mysqld.sock
|
|
37
|
+
|
|
38
|
+
staging:
|
|
39
|
+
vhost: https://staging.example.com
|
|
40
|
+
wordpress_path: /var/www/staging
|
|
41
|
+
database:
|
|
42
|
+
name: staging
|
|
43
|
+
user: staging
|
|
44
|
+
password: "<%= ENV['STAGING_DB_PASS'] %>"
|
|
45
|
+
host: localhost
|
|
46
|
+
ssh:
|
|
47
|
+
host: staging.example.com
|
|
48
|
+
user: deploy
|
|
49
|
+
exclude:
|
|
50
|
+
- ".git/"
|
|
51
|
+
- ".env"
|
|
52
|
+
- "node_modules/"
|
|
53
|
+
- "wp-config.php"
|
|
54
|
+
- "wp-content/*.sql.gz"
|
|
55
|
+
|
|
56
|
+
production:
|
|
57
|
+
vhost: https://example.com
|
|
58
|
+
wordpress_path: /var/www/example
|
|
59
|
+
database:
|
|
60
|
+
name: example
|
|
61
|
+
user: example
|
|
62
|
+
password: "<%= ENV['PROD_DB_PASS'] %>"
|
|
63
|
+
host: localhost
|
|
64
|
+
# mysqldump_options: --max_allowed_packet=50MB
|
|
65
|
+
# mysql_options: --protocol=TCP
|
|
66
|
+
ssh:
|
|
67
|
+
host: example.com
|
|
68
|
+
user: deploy
|
|
69
|
+
# port: 22
|
|
70
|
+
# password: only with sshpass installed; prefer keys
|
|
71
|
+
# rsync_options: --verbose
|
|
72
|
+
# gateway:
|
|
73
|
+
# host: bastion.example.com
|
|
74
|
+
# user: jump
|
|
75
|
+
exclude:
|
|
76
|
+
- ".git/"
|
|
77
|
+
- ".env"
|
|
78
|
+
- "node_modules/"
|
|
79
|
+
- "wp-config.php"
|
|
80
|
+
- "wp-content/*.sql.gz"
|
|
81
|
+
forbid:
|
|
82
|
+
push:
|
|
83
|
+
db: true # never push the database to production
|
|
84
|
+
hooks:
|
|
85
|
+
push:
|
|
86
|
+
after:
|
|
87
|
+
- command: wp cache flush
|
|
88
|
+
where: remote
|
|
89
|
+
raise: false
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## First level keys
|
|
93
|
+
|
|
94
|
+
`local` is mandatory and must keep that name. `global` is optional. Every other first level key is a remote environment, selected with `-e`. See [Multiple environments]({{ site.baseurl }}/environments/).
|
|
95
|
+
|
|
96
|
+
## `global`
|
|
97
|
+
|
|
98
|
+
| Key | Default | Meaning |
|
|
99
|
+
| --- | --- | --- |
|
|
100
|
+
| `maintenance_mode` | `false` | Wrap the target's database import and adaptation in `wp maintenance-mode activate`/`deactivate`. `WORDMOVE_MAINTENANCE_MODE=1` in the environment forces it on for one run. |
|
|
101
|
+
| `collation_fallbacks` | built-in table | Collations rewritten before import, e.g. `utf8mb3_uca1400_ai_ci: utf8mb4_unicode_ci`. Setting the key replaces the default table. |
|
|
102
|
+
| `charset_fallbacks` | `utf8mb3: utf8mb4` | Charsets rewritten before import. |
|
|
103
|
+
| `sql_adapter` | ignored | Accepted with a warning for 5.x movefiles. |
|
|
104
|
+
|
|
105
|
+
## `local` and each remote
|
|
106
|
+
|
|
107
|
+
### `vhost`
|
|
108
|
+
{: .no_toc }
|
|
109
|
+
|
|
110
|
+
> mandatory
|
|
111
|
+
|
|
112
|
+
The URL you use to reach the site, including any subdirectory WordPress is installed in. It should match `wp option get home`. Omit the trailing slash. `init` pre-fills it from `wp-config.php` or `wp option get home`.
|
|
113
|
+
|
|
114
|
+
### `wordpress_path`
|
|
115
|
+
{: .no_toc }
|
|
116
|
+
|
|
117
|
+
> mandatory
|
|
118
|
+
|
|
119
|
+
The absolute path of the installation. Spaces and other shell characters are handled; no manual escaping. On a remote it is the path **on that host**.
|
|
120
|
+
|
|
121
|
+
{: .warning }
|
|
122
|
+
Avoid values where one environment's `vhost` or `wordpress_path` is a prefix of another's (`https://site.test` and `https://site.test.example.com`): the search-replace of the shorter value would also rewrite the longer one. The doctor reports this.
|
|
123
|
+
|
|
124
|
+
### `database`
|
|
125
|
+
{: .no_toc }
|
|
126
|
+
|
|
127
|
+
> mandatory keys: `name`, `user`, `password`, `host`
|
|
128
|
+
|
|
129
|
+
| Key | Meaning |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `name`, `user`, `password`, `host` | as in `wp-config.php`. For a remote, as seen **from the remote host**: wordmove-ng connects over SSH first and runs `mysqldump`/`mysql`/`wp` there. |
|
|
132
|
+
| `port` | optional; `init` splits `DB_HOST` values like `localhost:3307`. |
|
|
133
|
+
| `socket` | optional unix socket; `init` splits `DB_HOST` values like `localhost:/path/mysqld.sock`. |
|
|
134
|
+
| `mysqldump_options` | passed verbatim to `mysqldump`/`mariadb-dump`, e.g. `--max_allowed_packet=50MB --ignore-table=db.wp_bigtable`. |
|
|
135
|
+
| `mysql_options` | passed verbatim to `mysql`/`mariadb` on import, e.g. `--protocol=TCP`. |
|
|
136
|
+
|
|
137
|
+
`mariadb`/`mariadb-dump` are preferred when installed, falling back to `mysql`/`mysqldump`. Imports run with `--binary-mode` (unless `mysql_options` already sets it), `SET FOREIGN_KEY_CHECKS=0` and a trailing `COMMIT;`; a MariaDB sandbox header is stripped.
|
|
138
|
+
|
|
139
|
+
### `paths`
|
|
140
|
+
{: .no_toc }
|
|
141
|
+
|
|
142
|
+
> optional
|
|
143
|
+
|
|
144
|
+
Customise WordPress internal paths when they are not the defaults, relative to `wordpress_path`. Configure it on every environment whose layout differs.
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
paths:
|
|
148
|
+
wp_content: app
|
|
149
|
+
wp_config: config/wp-config.php
|
|
150
|
+
uploads: app/uploads
|
|
151
|
+
plugins: app/plugins
|
|
152
|
+
mu_plugins: app/mu-plugins
|
|
153
|
+
themes: app/themes
|
|
154
|
+
languages: app/languages
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Remote-only keys
|
|
158
|
+
|
|
159
|
+
### `ssh`
|
|
160
|
+
{: .no_toc }
|
|
161
|
+
|
|
162
|
+
> mandatory key: `host`
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
ssh:
|
|
166
|
+
host: host
|
|
167
|
+
user: user
|
|
168
|
+
port: 22 # optional
|
|
169
|
+
password: secret # optional; needs sshpass, prefer keys
|
|
170
|
+
rsync_options: "--verbose" # optional, appended to rsync
|
|
171
|
+
gateway: # optional jump host, becomes `ssh -J`
|
|
172
|
+
host: bastion
|
|
173
|
+
user: jump
|
|
174
|
+
port: 22
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Every operation uses the **system `ssh` client**: rsync for directories, `ssh` for remote commands and hooks, `scp` for dump files. Whatever works for `ssh` on your command line works here: ssh-agent, `~/.ssh/config`, `ProxyJump`, hardware keys, modern key types. Only `host` is mandatory because the rest can live in `~/.ssh/config`:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
Host client_x_staging
|
|
181
|
+
Hostname 79.99.8.94
|
|
182
|
+
User welaika
|
|
183
|
+
Port 1337
|
|
184
|
+
ProxyJump bastion
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
staging:
|
|
189
|
+
ssh:
|
|
190
|
+
host: client_x_staging
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- Without `password`, connections run with `BatchMode=yes`: a failing key authentication is an error naming the failed command, never a prompt.
|
|
194
|
+
- `password` is passed through `sshpass -p` to `ssh`, `scp` and `rsync`. It requires `sshpass` locally and exposes the password in the process list.
|
|
195
|
+
- `rsync_options` are appended to the defaults `-rlpt --compress --omit-dir-times --delete`. See [rsync options for CI]({{ site.baseurl }}/usage/#rsync-options-in-a-continuous-delivery-context).
|
|
196
|
+
- `gateway` becomes `ssh -J [user@]host[:port]`. A `gateway.password` cannot be honoured and is ignored; the doctor warns.
|
|
197
|
+
- Remote commands always run through `sh -c`, so the remote login shell can be bash, zsh, fish or csh. Programs only need to be in the `$PATH` of a non interactive login.
|
|
198
|
+
|
|
199
|
+
### `exclude`
|
|
200
|
+
{: .no_toc }
|
|
201
|
+
|
|
202
|
+
> optional
|
|
203
|
+
|
|
204
|
+
Patterns ignored during `push` and `pull`, which also means matching files are **not deleted** on the destination when missing at the source. Each entry becomes an rsync `--exclude`, relative to `wordpress_path`, so all rsync pattern syntax applies; see [working on specific plugins]({{ site.baseurl }}/usage/#work-only-on-specific-plugins-or-themes).
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
exclude:
|
|
208
|
+
- ".git/"
|
|
209
|
+
- ".gitignore"
|
|
210
|
+
- ".env"
|
|
211
|
+
- "node_modules/"
|
|
212
|
+
- "tmp/*"
|
|
213
|
+
- "movefile.yml"
|
|
214
|
+
- "wp-config.php"
|
|
215
|
+
- "wp-content/*.sql.gz"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### `hooks`
|
|
219
|
+
{: .no_toc }
|
|
220
|
+
|
|
221
|
+
> optional
|
|
222
|
+
|
|
223
|
+
Commands run before or after a push or pull, locally or on the remote. See [Hooks]({{ site.baseurl }}/hooks/).
|
|
224
|
+
|
|
225
|
+
### `forbid`
|
|
226
|
+
{: .no_toc }
|
|
227
|
+
|
|
228
|
+
> optional
|
|
229
|
+
|
|
230
|
+
Blocks actions by configuration; forbidden tasks ignore command line flags and are skipped with a warning. Values must be booleans.
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
forbid:
|
|
234
|
+
push:
|
|
235
|
+
db: true
|
|
236
|
+
uploads: false
|
|
237
|
+
plugins: false
|
|
238
|
+
themes: false
|
|
239
|
+
languages: false
|
|
240
|
+
mu_plugins: false
|
|
241
|
+
pull:
|
|
242
|
+
db: false
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Removed: `ftp`
|
|
246
|
+
{: .no_toc }
|
|
247
|
+
|
|
248
|
+
FTP, FTPS and SFTP transports were removed in 6.0. A remote with an `ftp` block fails validation with a clear message. See [Upgrading]({{ site.baseurl }}/upgrading/#4-ftp-and-sftp-are-gone).
|
|
249
|
+
|
|
250
|
+
## Environment variables and `.env`
|
|
251
|
+
|
|
252
|
+
Because the movefile is an ERB template, secrets can come from the environment:
|
|
253
|
+
|
|
254
|
+
```yaml
|
|
255
|
+
production:
|
|
256
|
+
database:
|
|
257
|
+
user: "<%= ENV['PROD_DB_USER'] %>"
|
|
258
|
+
password: "<%= ENV['PROD_DB_PASS'] %>"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Set them in the shell (`export PROD_DB_PASS="…"`) or in a `.env` file next to the movefile:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
PROD_DB_USER="username"
|
|
265
|
+
PROD_DB_PASS="password"
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`.env.<environment>` (for example `.env.production`) is loaded when that environment is selected with `-e`. Add `.env*` to `exclude` and to `.gitignore`.
|
|
269
|
+
|
|
270
|
+
System variables work too: `wordpress_path: "<%= ENV['HOME'] %>/sites/example"`.
|
|
271
|
+
|
|
272
|
+
## YAML and ERB tips
|
|
273
|
+
|
|
274
|
+
### Anchors to avoid repetition
|
|
275
|
+
{: .no_toc }
|
|
276
|
+
|
|
277
|
+
```yaml
|
|
278
|
+
global:
|
|
279
|
+
default: &default
|
|
280
|
+
vhost: "http://example.com"
|
|
281
|
+
wordpress_path: "/var/www/site"
|
|
282
|
+
database: &db
|
|
283
|
+
host: localhost
|
|
284
|
+
user: username
|
|
285
|
+
password: password
|
|
286
|
+
name: database
|
|
287
|
+
ssh: &ssh
|
|
288
|
+
host: server
|
|
289
|
+
user: foo
|
|
290
|
+
|
|
291
|
+
staging:
|
|
292
|
+
<<: *default
|
|
293
|
+
vhost: http://staging.example.com
|
|
294
|
+
database:
|
|
295
|
+
<<: *db
|
|
296
|
+
name: db_staging
|
|
297
|
+
ssh:
|
|
298
|
+
<<: *ssh
|
|
299
|
+
user: foobar
|
|
300
|
+
|
|
301
|
+
production:
|
|
302
|
+
<<: *default
|
|
303
|
+
vhost: https://www.example.com
|
|
304
|
+
database:
|
|
305
|
+
<<: *db
|
|
306
|
+
name: db_production
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
The `default` anchor lives under `global` because every other first level key is treated as an environment.
|
|
310
|
+
|
|
311
|
+
### Variables inside the template
|
|
312
|
+
{: .no_toc }
|
|
313
|
+
|
|
314
|
+
```yaml
|
|
315
|
+
production:
|
|
316
|
+
<% prod_wp_path = "/home/site/public" %>
|
|
317
|
+
vhost: "https://example.com"
|
|
318
|
+
wordpress_path: <%= prod_wp_path %>
|
|
319
|
+
hooks:
|
|
320
|
+
pull:
|
|
321
|
+
after:
|
|
322
|
+
- command: 'cd <%= prod_wp_path %> && wp core version'
|
|
323
|
+
where: remote
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Conditional sections
|
|
327
|
+
{: .no_toc }
|
|
328
|
+
|
|
329
|
+
```yaml
|
|
330
|
+
hooks:
|
|
331
|
+
pull:
|
|
332
|
+
after:
|
|
333
|
+
<% if ENV.fetch('NOTIFY', nil) %>
|
|
334
|
+
- command: 'bash ./scripts/notify.sh'
|
|
335
|
+
where: local
|
|
336
|
+
<% end %>
|
|
337
|
+
- command: 'wp cache flush'
|
|
338
|
+
where: remote
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
`ENV.fetch('NOTIFY', nil)` returns the variable or `nil`; you can also compare against values (`<% if ENV.fetch('TARGET', '') == 'blue' %>`).
|
|
342
|
+
|
|
343
|
+
## Schema validation
|
|
344
|
+
|
|
345
|
+
`wordmove-ng doctor` validates every section against the schemas in [`lib/wordmove/assets`](https://github.com/tekgnosis-net/wordmove-ng/tree/master/lib/wordmove/assets), reports unknown or mistyped keys, rejects `ftp` blocks and flags prefix collisions between search terms.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contributing and releasing
|
|
3
|
+
nav_order: 11
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Contributing and releasing
|
|
7
|
+
{: .no_toc }
|
|
8
|
+
|
|
9
|
+
1. TOC
|
|
10
|
+
{:toc}
|
|
11
|
+
|
|
12
|
+
## Reporting a bug
|
|
13
|
+
|
|
14
|
+
Run `wordmove-ng doctor` first and include its output. Then open an issue with the command you ran, the relevant part of `movefile.yml` with secrets removed, the full error output, and your OS, Ruby (`ruby --version`) and wordmove-ng (`wordmove-ng --version`) versions. Only the latest release is supported; bugs in the legacy `wordmove` 5.x gem belong to its own tracker.
|
|
15
|
+
|
|
16
|
+
## Development
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone https://github.com/tekgnosis-net/wordmove-ng.git
|
|
20
|
+
cd wordmove-ng
|
|
21
|
+
bundle install
|
|
22
|
+
bundle exec rake # specs + rubocop, what CI runs
|
|
23
|
+
bundle exec rspec spec/deployer/ssh_db_spec.rb # one file
|
|
24
|
+
bin/wordmove-ng --help # run from the checkout, from any directory
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
CI runs the suite and rubocop on Ruby 3.0 through 4.0. Code must run on all of them. New rubocop offences are fixed rather than added to `.rubocop_todo.yml`, which only grandfathers the pre-6.0 backlog.
|
|
28
|
+
|
|
29
|
+
Repository layout, request flow and conventions are described in [`CLAUDE.md`](https://github.com/tekgnosis-net/wordmove-ng/blob/master/CLAUDE.md).
|
|
30
|
+
|
|
31
|
+
## Commit messages
|
|
32
|
+
|
|
33
|
+
Write [Conventional Commits](https://www.conventionalcommits.org): `fix: …` (patch), `feat: …` (minor), `feat!: …` or a `BREAKING CHANGE:` footer (major), and `docs:`, `chore:`, `ci:`, `test:`, `refactor:` for everything that does not ship a change. The version number and `CHANGELOG.md` are generated from them; never edit `lib/wordmove/version.rb` or the changelog by hand.
|
|
34
|
+
|
|
35
|
+
## Releasing
|
|
36
|
+
|
|
37
|
+
Releases are automated by [release-please](https://github.com/googleapis/release-please) and published to [rubygems.org](https://rubygems.org/gems/wordmove-ng) with [trusted publishing](https://guides.rubygems.org/trusted-publishing/), so no API key is stored anywhere.
|
|
38
|
+
|
|
39
|
+
1. Every push to `master` updates a "release PR" that bumps the version and the changelog from the commits since the last release. release-please proposes a patch release for any Conventional Commit, `ci:` and `docs:` included, so merge the PR only when there is something worth shipping.
|
|
40
|
+
2. Merging it creates the `vX.Y.Z` tag and the GitHub release.
|
|
41
|
+
3. The `publish` job in `.github/workflows/release.yml` re-runs the suite on the tagged commit, builds the gem, pushes it to rubygems.org and attaches the `.gem` file to the GitHub release.
|
|
42
|
+
|
|
43
|
+
Pushing a `v*` tag by hand at the head of `master` triggers the same publish job.
|
|
44
|
+
|
|
45
|
+
## This documentation
|
|
46
|
+
|
|
47
|
+
The site is built from the `docs/` folder on `master` with Jekyll and the just-the-docs theme by `.github/workflows/pages.yml`. Preview locally with
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd docs && bundle install && bundle exec jekyll serve
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Please keep it, and the README, updated when changing user-facing behaviour.
|