Skip to content

Schema migration system for ZIO Schema 2#982

Closed
Godzilla675 wants to merge 14 commits intozio:mainfrom
Godzilla675:schema-migration-for-zio-schema-2-system-v2
Closed

Schema migration system for ZIO Schema 2#982
Godzilla675 wants to merge 14 commits intozio:mainfrom
Godzilla675:schema-migration-for-zio-schema-2-system-v2

Conversation

@Godzilla675
Copy link
Contributor

Summary

  • Implement pure, serializable migration core for ZIO Schema 2 (DynamicMigration + MigrationAction + DynamicSchemaExpr schemas).
  • Add Schema.structural derivation for structural records/variants and structural bindings (Scala 3).
  • Add selector macros + builder syntax for optic-style paths (Scala 2/3).
  • Add build-time validation, DefaultValue resolution, correct transform context, and extended runtime path traversal.

Examples

Structural schema + addField

type PersonV1 = { def name: String }
@schema case class PersonV2(name: String, age: Int)

implicit val v1Schema: Schema[PersonV1] = Schema.structural[PersonV1]

val v1ToV2 =
  MigrationBuilder[PersonV1, PersonV2]
    .addField(_.age, 0)
    .build

Rename + composition

@schema case class PersonV3(fullName: String, age: Int)

val v2ToV3 =
  MigrationBuilder[PersonV2, PersonV3]
    .renameField(_.name, _.fullName)
    .buildPartial

val v1ToV3 = v1ToV2 ++ v2ToV3

Selector grammar (paths)

MigrationBuilder[Old, New]
.dropField(.address.street)
.optionalizeField(
.email)
.buildPartial

Notable behavior

  • build() validates structural changes (including optionality) by simulating actions.
  • DefaultValue resolves at build time (forward strict; reverse best-effort).
  • Typed Migration.apply returns a MigrationError for structural-only schemas; use applyDynamic.

Tests

  • sbt -no-colors schemaJVM/test schemaJS/test

Demo / Video

migration-demo.mp4

Notes / limitations

  • Scala 2 cannot derive Schema.structural for true structural/union types.
  • Typed apply for structural schemas is intentionally unsupported (use applyDynamic).

Review guide

  • Serialization schemas: schema/shared/src/main/scala/zio/blocks/schema/migration/MigrationSchemas.scala
  • Structural derivation: schema/shared/src/main/scala-3/zio/blocks/schema/SchemaCompanionVersionSpecific.scala (+ bindings)
  • Selector macros + syntax: schema/shared/src/main/scala-2|3/zio/blocks/schema/migration/*
  • Validation: schema/shared/src/main/scala/zio/blocks/schema/migration/MigrationValidator.scala
  • Tests: schema/shared/src/test/scala/zio/blocks/schema/migration/*

Issues

Ahmed and others added 14 commits February 4, 2026 18:23
…calls

- Replace typeName with typeId in structural derivation macros
- Use TypeId.nominal for structural types
- Fix DynamicValue.Record to use varargs or Chunk instead of Vector
- Fix MigrationValidator to use typeId.name instead of typeName.name
- Fix scalafmt issues in Scala 2 and Scala 3 migration files
- Fix Scaladoc @throws annotation to use fully qualified name
- Add MigrationValidatorSpec with 44 comprehensive tests
- Add 25+ error path tests to DynamicMigrationSpec
- Total migration tests increased from ~94 to ~166
- Add error aggregation tests for AtIndices, AtMapKeys, Elements, MapKeys, MapValues
- Add DynamicSchemaExpr tests: StringConcat, StringLength, CoercePrimitive, Arithmetic ops
- Add Logical/Relational operator tests
- Add navigateDynamicValue coverage tests
- Add Wrapped, AtMapKey, Case path navigation edge case tests
- Add MigrationValidator path navigation tests for all optic types
- Increase branch coverage to meet 80% minimum requirement
Copilot AI review requested due to automatic review settings February 5, 2026 13:07
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ Godzilla675
❌ Ahmed


Ahmed seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a pure, algebraic schema migration system for ZIO Schema 2. The system enables type-safe schema evolution through serializable migrations that operate on DynamicValue, with compile-time validation and automatic reversibility. The implementation includes structural schema derivation for Scala 3, selector macros for ergonomic path expressions, and comprehensive build-time validation.

Changes:

  • Core migration types: Migration[A,B], DynamicMigration, MigrationAction ADT, DynamicSchemaExpr, and MigrationError
  • Migration builder with fluent API and build-time validation via MigrationValidator
  • Selector macros (Scala 2 & 3) for type-safe path expressions with optic-like syntax
  • Structural schema derivation for Scala 3 (refinement types and union types)
  • Comprehensive test suite with 1600+ tests covering all operations

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated no comments.

Show a summary per file
File Description
MigrationAction.scala ADT for migration actions with 14+ action types and reversibility
DynamicMigration.scala Untyped, serializable migration with path-based value transformation (744 lines)
Migration.scala Typed migration wrapper providing type-safe API and composition
MigrationError.scala Comprehensive error types with path information
DynamicSchemaExpr.scala Serializable expressions for value transformations (594 lines)
MigrationBuilder.scala Fluent builder API with default value resolution (631 lines)
MigrationValidator.scala Build-time structural validation (693 lines)
SelectorMacros.scala Scala 2 & 3 macros for type-safe selector expressions
MigrationBuilderSyntax.scala Extension methods for ergonomic selector syntax
SchemaCompanionVersionSpecific.scala Structural schema derivation for Scala 3 (196 new lines)
Selector.scala Type-safe selector abstraction
package.scala Package documentation
Structural bindings Runtime support for structural types (Constructor, Deconstructor, Matcher)
Test files 10+ comprehensive test specs covering all migration operations
JsonBinaryCodecDeriver.scala Bug fix for recursive records (delayed initialization)
Test utilities Newline normalization for cross-platform compatibility
Documentation Migration reference guide with examples and best practices

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jdegoes jdegoes closed this Feb 5, 2026
@Godzilla675
Copy link
Contributor Author

Godzilla675 commented Feb 5, 2026

@jdegoes hi I was still working on the pr but i couldn't run the tests locally due to insufficient memory on my pc thats why i was pushing the changes and seeing if the checks will fail or not. thats why there are so many commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants