Contributing to Migrax¶
Thank you for helping. This guide covers building, testing and the rules for branches, commits and releases.
Build and test¶
Requirements: Java 17 or newer, Maven 3.9, and Docker for the real-database suite.
mvn install # core library, CLI and Maven plugin; unit tests and SpotBugs
mvn install -f integrations/pom.xml # Spring Boot, Quarkus, Micronaut, Helidon and Gradle integrations
Install the CLI you just built:
Test suites¶
| Suite | Command | Covers |
|---|---|---|
| Unit and H2 tests | mvn verify |
CLI, diff engine, readers, runner, Hibernate validation on H2 |
| Integrations | mvn install -f integrations/pom.xml |
Startup integrations in real Spring Boot, Quarkus, Micronaut and Helidon applications |
| Real databases | mvn verify -Pdatabase-integration |
MySQL, MariaDB, PostgreSQL, SQL Server and Oracle in Docker |
| Hibernate versions | bash compat/hibernate/run.sh [version ...] |
Generate, migrate and verify with every Hibernate minor version from 5.4 to 7.4 |
CI runs all of them on every pull request.
Writing tests¶
- Changes to how entities are read must keep the annotation scanner and Hibernate's mapping in
agreement (
HibernateValidationTest) and pass the Hibernate version matrix. - Changes to the CLI need a test in
src/test/java/org/migrax/cli. - A bug fix comes with a test that fails without the fix.
How the code is organized¶
Everything lives under src/main/java/org/migrax:
| Package | Contents |
|---|---|
cli |
The migrax command: Main, one *Command class per command, and shared helpers |
model |
Reading entities into a SchemaModel (Hibernate's mapping or annotation scanning) |
orm |
The parts that run against the project's own Hibernate version |
diff |
Comparing two models into operations, rename detection, snapshots |
ops |
The operations a migration consists of (CreateTable, AddColumn, ...) |
dialect |
Rendering operations as SQL for each database |
runner |
Applying, rolling back and tracking migrations; startup integration support |
lint, verify |
SQL linting; throwaway databases and schema comparison |
plugin |
Maven goals (mvn migrax:<command>), which run the CLI commands |
Adding a command¶
- Create
src/main/java/org/migrax/cli/<Name>Command.javaimplementingCommand. Copy a small one such asSqlCommandas a starting point. The interface asks for the name, help texts, the options the command accepts, andrun(CommandContext). - Add it to
CommandRegistry.standard().migrax help,migrax help <name>, aliases and "did you mean" suggestions then work without other changes. - A new option goes into
Options: theVALUESorFLAGSset, plus its help line. - Optionally add a Maven goal: a
*MojoinpluginextendingAbstractMigraxMojo.
In run, take everything from the context instead of creating it: context.project(),
context.args(), context.out(), context.migrationRunner(). Report mistakes the user can fix
by throwing UsageException with a hint; Migrax prints them without a stack trace. Return an
ExitCode.
Shared helpers: EntityChanges (entity changes since the snapshot), MigrationSql (writing
migration and rollback files), MigrationFiles, DuplicateMigrations, Reports (printing
operations and lint findings) and Errors.
CommandRegistryTest checks every registered command's help and options; CommandsTest and
MainTest show how to run a command end to end against an H2 project.
Adding a database¶
- Create a dialect in
org.migrax.dialectextendingAbstractDialect: id(), which is also matched against the JDBC URL prefix (jdbc:<id>:) and the database's product name; overrideacceptsUrloracceptsProductwhen they differ;logicalType()for the column types;acquireMigrationLock(), the database lock that keeps two Migrax processes from migrating at once. It must fail at once instead of waiting. Without it, Migrax refuses to migrate;aliases()if the database has other common names.- List the class in
src/main/resources/META-INF/services/org.migrax.dialect.Dialect.--dialect, detection from the JDBC URL, locking,migrax doctorand the help texts pick it up from there. - Add it to the real-database suite (
DatabaseEngineIT) and toDialectTest.
Branches¶
Work on a short-lived branch and open a pull request into main:
| Branch | Use |
|---|---|
feature/<name> |
New functionality |
fix/<name> or fix/<issue>-<name> |
Bug fixes |
docs/<name>, refactor/<name>, test/<name>, ci/<name>, chore/<name> |
Other changes |
release/X.Y.Z |
Release preparation (maintainers) |
hotfix/X.Y.Z |
Urgent fix for a released version (maintainers) |
main is protected: changes arrive by pull request with green CI.
Commit messages¶
Conventional Commits: type(scope): summary, for example
fix(hibernate): read identity columns on Hibernate 6.3. Types: feat, fix, docs,
refactor, perf, test, build, ci, chore. Mark breaking changes with ! and a
BREAKING CHANGE: footer.
Add a line to the Unreleased section of CHANGELOG.md for every user-visible change.
Documentation¶
The documentation site is built with MkDocs Material from docs/:
pip install -r docs/requirements.txt
python scripts/fetch-releases.py # copies the release files and writes the Download page
mkdocs serve # live preview at http://127.0.0.1:8000
mkdocs build --strict # what CI runs
scripts/fetch-releases.py must run before building: the Download page includes the file it
generates (docs/downloads/, not committed).
The CLI reference (docs/reference/cli.md) mirrors migrax help <command>: update it when you
change a command or option.
Releases¶
Versioning follows Semantic Versioning. See Versioning and releases for the release steps; in short: