Automatic Java Artifacts Upload to Nexus Repository with Walter and Git Hooks

I have been developing a tiny tool, RedPen. The tool is for proofreading input texts written in Markdown or LaTeX formats, and written in Java. As this tool are released, the jar files are uploaded into the Nexus repository.  For uploading, we used the Maven release plugin.

Although the settings of Maven release plugin (“pom.xml”, electronic signatures, etc.) is bothered, the tool itself is convenient. We can upload the artifacts to the Nexus repository just running the mvn release command at a release timing. However, I have recently feel that the release process with the plugin is troublesome.

This article introduces an automatic release process covering adding version numbers and upload artifacts to the Nexus repository with Walter, a tiny deployment pipeline and Git Hooks.

But first, I would like to introduce the release process with the Maven release plugin.

Release process with Maven release plugin

When we run the release plugin, we need to input misc information interactively. The following is the status for the preparation of a release plugin running mvn release:prepare.

➜ mvn release:prepare
[INFO] Scanning for projects...
...
[INFO] Checking dependencies and plugins for snapshots ...
What is the release version for "redpen"? (cc.redpen:redpen) 1.7.5: :

Then, we are requested to input the release version, though the release plugin suggests the release version guessed from the current snapshot version (1.7.5 in the above example). If the suggested version is not what we want, we input the version number manually.

Next, the plugin requests a development version number, and the we input it manually if necessary.

What is the new development version for "redpen"? (cc.redpen:redpen) 1.7.6-SNAPSHOT:

After that, the plugin commits the new version number to local git, and then the build is executed. When the build succeeds, the plugin notifies that it will push the version number change to the remote repository.

[INFO] Working directory: /Users/takahi-i/IdeaProjects/redpen
Username for 'https://github.com': Password for 'https://github.com':

As we see, the plugin requests the GitHub account name and password. In addition, even after mvn release:prepare succeeds, we still need to input interactively even for the next release command,release:perform.

Automatic uploading artifacts to Nexus with Walter

As we see the release plugin is quite tricky due to its interactive input operation.

Prior Examples

Recently I heard that we can use mvn deploy command for the release purpose and the command is simpler than Maven release plugin.

Applying Walter

We can apply mvn deploy Jenkins server for the release automation, and off course we can use external CI services such as Wercker or Traivs for this purpose. But just for the release process of a tiny project such as RedPen, both solutions are a bit costly. In addition, analyzing the log files in remote servers is bothered when the release process in such services does not work.

Therefore, I apply Walter for the automation of release process. Walter automates the release process and the process is run locally. Please refer here for details of Walter. Below is the configuration file for the automation of the RedPen release process.

pipeline:
  - name: Set Version
    command: mvn versions:set -DnewVersion=$REDPEN_VERSION
  - name: Add Files to the Next Changes
    command: git add pom.xml; git add **/*.xml
  - name: Commit Version Changes
    command: git commit -m "Set version in pom.xml to $REDPEN_VERSION"
  - name: Delopy to Sonatype
    command: mvn clean deploy -DperformRelease --settings ~/.m2/settings.xml > /dev/null
  - name: Create Release Tag
    command: git tag -a redpen-$REDPEN_VERSION -m "RedPen release $REDPEN_VERSION"
  - name: Flush Next Release Version Number
    command: echo $REDPEN_VERSION | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d-SNAPSHOT", length($NF), ($NF+1)%(10^length($NF))); print}'
  - name: Echo Next Version
    command: echo __OUT["Flush Next Release Version Number"]
  - name: Set next version
    command: mvn versions:set -DnewVersion=__OUT["Flush Next Release Version Number"]
  - name: Git Add
    command: git add .
  - name: Commit New Snapshot version
    command: git commit -m "Update versions in pom.xml for next release"

The first stage sets the version that was given from the environment variable. Next stage registers the changes to git. The artifacts are now ready to be uploaded on Nexus. Then the fourth stage (Delopy to Sonatype) uploads results to Sonatype with “mvn clean deploy”.

After the deployment, Walter assigns the development version for the next release. The development version name in Java projects commonly has a “-SNAPSHOT” suffix. The stage, “Flush Next Release Version Number”, calculates the next version number, and then set the version with the “mvn versions:set” command.

The release process is then completed just running the “walter -c release.yml” command (off course we need to close and release the stating repository by manual operation in Sonatype).

Combination Walter and Git Hooks for Further Automation

The release processing is able to be completed with a single command. However, one problem still exists. RedPen has the ability to check its versions with a command and server. The version is set by overwriting one line of the RedPen.java file.

Unfortunately I have an experience releasing RedPen without increasing the version number. For the problem, I applied Git Hook to solve this problem with Walter. When a specific git command is run, Git Hook automatically runs an assigned script.

I set Git Hook script to run the release command automatically with Walter only when the commit message is “Bump version…” at the time of git commit. Specifically I put the following Git Hook script file in ./git/hooks/post-commit.

#!/bin/bash

LATEST_MESSAGE=`git log -1 --pretty=%B`

if echo $LATEST_MESSAGE | grep -q "^Bump version " ; then
  export REDPEN_VERSION=`echo $LATEST_MESSAGE | grep -o "[0-9.]\+"`
  echo "Extracted Version: " $REDPEN_VERSION
  ./walter -c release.yml
else
  echo "Not changed version"
fi

With this file, when the commit message shows “Bump version” the release processing will run (the commit message that changes the RedPen version is Bump version). This trick prevents accidental release without increasing version number.

Future work

In the RedPen project, a sample server on Heroku is replaced to a the latest every time a commit is pushed to the remote repository. Although I am currently using Jenkins for the replacement of servers, I will try the replace of the process in Walter as the next step.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s