How to Add Build Info to Your Project
April 2, 2017
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 the Grails framework, we were able to add arbitrary properties to the application.properties
file. The Grails framework provides this information through the grails.util.Metadata
class, and for views this is easily made available through the 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 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: (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
- 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"></g:meta>></td></tr>
<tr><td>Build java version</td><td><g:meta name="build.java.version"></g:meta>></td></tr>
<tr><td>Build host</td><td><g:meta name="build.host"></g:meta>></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 abuild-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 can easily 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.