Add build info to your project

02 Apr 2017

Tags: Grails, Build

Introduction

When you build and run Grails 3 applications, often you may want to know about the build environment via the running application.

Since the early days of Grails, we were able to add arbitrary properties to the application.properties file. Grails provides this information through the grails.util.Metadata class, and for views this is easily made available through the <g:meta> tag.

Since Grails 3 is built with Gradle, the old application.properties is no longer in use, instead we’ll add properties to grails.build.info

The basics

When you build/run your Grails applications, one of tasks that Gradle always executes is the buildProperties. This task takes a small set of build information from your project, and places it in a file, which the Grails Metadata class later reads. This file is located in META-INF and is named grails.build.info.

At build time you can find this file at build/resources/main/META-INF/grails.build.info. The contents of this file looks like:

#Thu, 02 Feb 2017 15:30:37 +0100

info.app.version=0.1
info.app.name=metadata
grails.env=production
info.app.grailsVersion=3.2.5

This info primarily comes from build.gradle and gradle.properties (the curious can check out the source code in grails-core). This file will be part of your final application when you build your .jar or .war file.

In a .gsp this information is available by using the meta tag like this: <g:meta name='info.app.version'/> (see the tag documentation).

Adding more information to grails.build.info

With the Gradle build system it is possible to hook into the build process and execute our own code. In this case we want Gradle to complete writing grails.build.info and then we want to add additional properties to the file.

To accomplish this, add the following snippet to build.gradle in your project:

buildProperties.doLast {
    // Find the right file
    File grailsBuildInfoFile = it.outputs.files.files.find { it.name == 'grails.build.info' }
    if(!grailsBuildInfoFile) return // No need to continue if the file is not there
    Properties properties = new Properties()
    // Read properties from the file
    grailsBuildInfoFile.withInputStream {
        properties.load(it)
    }
    // Add new properties from various sources
    properties.setProperty('build.time', new Date().format("yyyy-MM-dd HH:mm:ss"))
    // Get a System property
    properties.setProperty('build.java.version', System.getProperty('java.version'))
    // Get the host name where the build was created
    properties.setProperty('build.host', InetAddress.localHost.hostName)
    // Add property set by your CI (in this case Bamboo)
    Map<String, String> env = System.getenv()
    if(env.bamboo_buildNumber) {
        properties.setProperty('build.number', env.bamboo_buildNumber)
        properties.setProperty('build.git.revision', env.bamboo_planRepository_revision)
        properties.setProperty('build.git.branch', env.bamboo_planRepository_branch)
    }
    // Write the properties back to the file
    grailsBuildInfoFile.withOutputStream {
        properties.store(it,null)
    }
}

This example shows how to set build.time from the time that the build was executed, how to set values from System.properties, how to get your build host name, and finally how to read environment variables set by your build server (in the above example by Atlassian Bamboo)

Now that we have this build information captured in grails.build.info, we can show it in our application in a .gsp page, for example:

<table>
    <thead>
        <tr><th>Name</th><th>Value</th></tr>
    </thead>
    <tbody>
        <tr><td>Build time</td><td><g:meta name="build.time"/>></td></tr>
        <tr><td>Build java version</td><td><g:meta name="build.java.version"/>></td></tr>
        <tr><td>Build host</td><td><g:meta name="build.host"/>></td></tr>
    </tbody>
</table>

and so on.

NOTE: If you use the Spring Boot Actuator endpoints, you can write your own custom InfoContributor that uses Grails Metadata! Alternatively, you can leverage the Auto-configured InfoContributors to add git commit info, expose build info by copying grails.build.info to a build-info.properties file (BuildInfoContributor), expose environment info by configuring properties starting with 'info.' such as 'info.app.name' (EnvironmentInfoContributor)

Conclusion

This blog-post shows how you easily can add build information to your Grails 3 application by leveraging the tasks already available within the Gradle build, and how you can show them in your application.

Published on 02 Apr 2017