Upgrade Module Skill
Upgrades Drupal modules with intelligent version handling. Defaults to safe minor/patch upgrades. Prompts before major version upgrades that may have breaking changes.
Usage
/upgrade-module <module-name> [module-name2] ...
Behavior:
- Minor/patch (6.2.0 → 6.3.0): Auto-upgrade, backwards-compatible
- Major (6.2.0 → 7.0.0): Prompt user, may have breaking changes
Handles:
- Version analysis with smart defaults
- Dependency resolution and ordering
- Security advisory detection
- Patch failure resolution
- Custom code updates (major versions only)
- Database updates and config export
- Comprehensive commit messages
Prerequisites
- Dev/local environment (will warn if production)
- Clean git working tree
- Composer and Drush available
Workflow
Phase 1: Discovery & Analysis
- Validate modules exist in composer.json
- Check current versions from composer.lock
- Find available versions:
composer show vendor/module --all - Categorize each module:
- Patch: 6.2.3 → 6.2.5 (bug fixes)
- Minor: 6.2.3 → 6.4.0 (new features, BC)
- Major: 6.2.3 → 7.0.0 (breaking changes)
- Default target: latest minor (will prompt for major)
Phase 2: Planning & User Confirmation
For modules with major versions available, prompt:
drupal/webform 6.2.3
- Latest minor: 6.5.0 (recommended, no breaking changes)
- Latest major: 7.0.2 (⚠️ may have breaking changes)
Upgrade to major version? [y/n/info]
If "info": Show CHANGELOG.md highlights, then re-prompt.
Build upgrade plan based on choices:
Upgrade Plan:
1. drupal/token: 1.11.0 → 1.13.0 [minor] ✓
2. drupal/webform: 6.2.3 → 7.0.0 [MAJOR] ⚠️
Dependencies: symfony/yaml 5.4.0 → 5.4.3
Custom code analysis will run for: webform
Proceed? [y/n]
Phase 3: Execution (per module)
Update composer.json version constraint
- Minor:
"^6.0"(if not already) - Major:
"^6.0"→"^7.0"
- Minor:
Run composer update
composer update vendor/module --with-all-dependenciesHandle security advisories (if blocked):
- Show vulnerabilities with CVE details
- Present options:
- Cancel - fix security issues first
- Proceed anyway (may resolve some)
- Show more details
- If proceeding:
composer config audit.block-insecure false- Run update
composer config audit.block-insecure true- Run
composer auditto check if resolved - Warn if vulnerabilities remain
Handle patch failures (interactive):
For each failed patch:
- Analyze: Read patch, extract issue number, determine source
- Check if still needed: Read CHANGELOG, check issue status
- Present options:
- Remove (fixed in new version)
- Search drupal.org for updated patch
- Regenerate with increased fuzz
- Skip - handle manually
- Execute choice and re-run composer update
Verify: Check composer.lock shows new version
Phase 4: Custom Code Analysis & Updates
Only runs for major version upgrades
Find breaking changes:
- Read vendor/MODULE/CHANGELOG.md (look for "Breaking", "Deprecated", "API changes")
- Check drupal.org release notes
- Extract specific changes (function signatures, removed APIs, etc.)
Search custom code for usage:
grep -r "deprecated_function" web/modules/custom/ web/themes/custom/ grep -r "use Drupal\\module_name\\" web/modules/custom/ grep -r "hook_module_" web/modules/custom/Present findings:
Custom Code Impact (webform 6→7): Breaking changes: - getData() now requires $format parameter - hook_webform_submission_presave() signature changed Affected files: 1. web/modules/custom/mymodule/WebformSubscriber.php:45 Fix: Add 'raw' parameter to getData() 2. web/modules/custom/mymodule/mymodule.module:89 Fix: Add $update parameter to hook Implement fixes? [y/n]Implement fixes (if confirmed):
- Read each file for context
- Update code using Edit tool
- Verify syntax:
php -l file.php - Check for cascading impacts
Run static analysis (if available):
vendor/bin/phpstan analyse web/modules/custom
Phase 5: Post-Upgrade Tasks
- Database updates:
drush updatedb --yes - Clear caches:
drush cache:rebuild - Export config:
drush config:export --yes - Status check:
drush status - Ask about testing:
Tests available: PHPUnit (156), Functional (42) Run tests? [y/n]
Phase 6: Commit
Generate commit message:
For minor/patch only:
Upgrade contributed modules to latest compatible versions
Upgraded:
- drupal/token: 1.11.0 → 1.13.0 [minor]
- drupal/webform: 6.2.3 → 6.5.0 [minor]
Dependencies: symfony/yaml: 5.4.0 → 5.4.3
All upgrades backwards-compatible.
For major versions:
Upgrade contributed modules including major versions
Upgraded:
- drupal/webform: 6.2.0 → 7.0.0 [MAJOR]
- drupal/token: 1.11.0 → 1.13.0 [minor]
Dependencies: drupal/ctools: 3.14.0 → 4.0.0 (required by webform 7.x)
Patches:
- Removed webform-fix-12345.patch (fixed in 7.0.0)
Custom code updates for webform 7.0:
- Updated WebformSubscriber.php getData() signature
- Fixed hook_webform_submission_presave() parameters
Security advisories: 2 detected, 0 remain after upgrade
Commit:
git add composer.json composer.lock patches/ web/modules/custom/ web/themes/custom/
git commit -m "$(cat <<'EOF'
[message here]
EOF
)"
Finding Breaking Changes
Priority order:
vendor/drupal/MODULE/CHANGELOG.md- Look for "Breaking", "Deprecated", "API"vendor/drupal/MODULE/UPGRADE.mdorUPGRADE.txt- Drupal.org release notes:
https://www.drupal.org/project/MODULE/releases/VERSION - Change records:
https://www.drupal.org/list-changes/MODULE - Git log:
cd vendor/drupal/MODULE && git log 6.0.0..7.0.0 --grep="break\|deprecat"
Quick search:
grep -i "deprecat\|break\|remov" vendor/drupal/MODULE/CHANGELOG.md
grep -r "@deprecated" vendor/drupal/MODULE/src/
Patch Management
Drupal.org patches: URL contains drupal.org/files/issues, has issue ID
Custom patches: In patches/ directory, no drupal.org URL
When patch fails:
- Remove if: Issue marked "Fixed" in target version, or code inspection shows fix included
- Update if: Issue still active, newer patch available in issue queue
- Skip if: Uncertain, needs manual review
Check issue status: Extract issue ID from patch URL → visit drupal.org/project/MODULE/issues/ID
Error Handling
Security advisories blocked:
- Never auto-bypass - always present to user
- Temporarily disable if user chooses to proceed
- Always re-enable after update
- Document in commit if encountered
Dependency conflicts:
- Update conflicting dependency first
- Adjust upgrade order
Database update fails:
- Do not commit
- Report for manual intervention
PHP version incompatible:
- Report required PHP version
- Suggest environment update
Tips
- Default upgrades are safe (minor/patch only)
- Use "info" option to review major version changes
- Grep custom code before accepting major upgrades to estimate impact
- Test major upgrades thoroughly, especially with custom integrations
Troubleshooting
"No version satisfying XYZ": Check composer show vendor/module --all
"Requirements could not be resolved": Dependency conflict - try updating dependencies first, may need core upgrade
Notes
- Review composer output for deprecation warnings
- Major upgrades may require custom code changes
- Check module upgrade guide on drupal.org
- Use
composer why vendor/moduleto understand dependencies