Category Archives: NAnt

I wish we could use JIRA for generating release file in build result. cc.net does have a ModificationHistory publisher, but for some reason, the version CCConfig I have doesn’t work for this. (Somebody filed the bug already, I did a vote.)

The workaround I’m using:

  1. Enable ModificationWriterTask in cc.net project publisher, this will generate a file named modifications.xml in artifact folder, which only contains the changes since last build.
  2. Create a NAnt task to merge modifications info into a modificationHistory.xml file. (idea from here)
  3. Create another NAnt task to transform the xml into a text file.
	<target name="publish.mod.history" depends="merge.mod.history" >
		<style style="${build.dir}\modifications.xsl"
			in="${CCNetArtifactDirectory}\modificationHistory.xml"
			out="${CCNetArtifactDirectory}\${application.version}\modifications.txt">
	    <parameters>
	        <parameter name="reportType" namespaceuri="" value="Plain" />
	    </parameters>
		</style>
	</target>

	<target name="merge.mod.history" description="add the new mod list to an existing xml file">
		<property name="xmlnodes" value=""/>
		<xmlpeek xpath="//ArrayOfModification" file="${CCNetArtifactDirectory}\modificationHistory.xml" property="xmlnodes"></xmlpeek>
		<property name="newnode" value="" />
		<xmlpeek xpath="//ArrayOfModification" file="${CCNetArtifactDirectory}\modifications.xml" property="newnode"></xmlpeek>
		<property name="xmlnodes" value="${newnode}${xmlnodes}" />
		<xmlpoke file="${CCNetArtifactDirectory}\modificationHistory.xml" xpath="//ArrayOfModification" value="${xmlnodes}" />
	</target>

Modifications.xsl:

<?xml version="1.0"?><!-- DWXMLSource="modificationHistory0.xml" -->
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"

     version="1.0">

    <xsl:output method="text"/>

    <xsl:variable name="modification.list" select="ArrayOfModification/Modification"/>

    <xsl:template match="/">
Modifications since last build (<xsl:value-of select="count($modification.list)"/>)
    <xsl:apply-templates select="$modification.list">
        <xsl:sort select="date" order="descending" data-type="text" />
    </xsl:apply-templates>
    </xsl:template>

    <!-- Modifications template -->
    <xsl:template match="Modification">
 (Revision:<xsl:value-of select="ChangeNumber"/>) <xsl:value-of select="FolderName"/>/<xsl:value-of select="FileName"/>, <xsl:value-of select="UserName"/> on <xsl:value-of select='substring(ModifiedTime, 0, 11)'/>, <xsl:value-of select="Comment"/>
    </xsl:template>

</xsl:stylesheet>

Result:

Modifications since last build (14)

(Revision:15) /trunk/build/modificationHistory0.xml, FMao on 2009-10-15,
(Revision:15) /trunk/build/modifications.xsl, FMao on 2009-10-15,
(Revision:12) /trunk/build/default.build, FMao on 2009-10-15, added new task to merge mod hist and transform xml
(Revision:12) /trunk/pbunit_demo.pbw, FMao on 2009-10-15, added new task to merge mod hist and transform xml

When using NAnt includebuild file, make sure you have both including and included file have this attributes in project setting, otherwise the include will fail.

<project name=”your.project” xmlns=”http://nant.sf.net/release/0.85/nant.xsd”>

But why? Magic xml.

As JP suggested, I always compile all my layered projects into a huge dll to make NAnt build file eaiser. This solution is perfect until I tried to embeb structuremap config file into cruise control. Because assembly file name changed, I have to find a way to replace the config file content in NAnt.

It was not easy. NAnt doesn’t have a replace task!

I don’t want hack into NAnt source to re-build my own version. It seems Jay Flowers, the creator of CI Factory has his modified version of NAnt which has replace task in it, but, no document to direct me how to use it.

OK, I have to call Ant task in NAnt build file then.

[NAnt build file]
<exec program=”c:\ant\bin\ant.bat” basedir=”${base.dir} “>
<arg value=”-Dcurrentproject.lib=${currentproject.lib}” />
</exec>

[Ant file]
<project name=”config” default=”replace_config” basedir=”.”>

<property name=”build.dir” value=”${basedir}\build”/>
<property name=”currentproject.lib” value=”undefined”/>

<target name=”replace_config”>
<replace file=”${build.dir}\StructureMap.config”>
<replacefilter token=”,mybizlayer” value=”,${currentproject.lib}”  />
<replacefilter token=”,mydatalayer” value=”,${currentproject.lib}”  />

</replace>

</target>
</project>

When I moved my dotnet project from my workstation to CC.net server (64 bit windows 2003 server), this problem appears:

System.NullReferenceException: Object reference not set to an instance of an object.
at NAnt.Core.FrameworkInfo.get_Version()

There is a solution on Jeffery Palermo’s blog in which a extra dotnet 3.5 configuration is provided. I didn’t want to do this at first because the version I have (.86 beta1) already include this part. I decided to change my xml file little by little with no good, finally, I copied the whole piece of  Jefferyof xml about .net 35 config to NAnt.exe.config, the problem was fixed then.

There must be something different in the assembly list, for 64 bit server maybe?