Use strapi_migration_v5 compose project consistently when starting mysql/mariadb containers in prepareDockerDatabase, matching postgres wipe.
Migration integration tests
End-to-end checks for v4 (or pinned v5) seed → optional published Strapi via steps → always workspace on the monorepo’s migration test fixture at examples/complex.
Test fixture
The Strapi app, schemas, seeds, validators, and DB tooling live in examples/complex/ (workspace name complex). This directory (tests/migration/) owns the runner, scenarios, and CI wiring only.
The fixture path is historical; we may relocate it under tests/migration/ later (e.g. tests/migration/fixture/). Until then, CI watches both trees — see When migration_v5 runs and .github/filters.yaml.
Requirements
--initial <semver>— explicit starting npm version (required unless you pass--scenario). Final app is always workspace; there is no--finalStrapi version.--via/-v— optional repeatable pinned Strapi versions between seed and workspace.
Hands-on commands and yarn test:migrations flags: examples/complex/README.md — Automated migration test. CI triggers and path filters are documented below (not repeated in the fixture README).
Quick reference
# Fast local smoke (~1–2 min when dist is warm)
yarn test:migrations:smoke
# Plan only (seconds; no installs)
yarn test:migrations:plan --initial 4.26.0
# Full local run (sqlite default; add --skip-build when already built)
yarn test:migrations --initial 4.26.0 --database sqlite --skip-build
JSON scenarios live in scenarios/. Optional checkpoints: CHECKPOINTS.md.
CI (GitHub Actions)
Job migration_v5 in .github/workflows/tests.yml runs:
yarn test:migrations --initial "$VERSION" --initial-node 20 --database <matrix> --skip-build
on sqlite, postgres, mysql, and mariadb (Node 20). $VERSION is the latest Strapi v4 from npm: npm view @strapi/strapi@legacy version. The step uses timeout 25m.
CI parity (local vs GitHub)
- Nested
yarn installin ephemeral apps (.migration-v5/) uses an emptyyarn.lock(standalone project marker) plusYARN_ENABLE_IMMUTABLE_INSTALLS=falseso PR hardened mode does not fail withYN0028when the lockfile is populated. - CI also sets
YARN_ENABLE_IMMUTABLE_INSTALLS: falseon the job and passes--initial-node 20to match the runner. - Postgres / MySQL / MariaDB matrix legs start DB containers via
examples/complex/docker-compose.dev.yml. CI setsSTRAPI_BENCH_RUNTIME=docker(andcompose.jsprefers Docker whenGITHUB_ACTIONS=true) because Podman is often installed on runners but not running. - If CI fails on nested install but local passes, compare Node major and re-run with
--initial-node 20.
When migration_v5 runs
Job migration_v5 runs when the migrations path filter matches the PR/push diff. Exact globs are defined only in .github/filters.yaml (that file’s other groups, e.g. global:, are independent).
Optional follow-up: v5-only baseline or extra --via matrix legs are not in CI yet.
Implementation
- Runner:
scripts/run-migration-scenario.js - Validators:
framework/validators.js