Skip to content

feat: add managed migration chains for enhanced migrations#495

Merged
Kamirus merged 13 commits into
mainfrom
feat/managed-migrations
Apr 16, 2026
Merged

feat: add managed migration chains for enhanced migrations#495
Kamirus merged 13 commits into
mainfrom
feat/managed-migrations

Conversation

@Kamirus
Copy link
Copy Markdown
Collaborator

@Kamirus Kamirus commented Apr 15, 2026

Problem

Managing Motoko enhanced migration chains is entirely manual today. Users must:

  • Manually pass --enhanced-migration=<path> in canister args
  • Name and order migration files correctly
  • Remember to suppress M0254 warnings when trimming chains
  • Keep track of which migrations are "frozen" vs in-progress

This is error-prone and creates friction for any project using enhanced migrations.

Solution

Add first-class migration management to mops via a new [canisters.<name>.migrations] config section and mops migrate commands.

New config

[canisters.backend.migrations]
chain = "migrations"         # frozen migration chain directory
next = "next-migration"      # directory for work-in-progress migration
check-limit = 1              # trim chain to last N for check (faster)
build-limit = 100            # trim chain to last N for build (smaller WASM)

New commands

  • mops migrate new <Name> [canister] — creates a timestamped migration file in the next directory
  • mops migrate freeze [canister] — moves the next migration into the permanent chain

Automatic --enhanced-migration injection

When [migrations] is configured, mops check, mops build, and mops check-stable automatically inject --enhanced-migration pointing to a temp directory that merges the chain + next migration. Explicit --enhanced-migration in [canisters.*.args], [moc].args, or [build].args is rejected to prevent conflicts.

Chain trimming

check-limit and build-limit control how many migrations are passed to moc. When trimming is active, M0254 warnings are auto-suppressed (-A=M0254). This keeps WASM sizes manageable and speeds up type-checking.

Migration hint

When a stable compatibility check fails and [migrations] is configured, a hint is shown: "You may need a migration. Run mops migrate new <Name> to create one."

Scope & limitations

  • Covers migration file lifecycle only. .most file management and deployed state tracking are deferred to a follow-up.
  • Symlinks are used for temp directories, which requires no special permissions on macOS/Linux but may need developer mode on native Windows.

Test plan

  • mops migrate new creates correctly named file with template (snapshot)
  • mops migrate new rejects invalid names (path traversal, spaces, digits-first)
  • mops migrate new errors when next dir already has a file
  • mops migrate new/freeze errors when [migrations] not configured
  • mops migrate freeze moves file from next to chain (snapshot)
  • mops migrate freeze errors when next is empty or file doesn't sort last
  • mops check fails without next migration, passes with it (snapshot — with-next fixture)
  • mops check with check-limit shows trimmed chain in verbose output (snapshot)
  • mops build produces correct .most with full chain (snapshot)
  • mops build with build-limit produces trimmed .most (snapshot)
  • Stable check failure emits migration hint (snapshot)
  • Conflict detection errors when both [migrations] and --enhanced-migration in args
  • TypeScript compiles cleanly, ESLint + Prettier pass, pre-commit hooks pass

Kamirus added 3 commits April 15, 2026 16:24
Add `mops migrate new/freeze` commands and `[canisters.<name>.migrations]`
config to automate Motoko enhanced migration chain management.

When `[migrations]` is configured, `mops check` and `mops build` auto-inject
`--enhanced-migration` with optional chain trimming via `check-limit` and
`build-limit`. A hint is shown on stable check failure suggesting migration
creation.

Spec: cli/specs/managed-migrations.md
Made-with: Cursor
- Sanitize migration name (reject path traversal, spaces, invalid chars)
- Extend --enhanced-migration conflict check to [moc].args and [build].args
- Pass verbose to prepareMigrationArgs in check-stable for consistency
- Validate check-limit/build-limit as positive integers (reject floats)
- Use UTC in generateTimestamp for cross-timezone consistency
- Eliminate redundant readdirSync in prepareMigrationArgs (pass chainFiles)
- Add test for invalid migration name rejection

Made-with: Cursor
check-stable also auto-injects --enhanced-migration when [migrations]
is configured — align all doc surfaces for consistency.

Made-with: Cursor
@Kamirus Kamirus changed the title feat: add managed migrations for enhanced orthogonal persistence feat: add managed migration chains for enhanced migrations Apr 15, 2026
Kamirus and others added 3 commits April 15, 2026 16:55
Git doesn't track empty directories, so cp on CI skips them and tests
fail with ENOENT when writing into the missing dir.

Made-with: Cursor
@Kamirus Kamirus marked this pull request as ready for review April 15, 2026 18:51
@Kamirus Kamirus requested a review from a team as a code owner April 15, 2026 18:51
@alexandru-uta
Copy link
Copy Markdown

The --enhanced-migration flag in [canisters.*.args], [moc].args, or [build].args is rejected to prevent conflicts.

I didn't understand this part; can you please explain?

Kamirus added 5 commits April 16, 2026 13:37
Consolidate 4 fixtures (basic, with-next, trimmed, incompatible) into 2
richer fixtures with 3-migration chains. All tests copy a fixture to a
temp dir and apply targeted modifications (remove next-migration, patch
mops.toml, overwrite deployed.most) to exercise different scenarios.

New snapshot-tested use cases:
- migrate new / freeze output
- check fails without next migration, passes with it
- check with chain trimming (verbose)
- build produces .most with full and trimmed chain
- stable check failure with migration hint

Made-with: Cursor
- "Migration management for enhanced migrations" → "Manage enhanced migration chains"
- Clarify in docs that check-limit applies to mops check-stable too

Made-with: Cursor
No longer needed — the feature is implemented and documented.

Made-with: Cursor
@Kamirus
Copy link
Copy Markdown
Collaborator Author

Kamirus commented Apr 16, 2026

The --enhanced-migration flag in [canisters.*.args], [moc].args, or [build].args is rejected to prevent conflicts.

I didn't understand this part; can you please explain?

Is this clear from the docs? https://github.com/caffeinelabs/mops/pull/495/changes#diff-2d8661e9a26cf52e64445b6f3bf88e576d2f20e1974c2fb701bc57db1e77f8e1

Kamirus added 2 commits April 16, 2026 14:16
Users can add migrations directly to the chain directory without
needing a separate next-migration staging workflow. The `next` field
is now only required when using `mops migrate new/freeze`.

Made-with: Cursor
Previously check-limit/build-limit only trimmed the frozen chain and
the next migration was always appended on top. This meant build-limit=2
with 3 chain + 1 next produced 3 files, but after freezing the same
limit produced 2 files — inconsistent output for the same logical state.

Now chain + next are merged into one list before applying the limit,
so the result is identical regardless of whether the last migration is
pending or already frozen.

Made-with: Cursor
@Kamirus Kamirus merged commit 0569541 into main Apr 16, 2026
25 checks passed
@Kamirus Kamirus deleted the feat/managed-migrations branch April 16, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants