Releasing SpawnWP¶
Releases are stable SemVer tags and immutable GitHub Release assets. The repository is
tts-empire/spawnwp; prereleases are not accepted by the updater.
Release key¶
The signing key currently lives at /root/.config/spawnwp/release-private.pem, mode
0600. It is never committed or uploaded to GitHub. Before public release, move release
signing to an offline workstation and keep an encrypted offline backup. The corresponding
public-key SHA-256 fingerprint is:
Publish a stable release¶
- Update
VERSION,docs/changelog.mdanddocs/release-notes/X.Y.Z.md. - Run the test workflow locally and ensure the working tree is clean.
- Create and push the annotated
vX.Y.Ztag from the release commit. - Build, sign and upload the immutable assets:
git tag -a vX.Y.Z -m "SpawnWP X.Y.Z"
git push origin main vX.Y.Z
SPAWNWP_RELEASE_KEY=/secure/path/release-private.pem \
bash updater/publish-release.sh X.Y.Z
The publishing script refuses to replace an existing release. Verify the release from an
installed server with spawnwp update --check; then test update and rollback on a clean
staging server before announcing it.
Release SpawnWP Deploy¶
WordPress.org is the only stable release authority for the optional plugin. The
distributable tree under plugins/spawnwp-deploy/ on main must match the current
WordPress.org ZIP; develop the next version on a dedicated branch.
- Update the plugin header, version constant,
readme.txtStable tag and changelog on the release branch. - Run PHP lint, JavaScript syntax checking, WPCS, PHPCompatibilityWP, Plugin Check and the clean-site smoke test.
- Copy the approved distributable tree to SVN trunk, create
tags/X.Y.Z, commit and complete WordPress.org Release Confirmation if enabled. - Wait until the Plugin Information API and official ZIP expose
X.Y.Z. Do not merge the release branch while the API still reports the previous stable. - Verify the production mirror and Git source:
sudo python3 /usr/local/lib/spawnwp/sync_wporg_plugin.py --check
python3 ops/website/sync_wporg_plugin.py \
--check-source plugins/spawnwp-deploy \
--lock-file /tmp/spawnwp-plugin-source-check.lock
The production timer checks every ten minutes and signs the exact WordPress.org ZIP for legacy cockpit clients. It never writes to SVN. New cockpit sites prefer this verified stable mirror and fall back to the stable ZIP embedded in the current SpawnWP release when offline. Existing WordPress sites update through WordPress core; do not add a custom plugin updater or force automatic updates.
Clean-server acceptance gate¶
A release is not stable until its public installer and signed assets pass on a separate, fresh server. The development/origin host is not an acceptable substitute. Verify:
- installation, one-time activation, Passkey, TOTP and recovery codes;
- an initially empty cockpit and deployment with every built-in blueprint;
- WordPress, WP Admin, Adminer, Mailpit and generated credentials;
- full-stack and per-container lifecycle actions;
- PHP switching, including expired recent-authentication and inline confirmation;
- snapshot/restore, complete destroy and Nginx rollback after a failed deployment;
- telemetry enable/disable, dashboard update, reboot persistence and rollback;
nginx -t,certbot renew --dry-run, and public exposure limited to ports 80/443.
Do not repair the staging server manually. Fix the repository, publish a new signed release, update the staging server through the product, and repeat the failed test.
Repository transition¶
While the repository is private, update checks use the server's GitHub CLI credentials.
When it becomes public, clients work anonymously without configuration. At that point,
enable GitHub Pages, restore the docs workflow's push trigger, and enable main branch
protection with the validate check required.