Skip to main content

Using Hudson environment variables to identify your buildsUsing Hudson environment variables to identify your builds

Posted by johnsmart on March 9, 2008 at 8:21 PM PDT

So your CI server now automatically deploys your application to an integration server. You've even configured it so that you can manually deploy to the QA server using the same process. Great! But wouldn't it be nice to know exactly what build you are looking at at any point in time? Well, Hudson lets you do just that.

When Hudson runs a build, it passes in a few useful environment variables, that you can use in your build script. This is a great way to inject information about the build into your deployable application. For example, Hudson build has a unique number, which you can reference in your build scripts using something like "${BUILD_NUMBER}". This is the list of variables (taken from an obscure corner of the Hudson documentation :-)):

  • BUILD_NUMBER: The current build number, such as "153"
  • BUILD_ID: The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
  • JOB_NAME: Name of the project of this build, such as "foo"
  • BUILD_TAG: String of "hudson-${JOBNAME}-${BUILD_NUMBER}". Convenient to put into a resource file, a jar file, etc for easier identification.
  • EXECUTOR_NUMBER: The unique number that identifies the current executor (among executors of the same machine) that's carrying out this build. This is the number you see in the "build executor status", except that the number starts from 0, not 1.
  • JAVA_HOME: If your job is configured to use a specific JDK, this variable is set to the JAVA_HOME of the specified JDK. When this variable is set, PATH is also updated to have $JAVA_HOME/bin.
  • WORKSPACE: The absolute path of the workspace.
  • HUDSON_URL: Full URL of Hudson, like http://server:port/hudson/
  • SVN_REVISION: For Subversion-based projects, this variable contains the revision number of the module.
  • CVS_BRANCH: For CVS-based projects, this variable contains the branch of the module. If CVS is configured to check out the trunk, this environment variable will not be set.

Sweet, you say. But how can you inject this into your deployable application? Easy. Just use these variables as you would any other properties, and let your imagination do the rest! In a Maven project, for example, you can use the maven-war-plugin plugin to inject data into the MANIFEST.MF file as follows:

<project>    ...    <build>        ...        <plugins>            <plugin>                <artifactId>maven-war-plugin</artifactId>                <configuration>                    <manifest>                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>                    </manifest>                    <archive>                        <manifestEntries>                            <Specification-Title>${}</Specification-Title>                            <Specification-Version>${project.version}</Specification-Version>                            <Implementation-Version>${BUILD_TAG}</Implementation-Version>                        </manifestEntries>                    </archive>                </configuration>            </plugin>            ...        </plugins>    </build>    ...</project>

Now, the WAR file generated by Hudson will contain the build number:

Manifest-Version: 1.0

Archiver-Version: Plexus Archiver

Created-By: Apache Maven

Built-By: hudson

Build-Jdk: 1.5.0_14

Implementation-Version: hudson-mywebapp-integration-tests-60
Specification-Title: MyWebApp
Specification-Version: 1.0-SNAPSHOT

It is then a simple matter to extract this field from the MANIFEST.MF file of your deployed application at runtime. The java.util.jar.Manifest comes in handy here. I use this to display the build version discretly at the bottom of the screen so that testers can identify exactly what version they are dealing with.

The San Francisco Java Power Tools Bootcamp - May 12-15

I'll be giving a 4 day Java Power Tools Bootcamp in San Francisco, from May 12 to May 15 just after JavaOne. So, if your in SF at this time, come along!


I've answered my own questions, see below!

This is fantastically useful. I wonder though, where is this obscure corner of the documentation? Thanks!