Skip to content

Repository files navigation

semantic-version-maven-plugin

Latest version Maven Central Version

Push create release Release Build License: MIT Java Version 17

A Maven plugin for automated semantic versioning with Markdown-based changelog management.

Table of Contents

Overview

The Semantic Version Maven Plugin automates version management using semantic versioning principles (MAJOR.MINOR.PATCH). It integrates changelog management through Markdown files, enabling you to:

  • Create version bump specifications with Markdown changelog entries
  • Automatically update POM file versions based on semantic versioning rules
  • Maintain synchronized changelog files across single and multi-module Maven projects
  • Support multiple versioning strategies for different project structures

Requirements

  • Java: 17 or higher
  • Maven: 3.9.12 or higher

Installation

Add the plugin to your pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>io.github.bsels</groupId>
            <artifactId>semantic-version-maven-plugin</artifactId>
            <version>1.5.0</version>
        </plugin>
    </plugins>
</build>

Goals

  • create: Creates a version Markdown file for specifying version bumps.
  • update: Updates POM file versions and CHANGELOG.md files based on version Markdown files.
  • verify: Verifies that version Markdown files are consistent with the project scope.
  • graph: Generates a JSON representation of the project dependency graph.

create

Full name: io.github.bsels:semantic-version-maven-plugin:create

Description: Creates a version Markdown file that specifies which projects should receive which type of semantic version bump (PATCH, MINOR, or MAJOR). The goal provides an interactive interface to select projects and their version bump types, and allows you to write changelog entries either inline or via an external editor.

Phase: Not bound to any lifecycle phase (standalone goal)

Configuration Properties

Property Type Default Description
versioning.modus Modus PROJECT_VERSION Versioning strategy:
PROJECT_VERSION: All projects in multi-module builds
REVISION_PROPERTY: Only current project using the revision property
PROJECT_VERSION_ONLY_LEAFS: Only leaf projects (no modules)
versioning.identifier ArtifactIdentifier GROUP_ID_AND_ARTIFACT_ID Artifact key format in version Markdown files:
GROUP_ID_AND_ARTIFACT_ID: use groupId:artifactId keys (default)
ONLY_ARTIFACT_ID: use artifactId only when all modules share the same groupId
versioning.directory Path .versioning Directory for storing version Markdown files
versioning.dryRun boolean false Preview changes without writing files
versioning.backup boolean false Create backup of files before modification
versioning.commit.message.create String Created version Markdown file for {numberOfProjects} project(s) Commit message template for version Markdown file creation. Use {numberOfProjects} placeholder for project count
versioning.git Git NO_GIT Defines the git operation mode:
NO_GIT: no git operations will be performed
STAGING: stage all changed files (added to the git index)
STASH: added changed files to the git staging (deprecated since 1.5.0: use STAGING)
COMMIT: commit all changed files with the configured commit message

Example Usage

Basic usage (interactive mode):

mvn io.github.bsels:semantic-version-maven-plugin:create

With custom versioning directory:

mvn io.github.bsels:semantic-version-maven-plugin:create \
  -Dversioning.directory=.versions

Dry-run to preview:

mvn io.github.bsels:semantic-version-maven-plugin:create \
  -Dversioning.dryRun=true

Multi-module project (leaf projects only):

mvn io.github.bsels:semantic-version-maven-plugin:create \
  -Dversioning.modus=PROJECT_VERSION_ONLY_LEAFS

update

Full name: io.github.bsels:semantic-version-maven-plugin:update

Description: Updates POM file versions and CHANGELOG.md files based on version Markdown files created by the create goal. The goal reads version bump specifications from Markdown files, applies semantic versioning to project versions, updates dependencies in multi-module projects, and merges changelog entries into CHANGELOG.md files.

Phase: Not bound to any lifecycle phase (standalone goal)

Configuration Properties

Property Type Default Description
versioning.bump VersionBump FILE_BASED Version bump strategy:
FILE_BASED: Use version Markdown files from .versioning directory
MAJOR: Apply MAJOR version bump to all projects
MINOR: Apply MINOR version bump to all projects
PATCH: Apply PATCH version bump to all projects
SUFFIX_ONLY: Only update the version suffix (requires versioning.suffix)
versioning.modus Modus PROJECT_VERSION Versioning strategy:
PROJECT_VERSION: All projects in multi-module builds
REVISION_PROPERTY: Only current project using the revision property
PROJECT_VERSION_ONLY_LEAFS: Only leaf projects (no modules)
versioning.identifier ArtifactIdentifier GROUP_ID_AND_ARTIFACT_ID Artifact key format in version Markdown files:
GROUP_ID_AND_ARTIFACT_ID: use groupId:artifactId keys (default)
ONLY_ARTIFACT_ID: use artifactId only when all modules share the same groupId
versioning.directory Path .versioning Directory containing version Markdown files
versioning.dryRun boolean false Preview changes without writing files
versioning.backup boolean false Create backup of POM and CHANGELOG files before modification
versioning.commit.message.update String Updated {numberOfProjects} project version(s) [skip ci] Commit message template for version updates. Use {numberOfProjects} placeholder for project count
versioning.dependency.bump.message String Project version bumped as result of dependency bumps Changelog entry text used when a project version is bumped because of dependency updates
versioning.update.scripts String - Script paths to execute per updated module, separated by the OS path separator (: on Unix-like systems, ; on Windows). Each script runs in the module directory with CURRENT_VERSION, NEW_VERSION, DRY_RUN (true or false), GIT_STASH (true or false. Deprecated since 1.5.0: use GIT_STAGING), GIT_STAGING (true or false), PROJECT_PATH (absolute path to module directory) and EXECUTION_DATE (yyyy-MM-dd) environment variables. For instance, to automate deprecation version management: -Dversioning.update.scripts=./update-deprecation-version.sh (adjusting the paths to the project root).
versioning.version.header String {version} - {date#yyyy-MM-dd} Header format for version Markdown files. Supports {version} and {date#yyyy-MM-dd} placeholders; date uses a DateTimeFormatter pattern.
versioning.changelog.header String Changelog Header label for the changelog title (H1)
versioning.major.header String Major Header label for major changes in the changelog
versioning.minor.header String Minor Header label for minor changes in the changelog
versioning.patch.header String Patch Header label for patch changes in the changelog
versioning.other.header String Other Header label for non-semantic changes in the changelog
versioning.suffix String - Optional suffix to append to the bumped version (e.g., -BETA, -RC1). If it doesn't start with a dash, one will be automatically added.
versioning.git Git NO_GIT Defines the git operation mode:
NO_GIT: no git operations will be performed
STAGING: stage all changed files (added to the git index)
STASH: added changed files to the git staging (deprecated since 1.5.0: use STAGING)
COMMIT: commit all changed files with the configured commit message

Example Usage

Basic usage (file-based versioning):

mvn io.github.bsels:semantic-version-maven-plugin:update

Force MAJOR version bump (override version files):

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.bump=MAJOR

Force MINOR version bump:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.bump=MINOR

Force PATCH version bump:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.bump=PATCH

Dry-run to preview changes:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.dryRun=true

With backup files:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.backup=true

Custom versioning directory:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.directory=.versions

Custom version file header:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.version.header='Release {version} ({date#yyyy-MM-dd})'

Multi-module project with revision property:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.modus=REVISION_PROPERTY

With version suffix:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.suffix=BETA

verify

Full name: io.github.bsels:semantic-version-maven-plugin:verify

Description: Verifies that version Markdown files are consistent with the project scope. The goal reads version Markdown files, validates that all referenced artifacts exist in scope, enforces the selected verification mode, and optionally requires consistent version bumps across all projects. When versioning.git is not NO_GIT, it runs git status before verification. This goal does not write files; versioning.dryRun and versioning.backup have no effect.

Phase: Not bound to any lifecycle phase (standalone goal)

Configuration Properties

Property Type Default Description
versioning.verification.mode VerificationMode ALL_PROJECTS Verification scope:
NONE: skip verification
AT_LEAST_ONE_PROJECT: require at least one version-marked project
DEPENDENT_PROJECTS: require all dependent projects to be version-marked
ALL_PROJECTS: all projects in scope must be version-marked
versioning.verification.consistent boolean false When true, all version-marked projects must share the same version bump type
versioning.modus Modus PROJECT_VERSION Project scope for verification:
PROJECT_VERSION: all projects in multi-module builds
REVISION_PROPERTY: only current project using the revision property
PROJECT_VERSION_ONLY_LEAFS: only leaf projects (no modules)
versioning.identifier ArtifactIdentifier GROUP_ID_AND_ARTIFACT_ID Artifact key format in version Markdown files:
GROUP_ID_AND_ARTIFACT_ID: use groupId:artifactId keys (default)
ONLY_ARTIFACT_ID: use artifactId only when all modules share the same groupId
versioning.directory Path .versioning Directory containing version Markdown files
versioning.git Git NO_GIT Git mode. Any value other than NO_GIT triggers a git status check before verification. Supported modes:
NO_GIT: no git operations will be performed
STAGING: stage all changed files (added to the git index)
STASH: added changed files to the git staging (deprecated since 1.5.0: use STAGING)
COMMIT: commit all changed files with the configured commit message

Example Usage

Basic verification:

mvn io.github.bsels:semantic-version-maven-plugin:verify

Verify dependent projects and require consistent bumps:

mvn io.github.bsels:semantic-version-maven-plugin:verify \
  -Dversioning.verification.mode=DEPENDENT_PROJECTS \
  -Dversioning.verification.consistent=true

graph

Full name: io.github.bsels:semantic-version-maven-plugin:graph

Description: Generates a JSON representation of the dependency graph for Maven projects within the current execution scope. It identifies internal dependencies between projects and can output the graph either to the console or to a specified file. The output includes transitive dependencies sorted in build order (topological order).

Phase: Not bound to any lifecycle phase (standalone goal)

Configuration Properties

Property Type Default Description
versioning.graphOutput GraphOutput ARTIFACT_AND_FOLDER Specifies the graph output format:
ARTIFACT_ONLY: Only Maven artifact identifiers
FOLDER_ONLY: Only project folder paths
ARTIFACT_AND_FOLDER: Both artifact identifiers and folder paths
versioning.outputFile Path - Path to the output file. If not specified, the graph is printed to the console.
versioning.relativePaths boolean true When true, project folder paths are resolved relative to the execution root; otherwise, absolute paths are used.
versioning.modus Modus PROJECT_VERSION Project scope for the graph:
PROJECT_VERSION: All projects in multi-module builds
REVISION_PROPERTY: Only current project using the revision property
PROJECT_VERSION_ONLY_LEAFS: Only leaf projects (no modules)

Output Format Description

The generated JSON is a map where each key is a project's artifact identifier (groupId:artifactId), and the value is a list of its internal dependencies.

ARTIFACT_ONLY:

{
  "io.github.bsels:parent": [],
  "io.github.bsels:child": [
    "io.github.bsels:parent"
  ]
}

FOLDER_ONLY:

{
  "io.github.bsels:parent": [],
  "io.github.bsels:child": [
    "."
  ]
}

ARTIFACT_AND_FOLDER:

{
  "io.github.bsels:parent": [],
  "io.github.bsels:child": [
    {
      "artifact": {
        "groupId": "io.github.bsels",
        "artifactId": "parent"
      },
      "folder": "."
    }
  ]
}

Example Usage

Basic usage (print to console):

mvn io.github.bsels:semantic-version-maven-plugin:graph

Write to file with absolute paths:

mvn io.github.bsels:semantic-version-maven-plugin:graph \
  -Dversioning.outputFile=graph.json \
  -Dversioning.relativePaths=false

Artifact-only output:

mvn io.github.bsels:semantic-version-maven-plugin:graph \
  -Dversioning.graphOutput=ARTIFACT_ONLY

Configuration Properties

Common Properties

These properties apply to create, update, and verify goals. The verify goal does not use versioning.dryRun or versioning.backup:

Property Type Default Description
versioning.modus Modus PROJECT_VERSION Defines versioning strategy for project structure:
PROJECT_VERSION: Process all projects in topological order
REVISION_PROPERTY: Process only the current project using the revision property
PROJECT_VERSION_ONLY_LEAFS: Process only leaf projects (no child modules)
versioning.identifier ArtifactIdentifier GROUP_ID_AND_ARTIFACT_ID Artifact key format in version Markdown files:
GROUP_ID_AND_ARTIFACT_ID: use groupId:artifactId keys (default)
ONLY_ARTIFACT_ID: use artifactId only when all modules share the same groupId
versioning.directory Path .versioning Directory path for version Markdown files (absolute or relative to project root)
versioning.dryRun boolean false When true, performs all operations without writing files (logs output instead)
versioning.backup boolean false When true, creates .bak backup files before modifying POM and CHANGELOG files
versioning.git Git NO_GIT Defines the git operation mode:
NO_GIT: no git operations will be performed
STAGING: stage all changed files (added to the git index)
STASH: added changed files to the git staging (deprecated since 1.5.0: use STAGING)
COMMIT: commit all changed files with the configured commit message

create-Specific Properties

Property Type Default Description
versioning.commit.message.create String Created version Markdown file for {numberOfProjects} project(s) Commit message template used when creating version Markdown files. The {numberOfProjects} placeholder is replaced with the actual count

update-Specific Properties

Property Type Default Description
versioning.bump VersionBump FILE_BASED Determines version increment strategy:
FILE_BASED: Read version bumps from Markdown files in .versioning directory
MAJOR: Force MAJOR version increment (X.0.0) for all projects
MINOR: Force MINOR version increment (0.X.0) for all projects
PATCH: Force PATCH version increment (0.0.X) for all projects
SUFFIX_ONLY: Only update the version suffix (requires versioning.suffix)
versioning.commit.message.update String Updated {numberOfProjects} project version(s) [skip ci] Commit message template used when updating project versions. The {numberOfProjects} placeholder is replaced with the actual count
versioning.dependency.bump.message String Project version bumped as result of dependency bumps Changelog entry text used when a project version is bumped because of dependency updates
versioning.update.scripts String - Script paths to execute per updated module, separated by the OS path separator (: on Unix-like systems, ; on Windows). Each script runs in the module directory with CURRENT_VERSION, NEW_VERSION, DRY_RUN (true or false), GIT_STASH (true or false. Deprecated since 1.5.0: use GIT_STAGING), GIT_STAGING (true or false), PROJECT_PATH (absolute path to module directory) and EXECUTION_DATE (yyyy-MM-dd) environment variables. For instance, to automate deprecation version management: -Dversioning.update.scripts=./update-deprecation-version.sh (adjusting the paths to the project root).
versioning.version.header String {version} - {date#yyyy-MM-dd} Header format for version Markdown files. Supports {version} and {date#yyyy-MM-dd} placeholders; date uses a DateTimeFormatter pattern.
versioning.changelog.header String Changelog Header label for the changelog title (H1)
versioning.major.header String Major Header label for major changes in the changelog
versioning.minor.header String Minor Header label for minor changes in the changelog
versioning.patch.header String Patch Header label for patch changes in the changelog
versioning.other.header String Other Header label for non-semantic changes in the changelog
versioning.suffix String - Optional suffix to append to the bumped version (e.g., -BETA, -RC1). If it doesn't start with a dash, one will be automatically added.

verify-Specific Properties

Property Type Default Description
versioning.verification.mode VerificationMode ALL_PROJECTS Verification scope:
NONE: skip verification
AT_LEAST_ONE_PROJECT: require at least one version-marked project
DEPENDENT_PROJECTS: require all dependent projects to be version-marked
ALL_PROJECTS: all projects in scope must be version-marked
versioning.verification.consistent boolean false When true, all version-marked projects must share the same version bump type

graph-Specific Properties

Property Type Default Description
versioning.graphOutput GraphOutput ARTIFACT_AND_FOLDER Specifies the graph output format:
ARTIFACT_ONLY: Only artifact identifiers
FOLDER_ONLY: Only folder paths
ARTIFACT_AND_FOLDER: Artifacts and folder paths
versioning.outputFile Path - Path to the output file. If not specified, output is printed to the console.
versioning.relativePaths boolean true When true, project paths are relative to execution root; otherwise, absolute.

Examples

Example 1: Single Project Workflow

  1. Create version specification:

    mvn io.github.bsels:semantic-version-maven-plugin:create
    • Select MINOR version bump
    • Enter changelog: "Added new user authentication feature"
  2. Preview changes:

    mvn io.github.bsels:semantic-version-maven-plugin:update -Dversioning.dryRun=true
  3. Apply version update:

    mvn io.github.bsels:semantic-version-maven-plugin:update

Example 2: Multi-Module Project Workflow

  1. Create version specifications for multiple modules:

    mvn io.github.bsels:semantic-version-maven-plugin:create
    • Select module-api → MAJOR (breaking changes)
    • Select module-core → MINOR (new features)
    • Enter changelog for each module
  2. Update with backups:

    mvn io.github.bsels:semantic-version-maven-plugin:update -Dversioning.backup=true

Example 3: Emergency Patch Release

Skip version file creation and force PATCH bump:

mvn io.github.bsels:semantic-version-maven-plugin:update -Dversioning.bump=PATCH

Example 4: Suffix-Only Release

Update only the version suffix without changing the semantic version:

mvn io.github.bsels:semantic-version-maven-plugin:update \
  -Dversioning.bump=SUFFIX_ONLY \
  -Dversioning.suffix=RC1

Example 5: POM Configuration

Configure the plugin directly in pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>io.github.bsels</groupId>
            <artifactId>semantic-version-maven-plugin</artifactId>
            <version>1.5.0</version>
            <configuration>
                <modus>PROJECT_VERSION</modus>
                <versionDirectory>.versioning</versionDirectory>
                <dryRun>false</dryRun>
                <backupFiles>true</backupFiles>
                <versionBump>FILE_BASED</versionBump>
            </configuration>
        </plugin>
    </plugins>
</build>

GitHub Action Integration

Release Workflow

You can automate your release process by integrating this plugin into a GitHub Action workflow. Below is an example workflow that triggers on a push to the main branch, updates versions based on Markdown files, commits changes, and creates a GitHub release.

name: Push create release
on:
  push:
    branches: [ main ]
permissions:
  contents: write
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Set up Git user
        run: |
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com

      - name: Run versioning
        id: bumpVersion
        run: |
          set -e
          # Run the update goal to apply version bumps and commit changes
          # We also run maintenance scripts to update the README and deprecation versions
          mvn io.github.bsels:semantic-version-maven-plugin:update \
            -Dversioning.git=COMMIT \
            -Dversioning.update.scripts=./update-deprecation-version.sh
          # Capture the new version for subsequent steps
          VERSION=$(./mvnw help:evaluate -Dexpression=project.version -q -DforceStdout)
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Create tag and push
        run: |
          git tag "v${{ steps.bumpVersion.outputs.version }}"
          git push
          git push origin tag "v${{ steps.bumpVersion.outputs.version }}"

      - name: Create release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ format('v{0}', steps.bumpVersion.outputs.version) }}
        run: |
          gh release create "$tag" \
              --repo="$GITHUB_REPOSITORY" \
              --title="${GITHUB_REPOSITORY#*/} ${tag#v}" \
              --generate-notes

Pull Request Workflow

To ensure that every pull request includes the necessary versioning files, you can use the verify goal in your PR workflow. This example fails the build if the versioning specifications are missing or inconsistent.

name: Pull Request Build
on:
  pull_request:
    branches: [ main ]
permissions:
  contents: read
jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7

      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: 'temurin'
          java-version: '17'

      - name: Build verify versioning
        run: |
          # Run the verify goal to check for consistent versioning files
          mvn io.github.bsels:semantic-version-maven-plugin:verify

Maintenance Scripts

The plugin can execute external scripts during the update goal via the versioning.update.scripts property. These scripts are useful for keeping documentation and source code in sync with the new version.

Each script receives the following environment variables:

  • CURRENT_VERSION: The version before the bump.
  • NEW_VERSION: The new version being applied.
  • PROJECT_PATH: Absolute path to the module directory.
  • DRY_RUN: true or false.
  • GIT_STAGING: true or false (indicates if the script should stage its changes).
  • EXECUTION_DATE: The date of execution in yyyy-MM-dd format.

update-deprecation-version.sh

This script automates the replacement of the 1.5.0 placeholder in the codebase. It searches for the placeholder in Java source files and Markdown documentation and replaces it with the NEW_VERSION.

#!/usr/bin/env bash
set -e

if [ -z "$NEW_VERSION" ]; then
  echo "Error: NEW_VERSION environment variable is not set."
  exit 1
fi

PLACEHOLDER="1.5.0"
BASE_DIR="${PROJECT_PATH:-.}"

# Identify files containing the placeholder within the project path
# Exclude the script itself, .git, and target directories
FILES=$(grep -lR "$PLACEHOLDER" "$BASE_DIR" --exclude=update-deprecation-version.sh --exclude-dir=.git --exclude-dir=target || true)

if [ -z "$FILES" ]; then
  echo "No files containing placeholder $PLACEHOLDER found."
  exit 0
fi

if [ "$DRY_RUN" = "true" ]
then
  for FILE in $FILES; do
    echo "Dry run: replacement in $FILE"
    sed "s/$PLACEHOLDER/$NEW_VERSION/g" "$FILE"
  done
else
  for FILE in $FILES; do
    echo "Processing $FILE..."
    sed -i "s/$PLACEHOLDER/$NEW_VERSION/g" "$FILE"
    if [ "$GIT_STAGING" = "true" ]
    then
      git add "$FILE"
    fi
  done
  echo "Successfully updated deprecation version to $NEW_VERSION"
fi

Usage in pom.xml:

<configuration>
    <updateScripts>./update-deprecation-version.sh</updateScripts>
</configuration>

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A Maven plugin that automates semantic versioning with markdown‑based changelog management. Provides two standalone goals: create generates interactive version spec files; update applies those specs, bumps project versions, and merges CHANGELOG entries.

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

Contributors

Languages