Ss5 data migration
Agent skills for Silverstripe CMS development — version upgrades, Elemental, the Essentials stack, and deployment workflows
npx -y skills add jsirish/silverstripe-skills --skill ss5-data-migrationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Complete workflow for executing Silverstripe 5 data migration tasks. Use this skill when the user wants to "run migration tasks", "migrate data", "sync and migrate", or specifically refers to "SS5 data migration" after a database sync or deployment.
SKILL.md
9.8 KB, as published. Nobody here has run it
SS5 Data Migration
Overview
This skill provides a reliable, ordered workflow for executing the necessary data migration tasks after upgrading a Silverstripe 4 project to Silverstripe 5 (specifically for Dynamic Agency Base Site architectures). It ensures all layout, content, and settings data are properly migrated to the new schema formats.
Prerequisites
Before running these migrations, ensure:
- The codebase is fully deployed and the
dev/buildhas completed successfully. - If working locally, you have synchronized the latest production database (e.g., using
ddev syncor a similar workflow).
Workspace Migration Skill Strategy
Due to project-specific differences (such as custom element types, obsolete legacy structures, or unique data schema), the exact migration tasks vary per project.
This global skill strongly recommends formalizing a project-specific migration command that documents the exact tasks to run in order for that specific site. The following workflow is an example baseline.
Canonical location: .claude/commands/migrate.md
Put the project runbook at .claude/commands/migrate.md so it becomes a Claude Code
slash command — typing /migrate loads the full runbook with context. This is more
discoverable and better documented than a plain .agent/workflows/data-migration.md
workflow file (which works for unattended // turbo-all runs but gives the developer far
less guidance). Prefer the slash command as the canonical, human-facing runbook; keep a
thin workflow file only if you also want a one-keystroke auto-runner.
[!NOTE]
devbuild.sh= cache rebuild only;migrate.sh= the task runner. Keep the two separate.devbuild.shshould be the 3-line cache-rebuild script (clearsilverstripe-cache, recreate it,dev/build) that DeployHQ runs after a code deploy — it must never run migration tasks. The ordered migration tasks below belong in a separatemigrate.sh(or this/migratecommand), invoked manually after a fresh prod sync. Conflating them causes a doubledev/buildin full-loop scripts and re-runs data migrations on routine deploys.
Minimal .claude/commands/migrate.md starter — fill in the task list from the workflow below:
---
description: Run the full SS5 data migration for <PROJECT> after a fresh prod sync
---
# /migrate — <PROJECT> data migration
Run after a fresh production database sync. Idempotent: safe to re-run on every sync.
## When to use
- After a prod DB + assets sync; NOT during a routine code deploy (that only needs `devbuild.sh`).
## Environments
| Role | Host / source | Notes |
|------|---------------|-------|
| Prod sync source | <host> | Read-only; `sync.sh` pulls DB + assets |
| Local dev | https://<project>.ddev.site | Where tasks run |
| Deploy target | <staging-host> | `deploy.sh` pushes migrated state |
## Task sequence
```bash
ddev exec ./devbuild.sh # cache rebuild only
ddev sake dev/tasks/block-migration "flush=1"
ddev sake dev/tasks/migrate-footer-links "flush=1"
ddev sake dev/tasks/NavigationMigrationTask "flush=1"
# …project-specific tasks…
```
## Expected outputs
- <task> → <confirmation string / row count>
## Verification
- [ ] Frontend QA of each page type — no blank pages
- [ ] ElementalArea_Live populated; CMS Settings/SiteConfig section works
- [ ] <project-specific checks: footer nav, slide-image links, etc.>
[!TIP] The SS3→SS4 skill ships a richer copy-paste template (with a breaking-changes table) at silverstripe-3-to-4-upgrade/references/project-migration-command-template.md. For an SS4→SS5 migration the same structure applies — drop the SS3→SS4 ClassName-remapping rows and keep the environments / expected-outputs / verification sections.
Do not rationalize
A migration step is not done until you have pasted the task output and the verification query results. The actual output, not a recollection.
| Rationalization | Required behavior |
|---|---|
| "No errors printed, so it worked" | Paste the task's migrated/skipped counts and the row-count queries below. Silence is not success; many tasks fail quietly on empty source tables. |
| "Row count looks close enough" | Counts match exactly or every missing row is named (skipped class, intentional exclusion). Paste the delta explanation. |
| "The page renders, so live data is fine" | Query _Live and _Versions directly. Draft-only rows render in the CMS preview and silently vanish on publish. |
| "It ran on the last sync, so it will run on this one" | Re-run and paste this run's output. Fresh syncs reset source data; the previous run proves nothing. |
Per-task verification (required)
After each task in the workflow below, before declaring the step done, paste evidence scoped to what that task writes:
- Tasks that write versioned rows (block migration, link migration, element content): count that task's target tables, draft vs live vs versions:
-- Substitute the task's own target tables; the shape is always draft vs live vs versions
SELECT COUNT(*) FROM Element;
SELECT COUNT(*) FROM Element_Live;
SELECT COUNT(*) FROM Element_Versions;
-- e.g. for the link task:
SELECT COUNT(*) FROM LinkField_Link;
- Tasks that write unversioned config or relations (footer links, navigation settings, link fixes): count the target table before and after, and paste the task's own changed/skipped summary.
- Asset tasks with no row-count target (gallery resample): paste the task output showing files processed, and spot-check one resampled variant on the frontend.
For versioned targets, draft and _Live counts must match for published content, and _Versions must be at least the draft count. Record the counts in the project's /migrate runbook under "Expected outputs" so the next run has a baseline to compare against.
Migration Workflow
The migration tasks must be run in the following sequence to guarantee data integrity.
1. Block Migration
Migrates legacy Elemental blocks to the SS5 standard Element structures.
Command: ddev sake dev/tasks/block-migration "flush=1"
2. Footer Links Migration
Cleans up and reorganizes footer navigation items.
Command: ddev sake dev/tasks/migrate-footer-links "flush=1"
3. Navigation Migration
Migrates core navigation settings and structures.
Command: ddev sake dev/tasks/NavigationMigrationTask "flush=1"
4. Slide Image Linkable Migration
Upgrades SlideImage links to the new LinkField format.
Command: ddev sake dev/tasks/Sail-Task-SlideImageLinkableTask "flush=1"
5. Fix About Links Task
Repairs specific internal links that may have broken during the schema changes.
Command: ddev sake dev/tasks/FixAboutLinksTask "flush=1"
6. Fix HomePage ElementalArea Owner Task
Repairs incorrect OwnerClassName data for ElementalAreas attached to HomePages to ensure specific layout templates resolve correctly.
Command: ddev sake dev/tasks/fix-homepage-elemental-area-owner "flush=1"
7. Asset Resampling (Pre-computation)
Preemptively generates variants (e.g., Fill or ScaleWidth) for heavily populated entities like Galleries before deployment. This prevents the initial page load on the remote server from timing out while computing hundreds of manipulation variants.
Command: ddev sake dev/tasks/gallery-resample-task "flush=1"
Automated Execution
To run all tasks automatically, invoke the project's /migrate slash command
(.claude/commands/migrate.md, see above) or
its migrate.sh runner. A .agent/workflows/data-migration.md workflow file with
// turbo-all is an acceptable lighter-weight alternative for unattended runs, but the slash
command is the canonical, better-documented form. Whichever you use, ensure each command exits
successfully before proceeding to the next, and keep these tasks out of devbuild.sh
(which is cache-rebuild-only).
An automated run still owes the per-task verification evidence: capture each task's output and the row-count queries in the run log. Exit code 0 alone does not clear the gate.
Deployment Strategy
When deploying migrated data and pre-computed assets to staging or production, a local rsync push is often more reliable than requesting the remote server to pull and compile constraints:
- rsync
public/assets/directly: Transferring thepublic/assets/directory (which contains all the locally generated manipulation variants from tasks likeGalleryResampleTask) averts the need for the live environment to lazily reconstruct the cache on the fly. - Deploy script: Use a
.env-backeddeploy.shscript to dump the local migrated database and sync assets, effectively pushing the exact tested state to the remote.
Heuristic Link Verification
After migrating structural links (especially mapping obsolete BlockLinkID or flat PageLinkID columns to the new LinkField records), verify site-specific hardcoded logic.
- Custom templates or unique features (e.g., the SlideImage header or an About Page's "Learn More" links) may lose connection if they bypass standard Elemental structures.
- Manual post-migration tasks (like a
FixAboutLinksTask) should be built to map known edge case links.
Troubleshooting
- If a task fails with a memory or timeout error, you may need to increase the PHP limits or execute the task via the browser interface instead of the CLI.
- Ensure
flush=1is appended to each command to clear cached configuration and class manifests between tasks.