drupal-contrib-mgmt
Comprehensive guide for managing Drupal contributed modules via Composer, including updates, patches, version compatibility, and Drupal 11 upgrades. Use when updating modules or resolving dependency issues.
What this skill does
# Drupal Contrib Module Management
## Core Update Workflow
### Standard Module Update
```bash
# Update a single module
composer require drupal/module_name --with-all-dependencies
# Update to specific version
composer require drupal/module_name:^3.0 --with-all-dependencies
# Update multiple modules
composer require drupal/module_a drupal/module_b --with-all-dependencies
# After any update, ALWAYS run database updates
drush updb -y
# Clear cache if needed
drush cr
# CRITICAL: Test by visiting pages to check for fatal errors
# Visit at least one page that uses the updated module
```
### Major Version Upgrades
When upgrading to a new major version (e.g., 2.x → 3.x):
1. **Check compatibility**: Ensure module supports your Drupal core version
2. **Search issue queue** for patches: `https://www.drupal.org/project/issues/MODULE_NAME?categories=All`
3. **Use Drupal Lenient** for version requirement issues (see below)
4. **Apply patches** via composer.json (see Patch Management section)
5. **Run upgrade_status** to check for deprecations
## Checking Drupal 11 Compatibility
**Three methods to check if a module is D11 compatible** (in order of preference):
### Method 1: Check .info.yml File (Fastest, Most Reliable)
```bash
# Check the module's .info.yml file for core_version_requirement
cat docroot/modules/contrib/MODULE_NAME/MODULE_NAME.info.yml | grep core_version_requirement
```
**What to look for**:
```yaml
core_version_requirement: ^9.5 || ^10 || ^11 # ✅ D11 compatible
core_version_requirement: ^8 || ^9 || ^10 || ^11 # ✅ D11 compatible
core_version_requirement: ^9 || ^10 # ❌ Not D11 compatible yet
```
**Example**:
```bash
$ cat docroot/modules/contrib/admin_toolbar/admin_toolbar.info.yml | grep core_version
core_version_requirement: ^9.5 || ^10 || ^11
# ✅ This module declares D11 support!
```
### Method 2: Use Composer Commands (Works Before Installing)
```bash
# Check what versions are available and their constraints
composer show drupal/MODULE_NAME --all | grep -A5 "^versions"
# Check currently installed version
composer show drupal/MODULE_NAME | grep versions
```
**What to look for**:
- Version number (e.g., 3.6.2)
- Check Drupal.org for release notes mentioning D11
### Method 3: Check Drupal.org Project Page
Only use as fallback when above methods aren't conclusive.
```
https://www.drupal.org/project/MODULE_NAME
```
Look for:
- Latest release notes mentioning "Drupal 11"
- Module page header showing D11 compatibility badge
- Issue queue for D11 compatibility issues
**Important Notes**:
- ⚠️ Module may declare D11 support but still have deprecation warnings
- ⚠️ upgrade_status warnings don't mean module is incompatible
- ⚠️ "Check manually" status often means runtime version checks (false positive)
- ✅ If .info.yml declares `^11` support, module maintainer says it works
**Real-World Examples**:
```bash
# admin_toolbar - Already D11 compatible
$ cat docroot/modules/contrib/admin_toolbar/admin_toolbar.info.yml | grep core_version
core_version_requirement: ^9.5 || ^10 || ^11
# But upgrade_status shows warnings about _drupal_flush_css_js()
# This is a FALSE POSITIVE - module handles it with version checks
# audiofield - Already D11 compatible
$ cat docroot/modules/contrib/audiofield/audiofield.info.yml | grep core_version
core_version_requirement: ^8 || ^9 || ^10 || ^11
# Has deprecation warnings but maintainer declares D11 support
```
## Drupal Lenient Plugin
The `mglaman/composer-drupal-lenient` plugin allows installing modules that haven't updated their version requirements yet.
### Setup
```json
{
"require": {
"mglaman/composer-drupal-lenient": "^1.0"
},
"config": {
"allow-plugins": {
"mglaman/composer-drupal-lenient": true
}
},
"extra": {
"drupal-lenient": {
"allowed-list": [
"drupal/module_name",
"drupal/another_module"
]
}
}
}
```
### Usage
```bash
# Add module to allowed-list, then install
composer require drupal/module_name --with-all-dependencies
```
## Patch Management (cweagans/composer-patches)
**IMPORTANT**: Use version 2.x for reliable patch application. Version 1.x uses the `patch` binary which can have issues on some systems. Version 2.x uses `git apply` by default.
### Patch Configuration
```json
{
"require": {
"cweagans/composer-patches": "^2.0"
},
"config": {
"allow-plugins": {
"cweagans/composer-patches": true
}
},
"extra": {
"composer-exit-on-patch-failure": true,
"patches": {
"drupal/module_name": {
"Description of patch": "https://www.drupal.org/files/issues/2024-01-15/module-issue-1234567-8.patch",
"Local patch": "patches/custom-fix.patch"
}
},
"patchLevel": {
"drupal/core": "-p2"
}
}
}
```
### Upgrading from 1.x to 2.x
If you're on version 1.x and experiencing patch failures:
```bash
composer require cweagans/composer-patches:^2.0 --with-all-dependencies
```
Key differences in 2.x:
- Uses `git apply` instead of `patch` binary (more reliable)
- `enable-patching` option removed (patching is always enabled)
- Better error messages and debugging
- **CRITICAL — the `patches.lock.json` apply source**: v2 applies patches from `patches.lock.json` on `composer install` / `composer reinstall`. It does **NOT** read `extra.patches` in `composer.json` during those commands — only `composer update` and `composer patches-relock` re-read `composer.json` and regenerate the lock. So adding a patch to `composer.json` and running `composer install` applies **nothing** for that patch until you relock. This is the #1 cause of patches that "keep regressing": local dev looks fixed (you hand-applied it or ran `update`), but the next clean install — CI, a teammate, a fresh deploy — reads the stale lock and drops the patch. **Always run `composer patches-relock` after editing `extra.patches`, and commit `patches.lock.json`.**
### Verifying Patches Are Applied
**THREE DIFFERENT PROBLEMS, ONE SCRIPT**:
1. **Lock-sync staleness (the root cause)**: a patch is registered in `composer.json` `extra.patches` but never added to `patches.lock.json` because `composer patches-relock` was skipped. v2 applies from the lock on `composer install`, so the patch is silently a no-op on every clean install. The fix is the relock; the script's job is to *catch* the skip by asserting every local patch in `composer.json` is present in `patches.lock.json`.
2. **Committed file drift**: a patch IS applied to the working tree, but the resulting contrib file change is never committed to git. Pantheon (and any platform that deploys from committed git state without running `composer install`) never sees it, so production silently runs un-patched code. Local dev looks fine. See CLAUDE.md "Contrib/Core Patch Policy" for context.
3. **Patch hash cache staleness**: even with the lock in sync, a stray reinstall or vendor update can skip re-applying. Rare next to (1) and (2), but the same materialized-file check catches it.
**SOLUTION**: `scripts/verify-patches.sh`
```bash
# Run manually (verifies committed state)
./scripts/verify-patches.sh
# Auto-reinstall affected modules to re-apply patches
./scripts/verify-patches.sh --fix
```
**Behavior**:
- Runs two checks. (1) **Lock-sync**: every local patch in `composer.json` `extra.patches` must also appear in `patches.lock.json` — catches the skipped `patches-relock`. (2) **Materialized-file**: the patched lines must be present in the committed contrib file — catches "patched but not committed".
- Auto-derives the verification list from `composer.json` `extra.patches` — **no manual curation required**. Adding a patch entry is enough; the script picks it up automatically.
- For each local patch (value starting with `patches/`), it parses all `+++ b/<path>` headers, extracts up to 5 distinctive added lines (≥ 8 non-whitespace chars, not a substring of any `-` line in the same patch), and greps the target file for them. Handles tRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.