Automating Semantic Versioning with Maven (SemVer GitFlow Maven)

Are you using a semantic approach to version control? Are you using gitflow? You are most likely familiar with the process of adjusting versions, creating branches, merging from master / dev, re-adjusting versions, dealing with merge conflicts, ...



In this article, I will briefly explain the release process that we essentially use for our libraries and how we have automated it. We usually use a CI / CD approach using build numbers, but for our libraries we chose to use semantic versioning. I ran into the tedious release process that accompanies this in several companies and now I finally found a solution.



This article is about Maven, but there are many alternatives to Gradle .



A sample project can be found on our GitHub page .



Semantic versioning and Git



Semantic versioning is the classification system for your releases. I'm sure you've seen version numbers like 1.6.4, 1.7.10, 1.12.2 and others. These numbers stand for MAJOR.MINOR.PATCH (MAJOR.MINOR.PATCH)



In addition, there are versions of SNAPSHOT that look the same, but with the addition of "-SNAPSHOT" at the end, such as 1.14.4-SNAPSHOT.



A typical release process consists of the following steps:



  1. Create a release branch from the development branch (hereinafter the development branch).
  2. Change the version in all pom.xml files from SNAPSHOT (1.2.3-SNAPSHOT) to non-SNAPSHOT (1.2.3) in the release branch.
  3. Upgrade the SNAPSHOT version on the develop branch (1.2.4-SNAPSHOT).
  4. When everything is done for release, merge the release branch into the master branch. This is the current release.
  5. Merge the master branch or release branch back to the development branch.


/ , : , , .



, , . , merge .



?



  • , .
  • master SNAPSHOT.
  • CI, .
  • merge .
  • hotfixes ( master ).


gitflow-maven



, maven, pom.xml. . , .



, , . , . , : gitflow-maven-plugin.



, :



  • .
  • release .
  • hotfix.
  • (Merging) .


, . , CI/CD, , .



, (goals) maven. , .



:



, .



$ mvn gitflow:release-start -B


release (-B Batch Mode)



$ mvn gitflow:release


. master .



, , .



$ mvn gitflow:hotfix-start -B


$ mvn gitflow:hotfix-finish -B -DhotfixVersion=1.8.9b 


hotfix master , 1.8.9b . . - , .





, poms:



<build>
    <plugins>
        <plugin>
            <groupId>com.amashchenko.maven.plugin</groupId>
            <artifactId>gitflow-maven-plugin</artifactId>
            <version>1.13.0</version>
            <configuration>
                <!-- optional configuration -->
            </configuration>
        </plugin>
    </plugins>
</build>


GitHub maven central.



GitHub. :



<configuration>
    <!-- We use maven wrapper in all our projects instead of a local maven installation -->
    <mvnExecutable>./mvnw</mvnExecutable>

    <!-- Don’t push to the git remote. Very useful for testing locally -->
    <pushRemote>true</pushRemote>

    <!-- Set to true to immediately bump the development version when creating a release branch -->
    <commitDevelopmentVersionAtStart>false</commitDevelopmentVersionAtStart>

    <!-- Which digit to increas in major.minor.patch versioning, the values being 0.1.2 respectively.
         By default the rightmost number is increased.
         Pass in the number via parameter or profile to allow configuration,
         since everything set in the file can't be overwritten via command line -->
    <versionDigitToIncrement>${gitflowDigitToIncrement}</versionDigitToIncrement>

    <!-- Execute mvn verify before release -->
    <preReleaseGoals>verify</preReleaseGoals>
    <preHotfixGoals>verify</preHotfixGoals>

    <!-- Configure branches -->
    <gitFlowConfig>
        <productionBranch>master</productionBranch>
        <!-- default is develop, but we use development -->
        <developmentBranch>development</developmentBranch>
    </gitFlowConfig>
</configuration>


, , . , Gitlab CI.



Gitlab CI



CI/CD Gitlab CI , commit snapshot, merge master — release.



, — , master merge , hotfixes.



Gitlab CI, . :





release. , release, release, snapshot, (merge) master snapshot. - .



git Gitlab CI



git Gitlab CI, : , CI git.



write_repository. , , .



GITLAB_TOKEN, protected, development, release/* hotfix/* (protected). , .



git remote runner, CI . , Gitlab, :



$ git remote set-url --push origin "https://oauth2:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"


git . Git «», git. , git , . :



$ git config user.name "Gitlab CI"
$ git config user.email gitlab-ci@viesure.io


git, CI. .





, git CI, gitflow. .



, , :



· MINOR



· PATCH hotfixes



.



(goals) -B, , .



Release



$ ./mvnw gitflow: release -B -DgitflowDigitToIncrement = $RELEASE_DIGIT


. master SNAPSHOT , . (goal ) maven , .





$ ./mvnw gitflow: release-start -B -DgitflowDigitToIncrement = $RELEASE_DIGIT


$ git push origin HEAD


. , , , (, , ). , , .



$ git symbolic-ref refs/heads/$CI_COMMIT_REF_NAME refs/remotes/origin/$CI_COMMIT_REF_NAME
$ ./mvnw gitflow:release-finish -B -DgitflowDigitToIncrement=$RELEASE_DIGIT


release . Git ( ref) HEAD . Gitlab CI . HEAD . , , HEAD.



master , .



(Hotfix)



, , , , .



$ ./mvnw gitflow:hotfix-start -B -DgitflowDigitToIncrement=$HOTFIX_DIGIT
$ git push origin HEAD


Hotfix-start hotfix, .



$ export CURRENT_VERSION=${CI_COMMIT_REF_NAME/hotfix\/}
$ git symbolic-ref refs/heads/$CI_COMMIT_REF_NAME refs/remotes/origin/$CI_COMMIT_REF_NAME
$ ./mvnw gitflow:hotfix-finish -B -DgitflowDigitToIncrement=$HOTFIX_DIGIT -DhotfixVersion=$CURRENT_VERSION


Hotfix-finish master . : . , , . .



, hotfix-start , . , .



. , .





. , - !



, git CI runners . , , .



, . CI .



Gitlab CI GitHub.








All Articles