feat(workspaces): bake cast plugin and allow wp-admin plugin updates - #8
Merged
Merged
Conversation
Bakes the latest LumeWeb/cast develop snapshot (Composer deps vendored at build) into the WordPress image, seeded to fresh plugin volumes and force-kept active by an image-owned MU guard that also works around WP 7.1's plugins-before-pluggable load order (core #62244). Drops DISALLOW_FILE_MODS so wp-admin can install and update plugins; the plugin/theme editor and out-of-band auto-updates stay disabled. Bootstrap runs 'wp plugin activate cast' on every boot, the composer:2 builder base is digest-pinned in versions.env and drift-checked by scripts/verify-pins.sh, and the verify matrix covers the new lockdown contract plus Cast's presence and activation.
This comment has been minimized.
This comment has been minimized.
pcfreak30
marked this pull request as ready for review
September 21, 2026 13:25
A volume seeded before Cast shipped never receives the plugin (one-time seeding), so an unconditional active_plugins filter forced a phantom entry that validate_active_plugins kept removing while the filter kept re-adding. Both force-on filters now apply only while the managed plugin files exist; the verify matrix gains a regression boot asserting the guard stays neutral on a pre-cast volume.
This comment has been minimized.
This comment has been minimized.
The pre-cast-volume regression check used 'wp plugin is-active cast', which failed with a not-found error instead of proving the guard keeps the force-on off while the plugin files are missing. Write the persisted active_plugins entry out (deactivate) before the recreate and assert the guard does not re-add Cast on the next option read.
This comment has been minimized.
This comment has been minimized.
One-time seeding left pre-Cast volumes without cast forever and froze seeded copies at their first-seed version, contradicting delivery-by-image. Adds reconcile_cast(): a flock-serialized, content-compared convergence of only plugins/cast to the image bake each boot, archiving the replaced copy as .cast.bak-<epoch> (dot-prefixed, invisible to get_plugins()). All other plugins stay volume-authoritative. The MU guard keeps its files-presence gate so transient absence never churns a phantom active entry. Regression coverage: guard neutral while files missing, reconcile restores cast, and a drifted cast copy converges back; deactivation ordering fixed so wp plugin deactivate runs before the files are removed (WP-CLI resolves operands via a filesystem scan and errors without rewriting the option).
Code Review Completed! 🔥The code review was successfully completed based on your current configurations. Kody Guide: Usage and ConfigurationInteracting with Kody
Current Kody ConfigurationReview OptionsThe following review options are enabled or disabled:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bakes the latest LumeWeb/cast
developsnapshot (Composer deps vendored at build) into the WordPress image, seeded to fresh plugin volumes and force-kept active by an image-owned MU guard that also works around WP 7.1's plugins-before-pluggable load order.Drops
DISALLOW_FILE_MODSso wp-admin can install and update plugins; the plugin/theme editor and out-of-band auto-updates stay disabled.Bootstrap runs
wp plugin activate caston every boot, and the verify matrix now covers the new lockdown contract and Cast's presence/activation. Existing workspaces pick Cast up on their next image redeploy.Summary
This PR makes the Cast plugin a platform-managed, force-active part of the WordPress workspace image, while re-enabling wp-admin plugin install/update (removing the old
DISALLOW_FILE_MODSlockdown).What changed
Bake Cast into the WordPress image
cast-builderDocker stage pulls the latestdeveloptree snapshot ofLumeWeb/castfrom GitHub, runscomposer install --no-devto vendor runtime dependencies at build time, and copies the result into/usr/src/wordpress/wp-content/plugins/cast.composer:2.10.3by digest).versions.env, passed throughdocker-bake.hcl, and validated byverify-pins.sh.Force Cast to stay active (Cast Guard MU plugin)
mu-plugins/cast-guard.php, is copied into the ephemeralwp-content/mu-pluginson every boot.active_plugins, it re-addscast/cast.phpso the plugin cannot be deactivated via wp-admin, WP-CLI, or REST writes.active_sitewide_plugins) and removes the admin Deactivate action.wp_salt()used by Cast at boot.Startup convergence for existing sites
wp-init.shnow runswp plugin activate caston every boot after the DB is available (fresh installs and existing sites), performing the real one-time activation transition (schema install, rewrite flush).Allow wp-admin plugin updates
wp-config.phpno longer definesDISALLOW_FILE_MODS, so plugin installs and updates through wp-admin work.DISALLOW_FILE_EDIT) and automatic/out-of-band updates remain disabled.Verification updates
verify-wordpress.shnow asserts Cast is present on fresh volumes, active, and survives container recreation.cast-guard.phpexists.DISALLOW_FILE_MODSis absent from the generated config while the other lockdown constants remain.Review note
The automated review flagged one high severity issue:
cast-guard.phpfiltersoption_active_pluginsunconditionally, so on an already-seeded plugins volume where Cast files are missing, the plugin is reported as active even though it does not exist — masking the missing state and defeating the deferred-delivery design. This should be addressed before merge.