Tuesday, December 01, 2009 by Per Ploug Hansen

Our first day of developement is all about getting project ready for the agile developement process. We don't want to worry about packing, file manifests or doing daily builds the next 24 days, so the first thing to do on this project is getting the infrastructure setup.

This will require:

  1. Source Code repository
  2. A build server
  3. A clean project structure containing all files
  4. A package manifest for installing the package on umbraco
  5. A nant script for putting the package together and automating manifests, zipping etc
  6. Som misc utillities for handling files in the package

Source code

Blog 4 umbraco is already on codeplex, so we will keep it there and modify the current project to fit our needs, source and issue tracker can be found on:
http://www.codeplex.com/blog4umbraco

Build server

We already use TeamCity for our Contour, Courier and Concierge build processes, it's easy to setup, has a fantastic UI and works fantasticly with nant and subversion, cannot recommend this enough. As there is alreay enough documentation out there on how to setup Team City, I won't spend more time on this, but it's awesome, your build process just works and you don't have to worry about anything. As we use Nant for building the code we can also test the entire build process locally, by running the nant scripts on the local developement machine.

Get TeamCity here: http://www.jetbrains.com/teamcity/

Project Structure

We put everything in our visual studio project to ensure it can build anywhere, so it will contain our nant script and package manifest files for easy editing. For the project files themselves we've setup this simple structure:

  • Solution items
    contains nant script, package manifes and utillities
  • Css
    All css files for the presentation
  • EventHandlers
    Classes that hook into the eventmodel
  • Images
    images for the presentation
  • Library
    The Blog xslt extension
  • Scripts
    javascript files
  • Templates
    Master template files
  • UserControls
    usercontrols for macros
  • Xslt
    xslt files for macros

Everything is now in source control so our build server can fetch it every night and put together a nice package and hotfix

Package Manifest

The package manifest is the part of the project that tells umbraco how the different items should be installed it contains refences to all files, templates, macros, css etc. Normally package files are created in the umbraco backend by using the package located in the developer section. However, we need to have the package file updated every night, and don't want to spend time on this. So instead we will generate a very basic package manifest, using the umbraco packager, which includes all document types, template references and other items that are unlikely to change. This basic package manifest will then be updated on every build to keep it uptodate.

For this project we installed the current blog package and then generated a new package containing all templates, document types, stylessheets, macros etc. and added its manifest to the visual studio solution.

Nant scripting

Nant is a automated build tool, which performs tasks in a build script (wikipedia). But it does so much more then building source code. In this project I've setup nant to perform the following tasks (so I don't have to)

  1. Build the source code
  2. Move files from the project into a package folder
  3. Modify the package.xml manifest with the list of current files
  4. Add template markup to the package manifest from the template files in the project
  5. Add stylesheets to the package manifest
  6. update the version number
  7. Zip the files as a package with a manifest
  8. Zip files as a hotfix to make it easy to update current installations
  9. publish the files on nightly.umbraco.org
  10. Clean up

I've setup a nant project a couple of times now, and making nant perform the above tasks took about 40 minuts to do. So how do you setup Nant to do these things, download the source from codeplex and view the nant.build file and go through the below chapters:

You need to have nant installed on your developement machine to be able to use nant. It can be downloaded and installed from here: http://nant.sourceforge.net/release/0.85/help/introduction/installation.html

To run the nant script, open cmd.exe, browse to the blog4umbraco directory and write the command "nant" hit enter and it will execute the .build file.

Nant script structure

The script is divided into different targets (<target> elements)

  • Compile
  • Movefiles
  • Manifest
  • Zip
  • Publish

These targets handle a different part of the process. You can execute all targets by call the command "nant" or just some of them by calling the comman "nant <name of target>" (ex: "nant manifest"). Each target depends on another target which ensures that everything is done in the right order.

 

Using nant to build your project

The first thing we need to do is compiling the source code. We use the Msbuild.exe which is included in the .net framework. msbuild is alot more picky about building visual solutions and forces you to clean up missing files, wrong page declarations etc. To make nant perform the build we call the msbuild.exe file directly and tell it to build out solution:

<exec program="${msbuild.app}" basedir="${root.dir}">
      <arg value="UmLaut.Umb.Blog.sln" />
      <arg value="/p:Configuration=Debug"/>
      <arg value="/p:Platform=&quot;Any CPU&quot;"/>
    </exec>

Adding template markup to the package manifest

We keep our templates as files in the project, but to install them, we need to move the markup to the package manifest, this is done by executing a nant task called loadfile and then xmlpoke:

<loadfile file="${core.dir}\templates\Blog.master" property="blog.master" />
<xmlpoke file="${zip.dir}\package.xml" xpath="/umbPackage/Templates/Template [Alias = 'Blog']/Design" value="&lt;![CDATA[${blog.master}]]&gt;" />

We load the template file into a property, and then inject the contents of that file into the package manifest. The xpath tells xmlpoke where to place the value ${blog.master} which is the contents of the file. We use the same technique for all the templates and for the stylesheets as well.

Gathering files for the package and zipping them

For our package we need to gather all the files umbraco needs for the installation and tell umbraco what path to place them on. For this we create a temporary folder and copy the needed files. We place them in the right structure as well. We use simple nant tasks to copy these files and make new directories

    <!-- Images -->
    <mkdir dir="${package.dir}\images" />
    <copy todir="${package.dir}\images" includeemptydirs="true" flatten="false" failonerror="false" overwrite="true">
      <fileset basedir="${core.dir}\images">
        <include name="*.*" />
      </fileset>
    </copy>

    <!-- Usercontrols -->
    <mkdir dir="${package.dir}\usercontrols\${dist.name}" />
    <copy todir="${package.dir}\usercontrols\${dist.name}" includeemptydirs="true" flatten="false" failonerror="false" overwrite="true">
      <fileset basedir="${core.dir}\usercontrols">
        <include name="*.ascx" />
      </fileset>
    </copy>

When we have the files collected in the folder, we execute a small utillity which registers all files in the package.xml manifest and moves them to the folder they will be zipped in. The current package format requires that all files are located in the root of the zipped folder so we also rename all files to a guid to ensure that nothing is overwritten. The utillity "AddFilesTopackages.exe" takes care of this as well (included in the blog 4 umbraco project)

    <!-- here we will append files in the package directory to the package file-->
    <!-- arguments: package.xml manifest, folder with files in correct structure, folder to send to for zipping-->
    <exec program="${root.dir}\AddFilesToPackage.exe">
      <arg value="${package.dir}\package.xml" />
      <arg value="${package.dir}" />
      <arg value="${zip.dir}" />
    </exec>

Finally we will zip everything into 2 packages, one is the installable umbraco package with all files located in the root of the folder, the other a hotfix release with all files named and located correctly so it's easy to xcopy to an existing installation.

     <!-- Zip everything -->
    <zip zipfile="${root.dir}\package.zip" includeemptydirs="true" >
      <fileset basedir="${zip.dir}">
        <include name="*" />
        <include name="**/*" />
      </fileset>
    </zip>

    <!-- Zip hotfix -->
    <zip zipfile="${root.dir}\hotfix.zip" includeemptydirs="true" >
      <fileset basedir="${package.dir}">
        <include name="*" />
        <include name="**/*" />
        <exclude name="package.xml" />
      </fileset>
    </zip>

These are all small snippets of the build script. I recommend you open up the nant.build file and investegate it further, it is a fantastic tool for automating anything and for handling the tedious task of maintaining a package manifest it is a real time-saver.

Moving forward

With nant, codeplex and teamcity in place, we are now ready to start adding features, we don't have to worry about spending time on releasing packages and can move forward much faster.

Nightly builds will be available on http://nightly.umbraco.org/Blog4Umbraco/ both as installable package and a hotfix.

The source code is on codeplex: http://blog4umbraco.codeplex.com/ where you can also add suggestions, snippets and post bugs

Tutorials on nant can be found here http://nant.sourceforge.net/release/latest/help/introduction/ and here http://blog.jpboodhoo.com/NAntStarterSeries.aspx for those who want to learn more.

 

End of the first chapter of the umbraco christmas calendar! I promise the next chapters will not be this long or filled with nant tasks xml.

7 comment(s) for “Blog 4 Umbraco 2.0.1 – Setting up the project”

  1. Gravatar ImageTim Says:

    wicked, thanks Per..... will be keeping a close eye on the nightlies.

  2. Gravatar ImageWarren Buckley Says:

    Hiya Per,
    A great first day post on the Blog 4 Umbraco Xmas Project.

    Never heard of nant before and sounds very useful, especially for building packages.

    I may try and play with it for the CWS package to automate builds etc...

    Warren :)

  3. Gravatar ImageRichard Says:

    Hi Per,

    Don't know what I like more, the blog or these tutorials :-)

    Thanks,

    Richard

  4. Gravatar ImageAndy Rose Says:

    Great post Per. It's good to see a CI tutorial based on an actual working project. Very handy for anyone thinking of adopting this kind of development practice.

  5. Gravatar ImageLee Kelleher Says:

    Good post Per! Great to have some insight to how you guys work, from the project structure to how you use NAnt!

    Looking forward to the upcoming posts and progress!

    Cheers, Lee.

  6. Gravatar ImageLee Says:

    This is great... Slightly over my head, but it's awesome stuff! If only I could do a weeks work experience in the Umbraco office to learn quicker ;)

  7. Gravatar ImageRoel Says:

    Keep them coming! Love to see more posts like these. Thnx.

Leave comment:


Brilliant umbraco hosting provided by FAB-IT