skip to content

Your team is moving releases into CI/CD. Would you keep maven-release-plugin or adopt CI-friendly versions with flatten + versions plugin? How do you decide?

level: principalimportance: nice to knowfreq 25%

answer

  1. axis = who owns version + tag
  2. release-plugin = Maven commits/tags
  3. CI-friendly = pipeline stamps -Drevision
  4. flatten mandatory for published POM
  5. non-negotiables: no SNAPSHOT deps, immutable release repo, tag↔artifact

basics

~20 s

It depends on who owns versioning and tagging. maven-release-plugin is SCM-driven and makes commits/tags itself; CI-friendly versions let the pipeline stamp the version (-Drevision) with flatten resolving the POM and the pipeline owning the git tag. For modern GitOps CI, the CI-friendly approach is usually cleaner.

solid answer

~50 s

I frame it around ownership and reproducibility. The `maven-release-plugin` bakes the release ceremony into Maven: it makes two SCM commits, creates the tag, and deploys from a clean checkout — self-contained but chatty, with mutated POMs and a stateful, sometimes fragile prepare/perform/rollback flow. CI-friendly versions invert control: the **pipeline** owns the version (from git describe / build number via `-Drevision`) and the tag, Maven just builds, and `flatten-maven-plugin` ensures the published POM is fully resolved. This avoids in-build commits, plays well with immutable pipelines and trunk-based development, and makes the version a pure function of the build context. I'd choose CI-friendly + flatten + versions-plugin for new CI-native setups; I'd keep the release plugin where the team already relies on its SCM ceremony or needs its interactive resumability. Either way I enforce: no SNAPSHOT deps in releases, immutable release repos, and a tag-to-artifact correspondence.

code

bash · 4 lines
bash
# CI-friendly release: pipeline owns version + tag
VER=$(git describe --tags --abbrev=0 | sed 's/^v//')
mvn -B -Drevision="$VER" -Dchangelist= deploy
# pipeline then: git tag v$VER && git push --tags

go deeper

for a junior

Can name the two approaches.

for a middle

Explains the mechanics of each and when one is simpler.

for a senior

Weighs ownership, branching model, and automation maturity to recommend one with trade-offs.

for a principal

Sets org-wide release-engineering policy: versioning source of truth, tag governance, immutability/reproducibility guarantees, and migration path.

## The real decision axis: who owns versioning and tagging? - **maven-release-plugin**: Maven owns it. The build itself commits version changes, tags SCM, and deploys from a fresh tag checkout. - **CI-friendly versions + flatten**: the CI pipeline owns it. The version is injected (`-Drevision=...`), Maven builds and deploys, and the pipeline creates the git tag. ## maven-release-plugin — strengths/weaknesses Strengths: - Self-contained ceremony; guarantees tag-to-artifact correspondence via clean checkout. - Resumable via `release.properties`; interactive prompts for ad-hoc releases. Weaknesses: - Makes commits during the build (POM churn), which fights immutable-pipeline / trunk-based norms. - Stateful prepare/perform/rollback can be fragile in automation; needs SCM write creds inside the build. - Mutates POMs on disk. ## CI-friendly versions + flatten + versions-plugin — strengths/weaknesses Strengths: - Version is a function of build context (git describe, build number) — `mvn -Drevision=1.2.3 -Dchangelist= deploy`. - No in-build SCM commits; the pipeline tags. Clean for GitOps/trunk-based. - `versions:set` available for explicit bumps; `flatten` keeps published POMs correct. Weaknesses: - Requires the flatten plugin or the published POM is broken. - Tag/version discipline now lives in pipeline scripts you must maintain. ## How I decide (checklist) 1. Branching model: trunk-based / immutable pipelines favor CI-friendly. 2. Existing investment: if release-plugin works and the team knows it, don't churn. 3. Automation maturity: scripted, non-interactive CI favors CI-friendly; ad-hoc human releases tolerate the release plugin. 4. Multi-module size: CI-friendly's single-property version shines in large reactors. 5. Tooling: consider `jreleaser`/`maven-deploy` for publishing; Renovate/Dependabot vs versions-plugin for upgrades. ## Non-negotiables regardless of choice - No `-SNAPSHOT` dependencies in a release build. - Release repository is immutable (no overwrite). - A published artifact maps to exactly one git tag/commit (auditability). - Reproducible builds where feasible. ## Example CI-friendly release step ```bash VER=$(git describe --tags --abbrev=0 | sed 's/^v//') mvn -B -Drevision=$VER -Dchangelist= deploy # then the pipeline pushes the git tag, not Maven ```

  • What governance rules apply regardless of which approach you pick?
    No SNAPSHOT dependencies in releases, immutable release repositories, one-to-one tag-to-artifact mapping for auditability, and reproducible builds where feasible.
  • Why can the release plugin's in-build commits be a problem in modern CI?
    They mutate the repo during the build and require SCM write credentials inside the build, which conflicts with immutable pipelines and trunk-based development where the pipeline (not Maven) should own commits/tags.

saying these in an interview costs you the question

  • Declaring one approach universally correct without context
  • Ignoring the tag-to-artifact / reproducibility guarantees
  • Forgetting flatten is mandatory with CI-friendly versions
  • Recommending churning a working release-plugin setup with no payoff

context