In a large monorepo, a single change to one module shouldn’t force a full rebuild of the entire project. For the Lime Mojito OSS Development Standard Build, we use the gitflow-incremental-builder (GIB) Maven plugin to keep CI cycles fast, efficient, and reliable.
The GitHub gitflow-incremental-builder plugin compares your feature branch to a base branch using git to determine which maven modules require a build. The plugin also marks dependent modules so they will be rebuilt as well.
How it works in the pom.xml
The project enables incremental builds by configuring the gitflow-incremental-builder as a Maven extension. This is managed in the root pom.xml in three key areas:
- Plugin Management: The plugin is defined in the
<pluginManagement>section (version4.6.0), ensuring version consistency across the monorepo. - The CI Profile: A specific
ciprofile is used to activate the plugin. By setting<extensions>true</extensions>, the plugin hooks into the Maven lifecycle to intercept the build process and calculate which modules actually need to run based on Git history. - IDE Compatibility: A clever profile named
disable-gib-in-intellijis automatically activated when theidea.versionproperty is present. This disables GIB (gib.disable=true) when working inside IntelliJ IDEA, preventing it from interfering with the IDE’s internal incremental compilation and ensuring a smooth developer experience.
Integration with GitHub Actions
The oss-feature-build.yml workflow implements a sophisticated two-step strategy to leverage incremental builds in CI:
- Step 1: The Primer (Fast Build)
The workflow first runs a “Fast Build” (-Pfast-build -Dgib.disable install). This step explicitly disables GIB and skips heavy tasks like tests and Checkstyle. Its purpose is to “prime” the local Maven repository by installing all modules, ensuring that artifacts for unchanged modules are available as dependencies for the next step. - Step 2: Targeted Validation (Incremental Build)
The core CI build runsclean installbut uses GIB to limit execution. It dynamically detects the default branch (e.g.,masterormain) and passes it via-Dgib.referenceBranch. GIB then analyzes the Git diff between the feature branch and the reference branch, selecting only the changed modules—and any downstream modules that depend on them—for testing and building.
Why Incremental Builds for Monorepos?
- Reduced Feedback Loops: Developers receive PR feedback in minutes rather than hours, as unrelated modules are skipped entirely.
- Resource Efficiency: By avoiding redundant work, the project significantly reduces the consumption of GitHub Actions runner minutes, lowering CI costs.
- Automated Dependency Tracking: GIB ensures safety by automatically identifying and building downstream dependents of changed modules, catching potential integration breaks that a simple “changed-files-only” approach would miss.
- Scalability: As the monorepo grows from 10 modules to 100, the build time for a single-module change remains constant rather than scaling linearly.

