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?
answer
- axis = who owns version + tag
- release-plugin = Maven commits/tags
- CI-friendly = pipeline stamps -Drevision
- flatten mandatory for published POM
- non-negotiables: no SNAPSHOT deps, immutable release repo, tag↔artifact
basics
~20 sIt 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 sI 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# 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 --tagsgo deeper
Can name the two approaches.
Explains the mechanics of each and when one is simpler.
Weighs ownership, branching model, and automation maturity to recommend one with trade-offs.
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