Skip to content

Releases: fsmutimeer/migrax

Migrax 0.17.2-rc.1

Migrax 0.17.2-rc.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 27 Oct 07:50

Release candidate for 0.17.2, for testing: Java migration numbering, the order of column drops,
verify in the server's version and the Quarkus startup metrics. It is not on Maven Central: use
the CLI from the Download page or the container image ghcr.io/fsmutimeer/migrax:0.17.2-rc.1.

Changed

  • verify starts its throwaway PostgreSQL, MySQL or MariaDB container in the version of your
    database server when Migrax can reach it, as reading a schema file already did, so the
    migrations are proven on the version they will run on. Before, it always used its default
    image (postgres:16-alpine for PostgreSQL). --image still picks another one.
  • generate and diff now drop columns after adding and changing the table's other columns.
    MySQL, MariaDB, Oracle and H2 commit each schema change at once, so when a later statement
    of a migration failed, for example making a new column NOT NULL while it still has empty
    rows, the old column and its data were already gone. Now the migration stops while they are
    still there. The order of the summary lines changes the same way, and so can the name of
    the generated file.

Fixed

  • generate gave its file the number of a Java migration written with migrax new --java
    when that number was the highest one, because it counted only SQL files. Both migrations
    then ran in an order nobody chose (the SQL file first). Java migrations now count, and
    generate, check and doctor report a SQL file and a Java migration that share a number,
    with how to fix it: rename the one that is not applied yet. A project that already has such
    a pair fails check (exit code 1) until then, unless both are applied in its database.
  • migrax new --java refuses a --java-package or migrax.java-package that is not a Java
    package name. A value such as /tmp/x or ..x made it write the class outside the project.
    With a comma list of packages, the class goes into the first one.
  • Quarkus: the migrax.migrations.applied and migrax.migrations.failed counters and the
    migrax.run timer of the migrations at startup could stay at 0 in the application's
    registries (Prometheus, OTLP, ...), depending on the order in which Quarkus ran its startup
    steps. They now always count the startup run.

Migrax 0.17.1

Choose a tag to compare

@github-actions github-actions released this 25 Oct 10:08

Added

  • Every GitHub release lists the libraries it contains in migrax-<version>-sbom.cdx.json
    (CycloneDX), and each of its files has a signed record of the workflow run that built it:
    gh attestation verify <file> -R fsmutimeer/migrax checks it. The container image carries
    its own software list and build record in the registry. See Download > Check your
    download.

Fixed

  • Renaming a table no longer needs --allow-destructive. Hibernate's foreign key names
    contain the table name, so generate --rename-table (or answering "yes" to "Did you
    rename table ...?") dropped the old key and added it again under its new name, and the drop
    was counted as a destructive change. A foreign key that comes back unchanged under a new
    name in the same migration is no longer destructive; one that is really removed or changed
    still is. It is listed as "rename foreign key ..." ("kind": "rename_foreign_key" in
    plan --json and diff --json). On PostgreSQL, CockroachDB, YugabyteDB and H2 the
    migration renames the key (RENAME CONSTRAINT); other databases drop it and add it again,
    which checks every row.
  • SQLite: the rollback of a table rename lost the other changes to that table (a renamed
    foreign key, a changed column). SQLite makes them by rebuilding the table, and the rollback
    looked the table up under the name it gives back only afterwards, so the rebuild was left
    out without a word. It is now rebuilt under that name, and a table that can't be found stops
    migrax generate with an error instead.
  • Oracle: making a NUMBER column smaller (fewer decimals or fewer digits before the point,
    bigint to integer included) failed with ORA-01440 once the table had rows, in a
    migration or in the rollback of one that made it larger. Oracle allows that only on an
    empty column, so the change now goes through a new column: first a check that every value
    fits unchanged (a value with too many digits or decimals stops the migration with a message
    saying how many, before the column is changed, and so does an index, constraint or column
    grant made by hand that dropping the column would remove), then the new column is added, a
    trigger keeps it up to date while the application goes on writing, the values are copied
    and checked once more, the old column is dropped (writes fail for a moment there) and the
    new one gets its name, default, NOT NULL and comment. The table is rewritten and the column
    moves to its end; the migration account needs CREATE TRIGGER. Columns in a key, index,
    unique constraint or check, and identity columns, keep the plain change, which Oracle
    still refuses once they have values (see Reference > Limitations).

Security

  • Container image: newer JDBC drivers without known vulnerabilities. PostgreSQL 42.7.5 to
    42.7.14 (could fall back to weaker authentication despite channelBinding=require, and a
    server could make it spend CPU on SCRAM), MariaDB 3.5.1 to 3.5.11 (could send the password
    in clear text to a server in the middle), SQL Server 12.8.1 to 13.6.1 (did not check some
    input from the server well enough). URLs with encrypt and trustServerCertificate work
    as before (tested on SQL Server 2022). The CLI download bundles no drivers and is not affected.
  • Container image: the base images are pinned to exact versions, so every build of a release
    ships the same thing, and /usr/bin/pebble, a program of the base image that Migrax never
    runs and that scanners report, is removed.
  • The published POMs no longer name library versions with known vulnerabilities
    (Micrometer, OpenTelemetry, Spring Boot). Migrax never bundled them: your application keeps
    its own versions, and the framework versions Migrax works with are unchanged.
  • The GitHub Action (uses: fsmutimeer/migrax@...) runs the actions it uses at exact
    commits instead of version tags, so a moved or compromised tag can't change what runs in
    your workflow.

Migrax 0.17.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 16:45

Added

  • Spring Data JDBC: projects without JPA that use Spring Data JDBC (3.0 to 4.1, Spring Boot 3.0
    to 4.1) get generate, check, verify, drift and the startup migration like JPA
    projects. Migrax reads Spring Data JDBC's own mapping, without a database: aggregate roots
    are the classes with @Table and the types of repositories, and their child tables get the
    back-reference and key columns Spring Data JDBC names (@MappedCollection), with a foreign
    key to the parent. Found by itself when the project has no JPA entities, or chosen with
    --extractor spring-data-jdbc. Names written in @Table or @Column keep their letter case
    where an unquoted name would get another one (lower case on H2, Oracle, HSQLDB and Derby,
    capitals on PostgreSQL), as Spring Data JDBC sends them quoted. See Reference >
    Entity readers.
  • Micronaut Data JDBC and R2DBC: projects with @MappedEntity entities (Micronaut Data 4 and
    5) get generate, check, verify and drift like JPA projects. Migrax reads the mapping
    Micronaut's annotation processor compiled, without a database, and follows Micronaut Data's
    rules for names, join tables, embedded values and generated ids (identity, sequences, UUIDs).
    Found by itself when the project has no JPA entities, or chosen with
    --extractor micronaut-data. Micronaut 5 projects need Migrax running on Java 25; Migrax
    names the Java a project needs when it can't load its classes. See Reference > Entity
    readers.
  • migrax environments: every environment's migrations side by side, read-only. For each
    migrax.environments.<name>.url (dev, staging, production, ...) it shows how many migrations
    are applied and pending, the last one applied and whether the schema drifted from the
    snapshot; -- migrax:env migrations count only where they run. All databases are asked at
    once with --timeout, so one that doesn't answer only marks its own row. Exit code 1 when an
    environment can't be reached or a migration failed, changed or is missing there, 2 on drift;
    --json for dashboards. Error MXE116 when none is configured. See Guides > Comparing
    databases.
  • Migrations from a SQL file instead of entities: with migrax.schema-file=db/schema.sql
    (--schema-file, MIGRAX_SCHEMA_FILE, or migrax.databases.<name>.schema-file), a project
    without JPA entities keeps its tables as they should be in one SQL file, and generate
    writes the migration and its rollback script from the changes, with rename questions, lint
    and --zero-downtime as for entities. plan, check, verify and doctor read the file
    too. Migrax reads it by applying it to a throwaway database (in memory, Docker, or an empty
    one given with --scratch-url) and keeps what it read in .migrax/schema-model.json, so
    check in CI needs no Docker while the file is unchanged. A statement that fails is named
    with its line (error MXE115). On PostgreSQL, MySQL and MariaDB the throwaway database runs
    the server's own version, so a file written by pg_dump --schema-only or
    mysqldump --no-data applies as it is. See Guides > SQL migrations for any language and
    Guides > Schema file from your ORM (SQLAlchemy, Drizzle, and any ORM through a dump).

Fixed

  • migrax clean drops tables and sequences whose names keep their letter case: names with
    capitals on PostgreSQL, or lower-case names created in quotes on H2 and Oracle. Before, it
    stopped with "table does not exist".
  • The Spring Boot starter now works on Spring Boot 4. Spring Boot 4 moved the classes the
    starter was ordered against, so it didn't run at all: no migrations at startup, and a JPA
    application with ddl-auto=validate failed with a missing table. The migrax health
    component works with Spring Boot 4's Actuator too.
  • migrax-micronaut now works on Micronaut 4.0 to 4.9. Before, those versions skipped it
    without an error: no migrations at startup, and the application failed on a missing table.
    Micronaut 4.10 and 5 work as before.

Migrax 0.16.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 14:28

Added

  • Drift at startup: migrax.drift.check=warn or fail makes the application compare the
    database with the schema its migrations produce when it starts, in the Spring Boot, Quarkus,
    Micronaut, Helidon and Jakarta EE integrations (migrax.databases.<name>.drift.check per
    database). warn logs every difference, fail stops the start; the default is off. The
    build puts .migrax/snapshot.json into the application: the Quarkus extension (also native)
    and the Gradle plugin do it by themselves, Maven with the new goal migrax:package-snapshot.
    See Guides > Production safety > Drift at startup.

Changed

  • history and pending can't be names of further databases (migrax.databases.<name>): the
    migrax command keeps the default database's files in .migrax/history/ and
    .migrax/pending/, next to each further database's .migrax/<name>/.
  • migrax-integrations and migrax-quarkus-parent are no longer published to Maven Central:
    they only group modules for the build, and no published artifact refers to them.

Migrax 0.15.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 08:28

Added

  • Several databases per application: a block migrax.databases.<name>.* (data source,
    folders, Java package, schemas, placeholders) migrates a further database at startup, in the
    Spring Boot, Quarkus (also native), Micronaut, Helidon and Jakarta EE integrations. Health
    checks report every database. See Guides > Several databases.
  • --database <name> on every command that works on a project (and -Dmigrax.database for
    the Maven goals, MIGRAX_DATABASE): the command works on that database, with its own
    connection, folders, entity package (migrax.databases.<name>.package) and snapshot in
    .migrax/<name>/. The default database no longer reads the entities of another database's
    package.

Changed

  • Every metric has the tag database (default, or the name of a further database), and
    spans the attribute migrax.database. Queries without the tag keep working.
  • A migration folder without a prefix (migrax.locations=db/sql, --locations db/sql) is now
    a classpath folder (under src/main/resources) for the migrax command and the Maven and
    Gradle goals too, the same as when the application migrates at startup. Before, the command
    looked for it in the project folder. Write filesystem:db/sql for a folder outside the
    resources; absolute paths are unchanged.

Migrax 0.14.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 11:38

Added

  • migrax.migrate-at-startup=false in the Spring Boot, Quarkus, Micronaut, Helidon and Jakarta
    EE integrations: the application starts without migrating, for teams whose pipeline or DBA
    runs the migrations, and logs what is pending; the health check keeps reporting.
  • Gauge migrax.migrations.pending (migrax_migrations_pending): how many migrations wait to
    run, in the same integrations when the application has Micrometer. Off with
    migrax.metrics.enabled=false. See Guides > Metrics and tracing.
  • migrax diff <source-url>: compares the schema of another database of the same kind (for
    example staging) with the project's database and lists the changes that would make it match;
    --sql prints them as a script, --json for tools, exit code 2 when they differ. Also
    mvn migrax:diff. See Guides > Comparing databases.
  • GitLab CI and Bitbucket Pipelines templates: check, lint of new or changed migrations, the
    HTML report as an artifact, and a comment on the merge or pull request (updated on each
    pipeline). See Guides > Continuous integration.
  • Published on Maven Central: the library and Maven plugin org.migrax:migrax, the framework
    integrations, migrax-junit and the Gradle plugin org.migrax, with sources, javadoc and
    signatures. Builds no longer need to install Migrax from the source first.

Changed

  • Migrax is now licensed under the Apache License 2.0 (with a NOTICE file). Releases up to
    0.13.0 keep the MIT License they were published with.

Fixed

  • generate no longer drops and re-adds a check constraint whose condition differs only in
    spacing or in parentheses around the whole condition (databases store conditions their own
    way, for example Derby).
  • Check conditions read from MySQL keep valid SQL quotes (MySQL reports '' as \'\'), and
    MySQL, MariaDB and TiDB primary keys are no longer named PRIMARY when Migrax writes them
    back.

Migrax 0.13.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 15:24

Added

  • Metrics and tracing of migrations at startup: Micrometer metrics (migrax.run,
    migrax.migration, migrax.migrations.applied/failed, migrax.lock.wait) and
    OpenTelemetry spans (migrax migrate with a migrax migration span each), recorded by the
    Spring Boot, Quarkus, Micronaut, Helidon and Jakarta EE integrations when the application has
    a MeterRegistry or an OpenTelemetry. Turn them off with migrax.metrics.enabled=false or
    migrax.tracing.enabled=false. MigrationListener beans hear every run too, and the Java API
    takes listeners with listener(...). See Guides > Metrics and tracing.
  • Preconditions: a -- migrax:require line makes a migration check the database before it
    runs (table-exists, table-missing, column-exists, column-missing, or sql <query>).
    An unmet condition stops the run (MXE114), or with else skip records the migration without
    running it. status and migrate --dry-run show the conditions of pending migrations;
    migrate --sql checks them for the first migration and stops before later ones.

Migrax 0.12.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 13:31

Four more databases: YugabyteDB, TiDB, HSQLDB and Apache Derby.

Added

  • YugabyteDB (2024.2 and newer), the 9th database: dialect yugabytedb, reached with the
    PostgreSQL driver (recognized from the server) or YugabyteDB's own driver. It writes
    PostgreSQL's SQL; the migration lock is PostgreSQL's advisory lock from 2025.1 on and a row
    in migrax_lock before. verify starts a throwaway YugabyteDB container, and
    --zero-downtime works as on PostgreSQL.
  • TiDB (7.5 and newer), the 10th database: dialect tidb, reached with the MySQL driver and
    recognized from the server. It writes MySQL's SQL; check constraints need
    tidb_enable_check_constraint (migrax doctor warns when it is off), --keep-data backs up
    with CREATE TABLE ... LIKE, and --zero-downtime can't split renames (no triggers or
    writable views). verify starts a throwaway TiDB container.
  • HSQLDB (HyperSQL 2.7 and newer), the 11th database: dialect hsqldb, recognized from
    jdbc:hsqldb: URLs. The migration lock is a row in migrax_lock, so it also holds across
    processes for file and server databases; verify replays the migrations in memory.
  • Apache Derby (10.16 and newer), the 12th database: dialect derby, recognized from
    jdbc:derby: URLs. Type changes Derby can't make in place rebuild the column, comments are
    left out (Derby keeps none), and verify replays the migrations in memory.

Migrax 0.11.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 08:49

Zero-downtime changes and an HTML report.

Added

  • generate --zero-downtime splits a change so the old and the new application version can
    use the database at the same time: an expand migration for this release (new columns still
    nullable, a renamed column copied and kept equal to the old one by a trigger, a renamed
    table's old name kept as a view, wider types) and a contract migration for the next release
    (drops, NOT NULL, narrower types, new constraints). The contract migration waits in
    .migrax/pending/ until generate --contract adds it to the migration folder. Column
    renames need PostgreSQL, MySQL, MariaDB or Oracle; table renames also work on SQL Server.
    See Guides > Zero-downtime changes.
  • migrax report (and mvn migrax:report) writes one HTML page for reviews and CI
    artifacts: the schema with a diagram, entity changes without a migration, every migration
    with its status and lint findings, and drift. The GitHub Action uploads it as the artifact
    migrax-report and links it from its pull request comment (report: false turns it off).

Changed

  • Lint rules MX007 (drops) and MX008 (renames) name generate --zero-downtime as the fix.

Migrax 0.10.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 07:08

A Java API, and a JUnit 5 extension that checks migrations against the entities.

Added

  • A Java API, org.migrax.api.Migrax: Migrax.configure().dataSource(ds).load(), then
    migrate(), status(), rollback(steps), rollbackTo(version), validate() (do the
    entities match the database?) and testRollbacks(). The startup integrations run on it.
  • migrax-junit, a JUnit 5 extension: @MigraxTest migrates a test database (H2, a
    DataSource or a Testcontainers container) before the tests and fails them when the
    entities don't match the migrated schema. With rollbacks = true it also tests every
    rollback script. See Guides > Java API and JUnit tests.