How would you write a build.xml
file, using neither custom code nor external dependencies (such as a shell script), that:
In my project i don’t increase the minor and major number automatically. We set it from our global build properties. Like that:
<entry key="build.major.number" value="${global.release.major}"></entry>
<entry key="build.minor.number" value="${global.release.minor}"></entry>
That’s because they will be changed for releases (not for test or other builds) and committed together with other sources (we have be able to build some old or branch version).
But if you want to increase the minor number, you can do it like the build number in my example.
<entry key="build.major.number" type="int" operation="+" default="1" pattern="00"/>
This was a while ago, so this is from memory:
I build a custom CruiseControl.Net labeller block that ticked up the build number on each build. It maintained an XML file with all 4 components of the version number and identified each project by name (so it could support multiple projects).
The four values it generated get passed to the build process (nAnt, in our case), which had the responsibility of tweaking all the AssemblyInfo.cs files to reflect the proper build number.
Edited to note: The only value that get automatically ticked up was the build number. Major/Minor version numbers were specified in the CC.Net project configuration. The build number restarted at 0001 for each change in major or minor revision number (e.g., if you went from version 7.1 to version 7.3, for instance, the 7.1 build might be at build number 783, but the first 7.3 build started with build number 1; the next 7.1 build would be build 784.
Change version numbers merely required tweaking 1 setting the CC.Net config file.
This solution does increment minor or revision number automatically if a compile or a dist target has been selected. The incrementation can be switched off if one of the following properties has been set:
If the property inc.major has been set, then the major number will be incremented and the other both values will be set to zero. The SHA-1 checksum is being calculated by the textual representation of the version file.
By the way: If would have been allowed, you could create your own ant task in java script, which is included in JDK 6.
Now here's the ant file
<?xml version="1.0" encoding="UTF-8"?>
<project name="Numbers" default="dist" basedir=".">
<property name="version.file" location="${basedir}/version.properties"/>
<target name="inc.revision.properties" unless="no.increment.revision">
<propertyfile file="${version.file}">
<entry key="minor.number" default="00" operation="=" pattern="00" type="int"/>
<entry key="major.number" default="00" operation="=" pattern="00" type="int"/>
<entry key="build.number" default="00" operation="+" pattern="00" type="int"/>
</propertyfile>
</target>
<target name="inc.minor.properties" unless="no.increment.minor">
<propertyfile file="${version.file}">
<entry key="minor.number" default="00" operation="+" pattern="00" type="int"/>
<entry key="major.number" default="00" operation="=" pattern="00" type="int"/>
<entry key="build.number" value="00" operation="=" type="int"/>
</propertyfile>
</target>
<target name="inc.major" if="inc.major">
<property name="no.increment.minor" value="true" />
<property name="no.increment.revision" value="true" />
<propertyfile file="${version.file}">
<entry key="minor.number" value="00" operation="=" pattern="00" type="int"/>
<entry key="major.number" default="00" operation="+" pattern="00" type="int"/>
<entry key="build.number" value="00" operation="=" pattern="00" type="int"/>
</propertyfile>
<load.version.info/>
</target>
<target name="inc.minor" depends="inc.major,inc.minor.properties">
<property name="no.increment.revision" value="true"/>
<load.version.info/>
</target>
<target name="inc.revision" depends="inc.major,inc.revision.properties">
<load.version.info/>
</target>
<macrodef name="load.version.info">
<sequential>
<property file="${version.file}"/>
<checksum file="${version.file}" property="sha1.number" algorithm="SHA" format="CHECKSUM"/>
<echo>Version: ${major.number}.${minor.number}.${build.number}</echo>
<echo>SHA1: ${sha1.number}</echo>
</sequential>
</macrodef>
<target name="compile" depends="inc.revision" description="Compile Task"/>
<target name="dist" depends="inc.minor, compile" description="Dest Task"/>
</project>
The build_info.properties
file:
build.major.number=00
build.revision.number=00
build.minor.number=00
The build.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<project name="project" default="current-number">
<property file="build_info.properties"/>
<property name="build.number" value="${build.major.number}.${build.minor.number}.${build.revision.number}"/>
<target name="current-number">
<echo>Current build number:${build.number}</echo>
</target>
<target name="compile">
<antcall target="revision"></antcall>
</target>
<target name="dist">
<antcall target="minor"></antcall>
</target>
<target name="revision">
<propertyfile file="build_info.properties">
<entry key="build.revision.number" type="int" operation="+" value="1" pattern="00"/>
</propertyfile>
</target>
<target name="minor">
<propertyfile file="build_info.properties">
<entry key="build.minor.number" type="int" operation="+" value="1" pattern="00"/>
<entry key="build.revision.number" type="int" value="0" pattern="00"/>
</propertyfile>
</target>
<target name="major">
<propertyfile file="build_info.properties">
<entry key="build.major.number" type="int" operation="+" value="1" pattern="00"/>
<entry key="build.minor.number" type="int" value="0" pattern="00"/>
<entry key="build.revision.number" type="int" value="0" pattern="00"/>
</propertyfile>
</target>
<target name="all">
<propertyfile file="build_info.properties">
<entry key="build.major.number" type="int" operation="+" value="1" pattern="00"/>
<entry key="build.minor.number" type="int" operation="+" value="1" pattern="00"/>
<entry key="build.revision.number" type="int" operation="+" value="1" pattern="00"/>
</propertyfile>
</target>
</project>
We can use conditions to check if we should increase the micro,minor and major version.
Increase minor if micro is 9, and so on.
<target name="increaseBuildNumber" depends="increase.micro, increase.minor, increase.major" description="Increase Build Number"/>
<target name="increase.micro" if ="microNotEquals9">
<propertyfile file="build.properties">
<entry key="micro.number" default="0" operation="+" pattern="0" type="int"/>
</propertyfile>
</target>
<target name="increase.minor" if = "microEquals9andMinorNotEquals9">
<propertyfile file="build.properties">
<entry key="minor.number" default="0" operation="+" pattern="0" type="int"/>
<entry key="micro.number" value="0" operation="=" pattern="0" type="int"/>
</propertyfile>
</target>
<target name="increase.major" if = "microAndMinorEquals9" >
<propertyfile file="build.properties">
<entry key="major.number" default="0" operation="+" pattern="0" type="int"/>
<entry key="minor.number" value="0" operation="=" pattern="0" type="int"/>
<entry key="micro.number" value="0" operation="=" pattern="0" type="int"/>
</propertyfile>
</target>
<condition property="minorEquals9">
<equals arg1="${minor.number}" arg2="9"/>
</condition>
<condition property="microEquals9andMinorNotEquals9">
<and>
<equals arg1="${micro.number}" arg2="9"/>
<not><equals arg1="${minor.number}" arg2="9"/></not>
</and>
</condition>
<condition property="microAndMinorEquals9">
<and>
<equals arg1="${micro.number}" arg2="9"/>
<equals arg1="${minor.number}" arg2="9"/>
</and>
</condition>
<condition property="microNotEquals9">
<not><equals arg1="${micro.number}" arg2="9"/></not>
</condition>
build_info.properties
will be created during build in your project
folder You could write all information about your build in this file.
After first build the file build_info.properties will be placed in the repository. You can change and commit any number (major, minor, build numbers) by your self when ever you want, or increase it automatically during build like build.number in the example below.
Using svnant 1.3.0:
<target name="checkout">
<echo>Checking out revision ${param_SubProjectSvnREV} of project: ${param_SubProjectSvnName}</echo>
<svn username="${svnant.repository.user}" password="${svnant.repository.passwd}">
<checkout url="${svnant.latest.url}/${param_SubProjectSvnName}/" revision="${param_SubProjectSvnREV}" destPath="${all.projects.dir}/${param_SubProjectDirName}" />
<info target="${all.projects.dir}/${param_SubProjectDirName}" ></info>
</svn>
<propertyfile file="${all.projects.dir}/${param_SubProjectDirName}/build_info.properties" comment="Modify build numbers in a properties file.">
<entry key="build.number" type="int" operation="+" value="1" pattern="00"/><!--increment it here -->
<entry key="build.revision" type="string" value="${svn.info.rev}"/>
<entry key="build.major.number" default="01"/><!-- can do some logic here to increase the values, or write value from somewhere else-->
<entry key="build.minor.number" default="01"/><!-- can do some logic here to increase the values, or write value from somewhere else-->
</propertyfile>
</target>
<target name="compile" depends="checkout">
<property file="${all.projects.dir}/${param_SubProjectDirName}/build_info.properties" />
<mkdir dir="${release.name}/${param_SubProjectDirName}/${build.major.number}.${build.minor.number}.${build.number}" />
<!-- compile it to the new folder, an so on... -->
<!-- after all, if the build wass successfull, commit the file 'build_info.properties' back to repository -->
</target>