Skip Navigation Links / Posts / Posts By Category

Posts for Category: Continuous Integration

Feed for this Category
Build WebPart DDF's from within your Nant build script

Having recently finished some work on setting up an automated build environment for a client I know how valuable it is to keep little build script snippets that you come across from time to time.  Last night Grant pointed me at an article which shows how you can build Sharepoint .ddf files from within your NAnt build.  This piece of script will create the ddf file and then fire MakeCab.exe to make the .cab file which is then ready for deployment into Sharepoint.

The article can be found here:
    http://sharepointblogs.com/cmetral/archive/2005/07/27/2975.aspx

...and, here is the working script which is linked to from that article:

<target name="build-cab" description="Creates the cab archive for a wp solution">
       
        <property name="wp.project.name" value="..." />
        <property name="wp.src.dir" value="..." />
        <property name="csproj.file" value="${wp.project.name}.csproj" />
       
       
        <mkdir if="${not directory::exists('${temp.dir}')}" dir="${temp.dir}" />
       
       
        <echo file="${temp.dir}/${wp.project.name}.ddf">.OPTION EXPLICIT
.Set CabinetNameTemplate=${wp.project.name}.cab
.set DiskDirectoryTemplate=CDROM
.Set CompressionType=MSZIP
.Set UniqueFiles="OFF"
.Set Cabinet=on
.Set DiskDirectory1=${project::get-base-directory()}/${build.dir}
        </echo>
       
        <xmlpeek property="assembly.name" file="${wp.src.dir}/${csproj.file}" xpath="
//VisualStudioProject/CSHARP/Build/Settings/@AssemblyName" />
        <xmlpeek property="assembly.build.location" file="${wp.src.dir}/${csproj.file}" xpath="//VisualStudioProject/CSHARP/Build/Settings/Config[@Name='${build.conf}']/@OutputPath" />
        <copy todir="${temp.dir}" file="${wp.src.dir}/${assembly.build.location}/${assembly.name}.dll" />
        <echo append="true" file="${temp.dir}/${wp.project.name}.ddf" message="${assembly.name}.dll" />
       
       
        <xmllist property="resources.list" file="${wp.src.dir}/${csproj.file}" xpath="//VisualStudioProject/CSHARP/Files/Include/File[@BuildAction='Content']/@RelPath" />
        <foreach item="String" delim="," in="${resources.list}" property="resource.file">   
            <echo append="true" file="${temp.dir}/${wp.project.name}.ddf" message="${resource.file}" />
            <copy todir="${temp.dir}" file="${wp.src.dir}/${resource.file}" />
        </foreach>
       
       
        <exec program="makecab.exe" workingdir="${temp.dir}" commandline="/F ${wp.project.name}.ddf" />
       
       
        <delete dir="${temp.dir}" failonerror="false" />
       
</target>

posted on 7/29/2005 12:23:02 AM ( 2 Comments )


TaskSchema - an msbuild task

Peli just published a new MSBuild task called TaskSchema on ProjectDistributor which is kinda similar to the NAnt nantschema task.  Tasks such as this are very cool because you can use them to emit the schema (*.xsd) for a group of tasks and then copy it into the Visual Studio schema folder so that you can get intellisense when writing tasks.  I often add the following nantschema task when authoring NAnt scripts to write the xsd information directly to that folder:

<nantschema
    output="C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml\nant.xsd"
    target-ns="
http://nant.sf.net/release/0.85-rc2/nant.xsd"
    failonerror="false"
    />


With Peli's task you can pass it a list of Assemblies to schematize so it's not quite like nantschema in that you don't need the task loaded into memory.  The way that you pass the assemblies is either by specifying a single assembly or creating a task item to define a fileset, like so:


Single Assembly specified within the Task
<TaskSchema
 Assemblies="PATH TO YOUR ASSEMBLY"
 OutputPath="."
 >


Task Item to define a fileset
<ItemGroup>
 <Assemblies Include="**\*.dll" />
</ItemGroup>


<TaskSchema Assemblies="@(Assemblies)" OutputPath="." />

You can grab Peli's task (including source) from here...
    http://www.projectdistributor.net/Projects/Project.aspx?projectId=138


More about Task Items

The benefits of using a task item to define a fileset is that you can define multiple files but also that task items have metadata attached to them.  For example, if I create a task item which contains some file info, I can then use batching to reference the metadata about the items:

Batching (display a list of task items)

<ItemGroup>
    <MyItem Include="foo1.txt"/>
    <MyItem Include="foo2.txt"/>
</ItemGroup>
<Target Name="Display">
    <Exec Command="echo %(MyItem.Filename)"/>
</Target>

Displays:
foo1.txt
foo2.txt

So, from a task item you can use the %(...) syntax to access the pre-defined metadata information about the items.  Here's some reference links about this subject matter:


Task Items :
http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_build/html/d762eff4-c92a-4b5f-a944-1ca30aa22319.asp

Pre-defined metadata :
http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_fxgenref/html/b5e791b5-c68f-4978-ad8a-9247d03bb6c0.asp

Batching :
http://winfx.msdn.microsoft.com/library/en-us/dv_build/html/31e480f8-fe4d-4633-8c54-8ec498e2306d.asp?frame=true

Explanation of the Batching Algorithm :
http://channel9.msdn.com/wiki/default.aspx/MSBuild.BatchingAlgorithm

posted on 7/26/2005 11:59:03 PM ( 1 Comments )


BizTalk Nant script

This week I've been sitting in on the BizTalk Essentials training which is being run by Bill.  I've really enjoyed seeing BizTalk put through its paces and starting to gain a better understanding of the various ways to achieve results.

One of the cool things that Bill pointed out today was a Nant script which has a deployment target for BizTalk in it.  You can find information about it here:

    http://www.traceofthought.net/PermaLink,guid,2e018262-cc86-4830-bdc6-871dfb1af51e.aspx

posted on 7/26/2005 9:44:08 AM ( 1 Comments )


Rebuilding solutions with NAnt and building Flash Projects

This last week I was with a customer helping them to set up a continuous build environment and there were a couple of interesting things that I thought that I should put down in here for my future self...

One of the projects that the customer needed to build was a flash project.  The customer had already found a command-line compiler for flash movies which seems to work quite nicely.  The tool is mtasc.exe.  Basically we just kick off an ExecTask which builds the flash artefacts via the mtasc tool and end up with a .swf file which gets copied to a release folder. 

The other thing that I only just realised is that the SolutionTask in NAnt doesn't have a property that allows you to run the build as a clean build.  In other words, when you build using the SolutionTask you will only get new assembly files for projects which have changed since the last build.  This wasn't good enough for me as I wanted to use the actual version from the assemblies themselves to generate unique release folders - and obviously, if the assembly doesn't get re-built then I can hardly expect a new version number.  The answer was to clean out the previously compiled binaries from the bin and obj locations before building the solution.  There's a good example of this on Jeffrey Palermo's blog entry:

    http://codebetter.com/blogs/jeffrey.palermo/archive/2005/04/21/69788.aspx

This isn't a problem when the continuous builds are running on the build server because you don't ever add the bin and obj folders to source control but is a problem on the developers machine.  Mitch and I are both big fans of ensuring that the NAnt scripts can run from any environment, so this clean target is important in achieving that. 

Mitch and I usually add the .build file into the root folder for the project and also supply a build.bat file to encourage developers to run the NAnt script on their own machines.  Running the file from the local machine also greatly speeds up the development of NAnt scripts.

posted on 7/17/2005 7:40:25 AM ( 2 Comments )


Added Unit Tests to my SUB build

Today I wrote some NUnit tests for SingleUserBlog and added them to my build script to run as part of my continuous integration process.  It was interesting to see how much "factoring" I had to apply to my code to get it ready to work with NUnit. 

The main area that I had to change was a class that I'd been using to expose configuration data to the application.  It was basically a class with a static accessor for each config. value and it was simply reading them out of the config. file at runtime.  Unfortunately, when the application is running via NUnit it doesn't have the ASP context that it requires to read the values out of the config. file so my code was breaking. 

What I ended up doing was to implement the config. settings class as an interface so that I can switch it in with a special implementation containing a hard-coded set of values from my test harness.  So, when the code is being run from the web application I set it with a web implementation which contains the dynamic values like so:

     FileSystemBlogDataProvider.ConfigurationProvider = new ApplicationSettings() ;

... and, in my unit test harness I set it with the special unit testing version which contains static lookup values, like so:

     FileSystemBlogDataProvider.ConfigurationProvider = new TestApplicationSettings() ;

posted on 7/12/2005 11:30:00 AM ( 2 Comments )


Getting a [license] error when running the Solution task in NAnt

Today I was finalizing the setup of my continuous integration process for SingleUserBlog.  Being a web application I needed to set the webmap for the solution task so that it would know where to find the solution items when they were checked out from SVN:

    <solution configuration="Release" solutionfile="Src\MarkItUp.SingleUserBlog.sln">
        <webmap>
            <map url="
http://localhost/SingleUserBlogWeb/SingleUserBlogWeb.csproj"
                path="Src\SingleUserBlogWeb\SingleUserBlogWeb.csproj" />
        </webmap>
    </solution>

After setting that I ran the build script and received an error about some sort of problem with the license file for FreeTextBox.  It was complaining that it couldn't find the strongly named type.  On closer inspection I discovered that the type defined in my license file was actually wrong - I think that I still had the license file for version 3 of that product.

I updated the version string in the licx file to match the correct assembly version of my FreeTextBox dll and bingo, it worked.  Interesting that VS doesn't do this check when building the solution though!

posted on 7/12/2005 2:00:44 AM ( 0 Comments )


Getting Draco and SVN playing together

As I mentioned last week  I installed TortoiseSVN on my home network and managed to get all of my projects checked in and synch'd up on all of my machines.  Tonight I decided to install Draco and get continuous integration up and running too.  This is mostly so that I can practice various scenario's and have a way to practice writing NAnt build scripts, using NantContrib tasks and getting my NUnit tests to run.

It should have been a simple excercise tonight: install the Draco service, configure the client web application and away I go.  I set it up but kept getting an error in my Draco logs stating that "The system cannot find the file specified".  When I hooked the debugger to the service I discovered that it was choking when it was attempting the start the "svn.exe" process.  I checked my PATH variable and discovered that it was not there so, following Mitch's sound advice I downloaded SVN and installed it - thus ensuring that my PATH variable was updated and now pointed to the svn executable.

I ran the Draco job and sure enough it failed again!  This time I created my own console app. and copied the process arguments out and ran them for myself - it worked.  Hrmm.  So it runs when I run it from my console app yet it fails when I run it via Draco... what gives?

Sure enough, a quick IM to Grant got me thinking sensibly again and he twigged me to the fact that the user who was configured to run the Draco service probably didn't have svn in their path.  I quickly updated the service to use my own account and VOILA it worked.  Now that's 2 hours of my life that I'd like to have back :-)

For future reference, here's a link to the Draco Wiki: http://draconet.sourceforge.net/wiki/index.php/BeginnersGuide?action=BackLinks

 

posted on 7/11/2005 2:53:24 PM ( 1 Comments )