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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f483b0f5d6fbc250704d0f32134a73eef315ab0cc2b31d8313a1e6553ad1aaa
4
- data.tar.gz: dfd3302b3678fac11044ea5a51405b57c4aab7369171f9d04d6b1e932476bd8a
3
+ metadata.gz: f35d0da6f7b15e8f492351b76ea90e096fe73b5c94cf55d9e8f10a0e93eb3802
4
+ data.tar.gz: cebf5ecc1de41bf581c5b07cdf4446e87ead5b73c891393b60cfa7a6d702c14c
5
5
  SHA512:
6
- metadata.gz: fdc7e665dbbe4e97cd9d58310cad0c23ca0cde8870da5470390aa4ac0e02285fa78be59676658b60a93490e86b7addc807cb9007821bd94787b2bbf843a4b9e8
7
- data.tar.gz: e33568402ef5f6638f8fe0748d29aeedd724af84f84ea9395dd7c7b9f2d89cbc051437c5ea3cf2afe317a248cc21dee1fabfb3cc43f8d236e5506a5c74359f6c
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
- run: gh release upload "$TAG" pkg/*.gem --clobber
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
@@ -19,3 +19,5 @@ test/tmp
19
19
  test/version_tmp
20
20
  tmp
21
21
  .vs/
22
+ docs/_site
23
+ docs/Gemfile.lock
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "6.0.0"
2
+ ".": "6.0.1"
3
3
  }
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 (unreleased)
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
- [![Tests](https://github.com/tekgnosis-net/wordmove-ng/actions/workflows/ruby.yml/badge.svg)](https://github.com/tekgnosis-net/wordmove-ng/actions/workflows/ruby.yml)
15
+ **Full documentation: <https://tekgnosis-net.github.io/wordmove-ng/>**
16
+
17
+ [![Tests](https://github.com/tekgnosis-net/wordmove-ng/actions/workflows/ruby.yml/badge.svg?branch=master)](https://github.com/tekgnosis-net/wordmove-ng/actions/workflows/ruby.yml?query=branch%3Amaster)
18
+ [![Gem](https://img.shields.io/gem/v/wordmove-ng)](https://rubygems.org/gems/wordmove-ng)
19
+ [![Docs](https://img.shields.io/badge/docs-tekgnosis--net.github.io%2Fwordmove--ng-blue)](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
- Until the gem is on rubygems.org, or to run the latest master:
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 wiki has the full reference:
246
- [movefile.yml configurations explained](https://github.com/tekgnosis-net/wordmove-ng/wiki/movefile.yml-configurations-explained),
247
- [Usage and flags explained](https://github.com/tekgnosis-net/wordmove-ng/wiki/Usage-and-flags-explained),
248
- [Multiple environments explained](https://github.com/tekgnosis-net/wordmove-ng/wiki/Multiple-environments-explained),
249
- [Hooks](https://github.com/tekgnosis-net/wordmove-ng/wiki/Hooks).
250
- Where a wiki page still describes wordmove 5.x behaviour, this README wins.
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 is cut.
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
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "jekyll", "~> 4.4"
4
+ gem "just-the-docs", "~> 0.12"
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 &copy; 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.