Use when updating a DDEV-based ProcessWire project's modules and core through CLI automation.
-
Gate: ask the user which ProcessWire core target to use before doing anything else: master or dev. Do not update files or commit until the user chooses. Store this as $targetBranch.
-
Start by scanning for available updates before changing files. Use ProcessWireUpgradeCheck through ddev php:
getModuleVersions(true, true) to list outdated modules.
getCoreBranches(false, true) to fetch all available core branches.
Use the user's $targetBranch choice to select the relevant entry, e.g. $branches[$targetBranch], and use that selected version for compatibility checks and the final core ZIP.
-
Include a compatibility check in the initial scan. Inspect each update's requirements from ProcessWireUpgradeCheck/module-directory data (requiresVersions) and, when ZIP/source files are available, the module's public getModuleInfo() array requires property. Compare requirements against the current PHP_VERSION, current config()->version, and the selected target core branch/version.
-
Decide update order from compatibility results:
- If all module updates satisfy the current PHP and ProcessWire versions, follow the normal modules before core paradigm.
- If one or more module updates require a newer PHP version than DDEV currently provides, warn the user clearly and stop for a PHP/DDEV version decision before installing those modules.
- If one or more module updates require a newer ProcessWire version than currently installed, but the selected target branch satisfies that requirement, explain that this is a compatibility exception and suggest updating ProcessWire core first, then returning to module updates.
- If one or more module updates require a newer ProcessWire version than even the selected target branch provides, stop and warn that the chosen core target is insufficient.
-
If the scan reports Pro/paid modules, stop and ask the user for local ZIP paths for each Pro module before proceeding. Do not assume the paths are the same across projects. Confirm the ZIPs exist and inspect their top-level folder/module names before installation.
-
Start DDEV and create a DB snapshot with ddev snapshot --name before-system-update-$(date +%Y%m%d%H%M%S).
-
Always update modules before ProcessWire core when compatibility allows it. Each module update must be committed separately with a conventional commit.
-
For module ZIPs, use wire/modules/Process/ProcessModule/ProcessModuleInstall.php and ProcessModuleInstall::unzipModule($tempZip, config()->paths->siteModules . $module . '/'), then modules()->refresh() and modules()->resetCache(). Copy paid ZIPs into a project/cache temp path first because unzipModule() deletes the ZIP it extracts.
-
For public modules, download the ZIP quietly into site/assets/cache/module-update-zips/, install via the same ProcessModuleInstall::unzipModule() flow, verify version with getModuleInfoVerbose(), then commit only that module directory.
-
After all modules report no outdated modules, update ProcessWire core from the user-selected branch ZIP, not a hardcoded branch. Replace wire/ from the extracted archive, update index.php when its PROCESSWIRE index version changes, update .htaccess only after reviewing diffs, and update composer.json package metadata if changed.
-
Verify via ddev php bootstrap: config()->version, module versions, selected target branch/version, and count($check->getModuleVersions(true,true)) === 0. Smoke test frontend and the admin URL from config()->urls->admin.