ColdFusion ANT Deployment Scripts - Part One: Versioning

This is the first post of a series in which I will be discussing how I leverage ANT with my ColdFusion applications for various pieces of deployment.  Tentatively, this series will consist of:

  1. Versioning

  2. Generating ColdDoc (javadoc-like CFC documentation)

  3. Automating MXUnit Tests

  4. Deployment (via SSH, FTP, Windows Network)

Note: All files mentioned here should be placed directly in your root project directory.

Step 1 - Create our basic build.xml file

First, we will simply stub out our build file.  For now I simply stub one target, called version.  We will also reference a file to hold all variables that pertain to the build (we'll build it later).

<project name="CFAntDemo" default="version" basedir=".">   <property file="" /> <target name="version">     </target> </project>

Step 2 - Create our file

This is a very simple properties file to control our versioning.  It contains two properties - the first, version, is a standard major minor version number which we will manually adjust (I'm starting at 1.0 for this demo).  The second, build, will simply get auto incremented by our ANT script each time we call the version target.

version=1.0 build=0

Step 3 - Create our version_stub.cfm file

This file will never actually be referenced by our application (in fact, we don't need to deploy it).  It is solely for use by our version target.  Basically, we will leverage ANT to replace the tokens @version@ and @build@ with the values of their properties from our file.

<cfscript> this.version="@version@";"@build@"; </cfscript>

Step 4 - Create our version.cfm file

Typically, this file will be generated by ANT, but for our first run, let's manually code this file so that we can test our Application.cfc properly.  This file will be cf-included in our Application.cfc, providing properties containing the version number and build number of our current application.

<cfscript> this.version="1.0";"0"; </cfscript>

Step 5 - Edit our Application.cfc

We need to add a few things to our root Application.cfc.  First, in the properties section, we need to cfinclude our version.cfm file.

<cfcomponent displayname="Application"> <cfset"CFAntDemo"> <cfinclude template="version.cfm">

Next, we need to add code into our onApplicationStart() method, to store this.version and in the Application Scope.  I do this in a single variable called, application.fullversion.

<cffunction name="onApplicationStart" returntype="boolean"> <!--- all of my normal onAppStart stuff, Singletons, etc... ---> <cfset application.fullversion = this.version & "-" &> <cfreturn true> </cffunction>

Lastly, I add a hook into my onRequestStart() to call onApplicationStart() whenever this.fullversion does not equal application.fullversion.  Effectively, my application will now refresh itself whenever it's deployed to another server after this target has run.

<cffunction name="onRequestStart" returntype="boolean"> <cfargument name="targetPage" type="string"> <cfset this.fullversion = this.version & "-" &> <cfif not isDefined('application.fullversion') OR this.fullversion neq application.fullversion> <cfset onApplicationStart()> </cfif> <!--- the rest of my onReqStart stuff---> <cfreturn true> </cffunction>

Step 6 - Setup our file

Create the file.  For now, we need 2 properties, version.file (points to our version.cfm file), and version.stub (points to our version_stub.cfm file).

version.file=${basedir}/version.cfm version.stub=${basedir}/version_stub.cfm

Step 7 - Code in our version target on our build.xml file

Replace our stubbed out version target with the following code, which does the following:

  • Only executes if the version.file property has been set (we did this in

  • Increments the build property in the file

  • Copies our version "stub" file over our version.cfm file

  • Replaces our @version@ and @build@ tokens with their values from the updated file.

<target name="version" if="version.file">     <propertyfile file="">         <entry key="build" type="int" operation="+" default="0" />     </propertyfile>     <copy overwrite="true" file="${version.stub}" toFile="${version.file}" />     <replace file="${version.file}" propertyFile="">         <replacefilter token="@version@" property="version" />         <replacefilter token="@build@" property="build" />     </replace> </target>


Coming soon, a download with a working example of this, zipped up.