Sunday, January 01, 2017

Get release details into your Grails-3 application . . .

It is always a good practice to make application release details like: commit id, version number and build tag etc. available within the application for display as a reference to know the current deployed code state of the application. Typically, these details can be taken into the application during build, specifically during the assembling phase of creating a deployable artifact (war or jar archive file). In an integrated development environment, Continuous Integration (CI) platforms like Jenkins, Bamboo can pass in release details to the build job which is setup to run application's build task(s).

In Grails-3 applications, this can simply be achieved by hooking into the underlying Gradle build system's assemble task. This involves writing customizing processResources task in build.gradle build file something like as shown below:

build.gradle
... //filters, populates BUILD_TAG and GIT_REVISION in the resource file: application.yml with their //actual values passed through -P flag when 'assemble' task is run processResources { println "Processing resources..." def buildTag = project.properties['BUILD_TAG'] ?: 'undefined' def gitRevision = project.properties['GIT_REVISION'] ?: 'undefined' filesMatching("**/application.yml") { println "Replacing BUILD_TAG and GIT_REVISION in application.yml with ${buildTag} and ${gitRevision}..." expand( [ 'BUILD_TAG' : buildTag, 'GIT_REVISION': gitRevision ] ) } } ...

That's no big deal, but if you have more than one Grails-3 application in your organization, with this strategy, you end up copying such customized build code snippet across all projects.

Grails framework applies and promotes DRY (Don't Repeat Yourself) principle. Gradle offers a plugin architecture for sharing reusable build logic across many projects'  build scripts. Gradle's plugin architecture can be leveraged to put a DRY solution to this problem. So, an ideal DRY solution to this problem in a Grails-3 environment is to make this piece of build logic packaged into as a simple custom Gradle Plugin.

I recently created a simple Gradle plugin as a DRY solution to this problem and hosted it on our organization's Bintray repository. The source code is hosted and available on Github.

Plugin Source Code - https://github.com/gpottepalem/gradle-release-info
Plugin repository - https://bintray.com/goodstartgenetics/gradle-plugins/release-info

References