# civictheme-upgrade > Plan and execute CivicTheme upgrades in Drupal projects. Use when working with Drupal sites using CivicTheme that need version upgrades (e.g., 1.10→1.11, 1.11→1.12). Handles SDC migration, Twig syntax updates, build tooling changes, and customisation preservation. Triggers include "upgrade civictheme", "civictheme migration", "update civictheme version", or any CivicTheme-related Drupal theme upgrade work. - Author: ivangrynenko - Repository: truecms/civictheme-upgrade-lab - Version: 20251230222732 - Stars: 1 - Forks: 0 - Last Updated: 2026-02-08 - Source: https://github.com/truecms/civictheme-upgrade-lab - Web: https://mule.run/skillshub/@@truecms/civictheme-upgrade-lab~civictheme-upgrade:20251230222732 --- --- name: civictheme-upgrade description: Plan and execute CivicTheme upgrades in Drupal projects. Use when working with Drupal sites using CivicTheme that need version upgrades (e.g., 1.10→1.11, 1.11→1.12). Handles SDC migration, Twig syntax updates, build tooling changes, and customisation preservation. Triggers include "upgrade civictheme", "civictheme migration", "update civictheme version", or any CivicTheme-related Drupal theme upgrade work. --- # CivicTheme Upgrade Skill Assists with planning and executing CivicTheme upgrades in Drupal projects using a documentation-first, sequential upgrade approach. ## Core Principles 1. **Sequential upgrades**: One CivicTheme release per upgrade step. Never skip versions. 2. **Exact version constraints**: Use `drupal/civictheme:1.12.0` not `^1.12`. 3. **Non-production first**: All work in feature branches, dev, or staging environments. 4. **Preserve `.gitignore`**: Never modify existing `.gitignore` files. 5. **Customisation register**: Track all theme customisations with stable IDs (C001, C002, etc.). ## Workflow Overview ```text 0. Pre-flight → 1. Discovery → 2. Planning → 3. Changes → 4. Validation ``` ### Step 0: Pre-flight (Baseline Normalisation) Before any upgrade, ensure exact version pinning and detect parent-theme modifications. **1. Get versions and locate theme**: ```bash CIVICTHEME_VERSION=$(composer show drupal/civictheme --locked --format=json | grep -o '"version": "[^"]*"' | head -1 | cut -d'"' -f4) INSTALLED_THEME=$(composer show --path drupal/civictheme) echo "Version: $CIVICTHEME_VERSION | Path: $INSTALLED_THEME" # Check constraint type in composer.json grep -A2 '"drupal/civictheme"' composer.json ``` **Constraint classification**: Exact (`1.12.0`) = OK. Non-exact (`^1.12`, `~1.12`, `*`) = must normalise after comparison. **2. Detect Composer patches** (these are legitimate customisations): ```bash # Check for patches in composer.json grep -A50 '"patches"' composer.json | grep -A10 '"drupal/civictheme"' || echo "No patches" # Check for external patches file grep '"patches-file"' composer.json ``` **Record any patches found** – they must be applied to the pristine copy for fair comparison. **3. Build pristine copy (with same patches)**: ```bash WORKDIR="/tmp/civictheme-compare" rm -rf "$WORKDIR" && mkdir -p "$WORKDIR/pristine-project" cp -R "$INSTALLED_THEME" "$WORKDIR/installed" cd "$WORKDIR/pristine-project" composer init --no-interaction --name="temp/check" # If patches exist: add cweagans/composer-patches and copy patch config composer require drupal/civictheme:$CIVICTHEME_VERSION --no-interaction PRISTINE=$(composer show --path drupal/civictheme) cp -R "$PRISTINE" "$WORKDIR/pristine" cd - ``` **4. Portable diff** (remove noisy dirs from copies first): ```bash rm -rf "$WORKDIR/installed/node_modules" "$WORKDIR/pristine/node_modules" rm -rf "$WORKDIR/installed/.npm" "$WORKDIR/pristine/.npm" rm -rf "$WORKDIR/installed/storybook-static" "$WORKDIR/pristine/storybook-static" # NOTE: Do NOT remove dist/ by default – compiled asset differences ARE meaningful diff -rq "$WORKDIR/pristine" "$WORKDIR/installed" ``` **If differences found** (after patch-aware comparison): Parent theme manually modified. Backup, record as HIGH risk, **STOP** for developer decision. **If no differences and non-exact constraint**: ```bash composer require drupal/civictheme: --no-update ``` ### Step 1: Discovery Identify current state and customisations: ```bash # Current CivicTheme version (use --locked for authoritative source) composer show drupal/civictheme --locked | grep -E "^versions" # Drupal core version (1.11+ requires ^10.2 || ^11) drush status --field=drupal-version # Find sub-theme location ls -la web/themes/custom/ # Audit Twig templates for breaking patterns grep -rn "include '@atoms/" /templates/ grep -rn "{% extends " /templates/ grep -rn "_slot %}" /templates/ ``` ### Step 2: Planning Read version-specific documentation: ```text references/versions/v-to-v/ ├── spec.md # What & why (upstream changes, risks) ├── tasks.md # Checklist (tickable items) └── playbook.md # How (ordered runbook) ``` Cross-reference with `references/customisations.md` to identify impacted customisations. ### Step 3: Changes Apply upgrade in order: 1. **Composer update**: `composer require drupal/civictheme:` 2. **Twig syntax**: Update include patterns 3. **Block names**: Rename `_slot` → `_block` 4. **Library overrides**: Update file references in `.info.yml` 5. **Build tooling**: Update `package.json`, `build.js`, Storybook config ### Step 4: Validation ```bash drush cr && drush updb && drush cim -y composer show drupal/civictheme --locked | grep -E "^versions" # Verify exact version npm run build # or ahoy fe ``` **Success criteria**: Version output matches exact target version (e.g., `1.12.0`). Test: home page, navigation, search, forms, custom components. ## Version-Specific References | Upgrade Path | Key Changes | Reference | |-----------------|---------------------------------------|--------------------------------------------| | 1.10.0 → 1.11.0 | SDC migration, Twig namespace changes | `references/versions/v1.10.0-to-v1.11.0/` | | 1.11.0 → 1.12.0 | Security fixes, SDC refinements | `references/versions/v1.11.0-to-v1.12.0/` | | 1.12.0 → 1.12.1 | Patch release | `references/versions/v1.12.0-to-v1.12.1/` | | 1.12.1 → 1.12.2 | Patch release | `references/versions/v1.12.1-to-v1.12.2/` | **Before starting any upgrade**, read the relevant `spec.md` and `tasks.md` for that version step. ## Critical Breaking Changes (1.11.0+) ### Twig Include Syntax ```twig {# OLD (pre-1.11) #} {% include '@atoms/paragraph/paragraph.twig' %} {% include '@molecules/logo/logo.twig' %} {# NEW (1.11+) #} {% include 'civictheme:paragraph' %} {% include 'civictheme:logo' %} ``` ### Block Naming ```twig {# OLD #} {% block content_slot %} {# NEW #} {% block content_block %} ``` ### Template Extension **Not supported in 1.11+**: `{% extends %}` and `{{ parent() }}` for CivicTheme components. Options: - **Override completely**: Copy full upstream template, apply customisations inline - **Remove override**: Use upstream component unchanged ### Library Overrides (`.info.yml`) ```yaml libraries-override: civictheme/global: css: theme: dist/civictheme.base.css: dist/styles.base.css dist/civictheme.theme.css: dist/styles.theme.css dist/civictheme.variables.css: dist/styles.variables.css js: dist/civictheme.drupal.base.js: dist/scripts.drupal.base.js ``` ## Customisation Register Maintain at `docs/civic-theme-upgrades/customisations.md` with: ```markdown - [ ] C001 [HIGH] Custom header override - templates/civictheme-header.html.twig - [ ] C002 [MEDIUM] Event listing styles - scss/components/_event-card.scss - [ ] C003 [LOW] Footer logo swap - templates/civictheme-footer.html.twig ``` Impact levels: - **HIGH**: Extended templates, structural changes - **MEDIUM**: Style overrides, custom components - **LOW**: Minor tweaks, configuration ## Stop Conditions Halt and seek developer input when: 1. CivicTheme version doesn't match expected "from" version 2. Drupal core < 10.2 (for 1.11+ upgrades) 3. `{% extends %}` patterns found (requires refactoring decision) 4. Build failures after tooling updates 5. Test regressions detected 6. **Parent theme modified**: Differs from pristine **after applying same Composer patches** 7. **Dev/non-release version**: `composer.lock` shows `dev-*` or non-semver version 8. **Composer patches exist**: Record patches in register; ensure they're applied in pristine comparison **DO NOT**: - Run `composer update` globally—only update CivicTheme deliberately - Modify `web/themes/contrib/civictheme` directly—treat as overwriteable - Run `npm install` inside `web/themes/contrib/civictheme`—masks real diffs - Flag diff as "modification" without applying same patches to pristine ## Additional References - `references/planning.md` - Global framework and governance - `references/customisations.md` - Customisation register template - `references/versions/*/spec.md` - Version-specific specifications - `references/versions/*/tasks.md` - Version-specific task checklists - `references/versions/*/playbook.md` - Version-specific runbooks ## External Links - CivicTheme docs: - CivicTheme releases: - Upgrade tools: