Continuous integration is a software development term describing the process that completely rebuilds and tests applications frequently. We recently implemented a continuous integration environment to “publish” our DotNetNuke modules to our development/staging DotNetNuke sites.
The main advantages of a continuous integration environment are:
- Issues are detected and fixed continuously!
- Enhancements and new features are published continuously!
- You are warned about problematic code before it is published.
- Immediate unit testing of all changes.
- Constant availability of a "current" build for testing, demos, or releases.
- Bragging rights for developers who have the least number of broken builds.
- Huge conservation of time when considering the normal administrative process of Build > Package > install in DNN > Test.
- Did I mention this is continuous?
How Our CI and DNN Environment Works
Below is a picture to show you the basics of how our continuous integration environment works.

Disclaimer:
- If you are running Visual Studio 2005 Web Developer Express, our setup will not work for you. You can stop reading here, or upgrade, unless you are just curious, then read on…
- There have been long discussion on Web Site Projects (WSP) versus Web Application Projects (WAP) and this post is not one to argue about which is better, rather than to say this is what we do, and the basics of how it works.
- You are free to comment and collaborate with others on this post. Feel free to even argue about WAP versus WEP, or that you may know of a way to integrate CI with DNN and WSP, we really do not care. However, we do not have time to walk you through setting any of this up, so please do not ask…unless you are interested in one of our DNN support packages, then by all means we can help

Basics of the process:
- A developer “commits” the DNN module code to Subversion.
- The commit triggers CruiseControl.Net to “build” the DNN module using a “Trigger” for the project.
- CruiseControl.Net can be configured to unit test the module before publishing.
- An “ExecutableTask” is used with our custom assembly publisher application to send the .DLL file to the DNN website.
- A “BuildPublisher” sends the code from the source directory to the DNN site (D:\DNNSites\ClientDevSite\DesktopModules\CustomDNNModule as example).
- Results of “build” are visible in the CruiseControl.Net Web Dashboard.
Implementing CI for DNN Development
Development:
We started DotNetnuke 4 development using the WSP methodology for all of our DNN projects. This has been successful for us for quite a while, especially when using EntitySpaces for the Persistence Layer and Business Objects (it's so easy using ES to generate the DAL. You must check this out if you are not using it). However, we found that to make this work we have to use WAP projects. I have a very fast laptop, but using WSP and doing a build of all of DNN to compile a module can be quite time consuming, taking several minutes sometimes. But, building a WAP project is FAST, saving some development time when debugging and testing builds, especially when doing those final little tweaks. One could argue that WSP is better, but for our setup with one to many developers working on a single module, WAP is the best decision. So, it did not take much to twist our arm to changing our methodology. It is unfortunate that in order to use this for our existing clients and projects, we will need to convert our WSP modules to WAP. But, we have started developing all new modules as WAPs and converting WSP modules to WAP is not a difficult task.
To read about the great WSP versus WAP debate, see the following links:
Shaun Walker’s post on WAP
http://www.dotnetnuke.com/Community/Blogs/tabid/825/EntryID/434/Default.aspx
An interesting debate between Michael Washington and Vladan Strigo
http://www.dotnetnuke.com/Projects/ModuleNews/Forums/tabid/953/forumid/111/threadid/91268/threadpage/6/scope/posts/Default.aspx
WAP Methodology
“Web Application Projects provide a companion web project model that can be used as an alternative to the built-in Web Site Project in Visual Studio 2005. This new model is ideal for web site developers who are converting a Visual Studio .Net 2003 web project to Visual Studio 2005. (Released May 8, 2006)” - http://msdn2.microsoft.com/en-us/asp.net/aa336618.aspx
Michael Washington has a great post on creating a DNN WAP Module:
http://www.adefwebserver.com/DotNetNukeHELP/DNN4_WAP/
Once the module is ready for testing on our client development site, we use TortoiseSVN to “commit” code to Subversion (http://tortoisesvn.tigris.org/).
Source Code Version Control:
We use Subversion for our source code repository and version control system (http://subversion.tigris.org/). We have tried Visual SourceSafe and CVS, but have been using Subversion with success for quite some time now. CruiseControl.Net integrates with Subversion easily. It is also nice that there is a plugin for Subversion that allows us to send our comments directly to Gemini (project management/tracking application) when we commit new code.
Continuous Integration Software:
We use CruiseControl.Net, a .Net port of the Java based CruiseControl
Continuous Integration Server using CruiseControl.Net
The CruiseControl.Net Server automates the integration process by monitoring the team's source control repository directly. Every time a developer commits a new set of modifications for the DNN module, the server will automatically launch an integration build to validate the changes. When the build is complete, the server notifies the developer whether the changes that they committed integrated successfully or not.
CruiseControl.Net allows for several different types of “Tasks”, such as:
- EmailPublisher (for emailing of build details)
- ExecutableTask (for kicking off executables, such as our custom assembly publisher)
- NAntTask (for unit testing)
- NUnitTask (for unit testing)
- RSSBuildsPublisher (for generating a RSS feed with details)
- VisualStudioTask (for running something in VS)
- Etc.
Here is an example ccnet.config:
<!--<ccnetconfig><configurationVersion>1.2.1</configurationVersion></ccnetconfig>-->
<cruisecontrol>
<project name="BPLWantList">
<workingDirectory>D:\cibuilds\ProjectName\ModuleName</workingDirectory>
<webURL>http://ourCIdomain.com/server/local/project/ModuleName/ViewProjectReport.aspx</webURL>
<sourcecontrol type="svn">
<trunkUrl>svn://localhost/ProjectName/ModuleName</trunkUrl>
</sourcecontrol>
<triggers>
<intervalTrigger name="Quarter Hour Build" seconds="900" />
</triggers>
<tasks>
<exec>
<executable>VenexusAssemblyPublisher.exe</executable>
<baseDirectory>D:\</baseDirectory>
<buildArgs>"d:\Source\ProjectName\DesktopModules\ModuleName\obj\Debug" "d:\DevSites\ProjectName\bin"</buildArgs>
</exec>
</tasks>
<publishers>
<buildpublisher>
<sourceDir>D:\cibuilds\ProjectName\ModuleName</sourceDir>
<publishDir>D:\DevSites\ProjectName\DesktopModules\ModuleName</publishDir>
<useLabelSubDirectory>false</useLabelSubDirectory>
</buildpublisher>
<xmllogger />
<statistics />
</publishers>
</project>
</cruisecontrol>
CruiseControl.Net Web Dashboard
The CruiseControl.Net Web Dashboard Application is used for reporting a wide range of information about the builds. At one end of the scale it reports summary details of all projects in your organisation and at the other it can give specific metric output for any specific build.
Here is an example of a simple DNN Module being used in our CI environment:

Notice the failed build notification. While we have not setup unit testing, you can see in the left menu in the image, there are quite a few different options.
Conclusion
For long term DotNetNuke module projects, setting up a continuous integration environment will save a tremendous amount of time in the long run. All of the tools to implement CI are free, lowering the total cost of DNN module development. With a little bit of time setting up your environment, you can provide continuous updates to your clients, all while forcing good coding practices among your developers.