Hi all,

I'd like to propose a small CI check for Liquibase changelog registration
and get your thoughts before I start working on it.
The problem

Every changelog part must be registered with an <include> in a master
changelog (changelog-tenant.xml or a module's module-changelog-master.xml).
If that include is accidentally removed—for example, while resolving a
merge conflict near the end of a master changelog—the part is never
executed.

The problem is that nothing fails during the Liquibase migration itself.
The failure often surfaces later in seemingly unrelated tests, which makes
the root cause difficult to identify.

This happened in one of my PRs (#6124). A merge conflict resolution dropped
the include line, and all database shards subsequently failed with:

Configuration property 'disallow-backdated-transactions' does not exist

There was nothing in the failure output that pointed back to the missing
changelog registration.
What's already in place, and why it doesn't cover this

   -

   *Verify Liquibase Backward Compatibility* checks the changesets that
   actually run. An unregistered part never runs, so there is nothing for it
   to validate.
   -

   *Regression Safety - Database Changes* replays migrations from the base
   branch to the PR and similarly skips an unregistered part.
   -

   *check-liquibase-ddl-safety.sh* inspects DDL in changed files, but does
   not verify whether a changelog file is registered.
   -

   *Liquibase's own validation* only sees files reachable from the master
   changelog, so an orphaned file remains invisible.
   -

   Switching to *includeAll* would remove the manual registration step, but
   it introduces ordering concerns. Our part numbers are not globally unique
   or consistently increasing, so a fresh installation and an upgraded
   database could potentially execute files in different orders. Explicit
   includes also carry contexts such as initial_switch.

The proposal

Add a script, following the same approach as
check-liquibase-ddl-safety.sh—*bash
and grep only, with no new dependencies*—and run it on PRs that modify
db/changelog.

The check would:

   -

   *Fail* if a changelog part is not included by any master changelog.
   -

   *Fail* if a changelog part is included more than once.
   -

   *Fail* if an <include> points to a file that does not exist.
   -

   *Warn*, but not fail, if a new part reuses a number already present on
   develop.

The script would discover the master changelogs itself and resolve each
include relative to its master. This would cover fineract-provider (tenant
and tenant-store) as well as all modules, including the different folder
layout used by fineract-savings.

On develop today, there are *429 parts across 9 changelog trees*, and every
part is included exactly once. The check would therefore pass against the
existing codebase without requiring a list of exceptions.

For example:

ERROR  fineract-provider/tenant: parts/0255_add_example_column.xml is
not included by any master changelog
WARN   fineract-provider/tenant: parts/0254_add_example_config.xml
reuses 0254, which develop already uses

A note on numbering

At the time of writing, there are *19 open PRs adding a changelog part*.

   -

   10 use a number that develop already has, which the proposed warning
   would flag.
   -

   Another 6 share an unused number with a different open PR. For example,
   five PRs currently want 0255. A check against develop alone would not
   detect those conflicts.

Questions

I'd appreciate your thoughts on a few points:

   1.

   Would this check be useful to you?
   2.

   For reused changelog numbers, should the check *warn, fail, or ignore*
   them? develop already contains duplicate numbers such as 0242 and 0243,
   and they work correctly, so the main cost of enforcing uniqueness would be
   the need to renumber during rebases.
   3.

   Should this be implemented as a *separate workflow*, or as a step in one
   of the existing Liquibase workflows?

Once there's some rough agreement, I'll open a JIRA ticket and follow it up
with a PR.

Thanks,
Abhishek Chaudhary

Reply via email to