Sunday, April 26, 2009

Richmond Code Camp Recap

Ok, so this can’t be a full blown recap of the Code Camp.  I wasn’t able to stick around the whole day.  My wife and I celebrated our 6th anniversary this weekend.  So there was no way I could get by with spending the whole Saturday at a technical conference.  However, I really enjoyed the time I spent there.  It was a great environment, and I thought the organizers did a great job.

I presented a talk titled “Continuous Integration or:  How I Learned to Stop Worrying and Love the Build”.  I felt like it was fairly well attended and well received by those that were there.  I’m pretty new to presenting, so I think it went about as well as I could have expected.  The main glitch was the resolution of my screen vs. the resolution of the projector.  I didn’t realize the projector was cutting off my slides until about halfway in.  Instead of fixing it, I tried to keep driving forward.  I think it would have gone better if I had taken the minute or two to fix the discrepancy.

Anyway, I felt like I had a great audience and really enjoyed their participation.  Also, I felt like I did get the point across that Hudson rocks.  Hudson is a great tool to present Continuous Integration as an accessible practice.  I mean, I can spin it up from scratch and have new projects running in a matter of a few minutes.  I wouldn’t even dream of doing that with other CI tools in a live demo in front of a crowd.

So, with the success of this weekend, I’m going to take this talk to some other venues.  Next up, I’m penciled in to present this at May’s Richmond Java User’s Group.  I’ll have to rework some of the demo to translate the .NET project and tools to the Java platform.  I love the fact that I’m able to use the same talk for audiences from different platforms and languages.

This is really exciting for me.  For the last year and a half, I have had two major career goals.  First, to be equally proficient between the .NET and Java platforms.  Second, start presenting at user groups and conferences.  This is great because I am knocking both out at the same time.

Friday, March 27, 2009

Getting Started with Rake on .NET Projects

I attended Developer Day in Durham last weekend, and had a blast.  The event was very much Ruby-centric, which is a little out of my comfort zone.  However, there were plenty of things that I’m bringing back to my day job on .NET and Java projects.


The first two things I resolved myself to do:  1)write less XML, and 2) try to incorporate scripting languages (starting with Ruby) into my routine tasks.  This led me to Rake.  Rake helps me accomplish both goals at one time.  I get to stop writing XML for my build scripts, and use Ruby to build my projects.


There are a lot of blog posts on Rake and even some on Rake with .NET.  However, I didn’t find one that got me running build scripts in Rake from scratch.  I’m focused on the simplest case for .NET.  If you want more general Rake information, go to Martin Fowler’s article.  If you want a more complete (and very entertaining) tutorial, check out the Rails Envy site.

So here it goes…


1. Get Ruby

I’m on a windows machine, so I used the One Click Installer.  I ran the installer, re-booted my machine, and was good to go with Ruby (Rake is delivered as part of the Ruby install).


2. Find a Project that Needs Building

I set up a very simple solution that has two class libraries (DoStuffInDotNet and TestStuffInDotNet).  One has a single class with limited functionality.  The other has a single NUnit test.  I have also included a tools folder, which contains the NUnit test framework.


SolutionImage


3.  Create a Rake File

I created a file called rakefile.rb.  I’ll break down each part of the file below.

The first line sets up the default task.  In this case, it is calling the build task.  So, from this folder, “build” executes by simply typing in “rake”.

task :default => :build


The next line shows that “build” is  a composite task that is comprised of the “clean”, “compile”, and “test” tasks.



task :build => [:clean, :compile, :test]


The “clean” task is just calling Ruby’s FileUtils class to remove the contents of the “build” folder.



task :clean do
FileUtils.rm_rf(
"build")
end


The “compile” task calls MSBuild to execute on the solution under the AutomatedDebug configuration.  AutomatedDebug is a setting I created in Visual Studio’s Configuration Manager.  The only difference between this and the default Debug configuration is that my output path is set to “..\..\build\Debug\”.  This will put the output of the rake build into the “DoStuffInDotNet\build” folder.



task :compile do
params = '/t:Rebuild /nologo /v:m /p:Configuration=AutomatedDebug src\DoStuffInDotNet.sln'
msbuid
= 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\MSBuild.exe'
sh
"#{msbuid} #{params}"
end


The final task is “test”.  Rake uses the current execution directory as its working directory, so I am using FileUtils to change the working directory to the “build\Debug” folder.  Then I execute NUnit against the test dll.



task :test do
FileUtils.cd
'build\\Debug'
exec
"..\\..\\tools\\nunit\\nunit-console.exe TestStuffInDotNet.dll"
end


From the cmd window, you can just run the command “rake” from the directory that contains rakefile.rb.



image



In effort of completeness, below is the full code in rakefile.rb.  Like I’ve stated early, this is a stupidly simple example.  However, I hope that it can help you get started if you are looking to start from ground zero.



task :default => :build

task :build
=> [:clean, :compile, :test]

task :clean
do
FileUtils.rm_rf(
"build")
end

task :compile
do
params = '/t:Rebuild /nologo /v:m /p:Configuration=AutomatedDebug src\DoStuffInDotNet.sln'
msbuid
= 'C:\\WINDOWS\\Microsoft.NET\\Framework\\v3.5\\MSBuild.exe'
sh
"#{msbuid} #{params}"
end

task :test
do
FileUtils.cd
'build\\Debug'
exec
"..\\..\\tools\\nunit\\nunit-console.exe TestStuffInDotNet.dll"
end

Thursday, March 12, 2009

How to make your code last: call it a temporary solution

Throughout my career, I have found several common themes that appear over and over again.  One of them popped up again recently: If you say you are going to develop a temporary solution and clean it up later, you never will.  It’s not always a matter of laziness (although, at times, it is), the odds are very high that an obstacle will get in our way later.

I was writing a demo Web Part project last week in order to demonstrate how SharePoint projects can use Continuous Integration.  The project itself was not the focus of the talk, I just wanted to demonstrate how CI works. 

Although the content of the solution was not significant to my original theme, it caught my audience’s attention.  Once we got through the discussion of CI, they were very interested in the approach I took and how I was deploying the Web Parts.  It turns out that they were having problems building and deploying Web Parts themselves.

Fortunately, I learned my lesson long ago that all code I demo or commit to source control should be thought out.  I could have cut a lot of corners when building this project, but I didn’t.  I’m not saying that I write perfect, bug-free software, I just attempt to do a good job as a professional. To quote the Manifesto for Software Craftsmanship I’ve come to value “Not only working software, but also well-crafted software.”

When the presentation was over, the client wanted my code and build scripts.  They are still interested in CI, but my sample code and build scripts solved the exact problems they were having at that time.  Now this is a lucky situation where my little demo app solved a problem for a client that I didn’t know they had.  But think if I had taken short cuts or allowed myself to get sloppy.  I would have had to spend the next day or week rewriting the project before I handed it over to them.  Or I would have lost credibility with them because my code could have been short cutting around their problem.

In the end, my code and/or its build script may be the building blocks for the client’s own Web Parts and projects.  So this seemingly inconsequential application may become the foundation for future code.  They may not use the code itself in the future, but there is power there because it helps form the clients initial understanding of Web Part development.  How about that?  If I had done a sloppy job, that means their initial understanding would be … well… sloppy, or even worse, incorrect.

Wednesday, February 25, 2009

Hudson for .NET Projects

I’ve been working on some SharePoint projects recently, and I wanted to implement Continuous Integration(CI).  Unfortunately, I did not find much information when I was researching CI for SharePoint projects.  My company traditionally uses CruiseControl.NET for its standard .NET projects; however, CC.NET seemed to require a good bit of configuration to get started.  I was looking for something I could spin up rather quickly.  I had heard Java folks raving about Hudson's ease of use out of the box, so I wanted to see if the same held true for .NET and SharePoint projects.  I was amazed at how simple it was.

Since I didn’t see many people in the blogosphere talking about Hudson with .NET (and even fewer talking about Hudson with SharePoint).  I thought I would give a very basic tutorial on the .NET set-up for Hudson.  NOTE: Hudson is a Java .war file, so it requires Java 1.5 or later to be on the machine.

Step One – Download Hudson from https://hudson.dev.java.net/

Step Two – If Hudson downloaded as a .zip file, rename it to Hudson.war

Step Three – Run Hudson from the command line, by executing the following line:

java –jar hudson.war

Step Four – Now that Hudson is running, pull it up in the browser.  By default, it will be running at http://localhost:8080/

Step Five – Hudson does a lot of things out of the box, mostly centered around Java tools.  So to get .NET projects up and running, we’re going to need to download some plugins.  Hudson makes this incredibly easy.  From the home page, click on the “Manage Hudson” link.  Then, on the manage screen, click on the “Manage Plugins” link.

On the Manage Plugins page, select the "Available" tab and select the tools required for your build.  As you can see in the screenshot below, there are plugins for MSBuild and MSTest, but I have selected NAnt and NUnit as my tools of choice.  There is a TFS plugin, but I haven’t used it yet.  I am currently using Subversion on my projects

HudsonPlugins

Once the plugins have been installed, you’ll need to restart Hudson. 

Step Six – From the home page, click on the “Manage Hudson” link.  Then click on the “Configure System” link.  This screen will allow you to configure the email server and the default Nant installation.  

 HudsonConfigureNantEmail

Now you’re set for adding projects.  And now for the easy part…

Step Seven – Add a new job.  Click on the “New Job” link to start the wizard for adding new jobs.  Enter a name for the job and make sure you have selected “Build a free-style software project”

HudsonAddJob

The next page of the wizard allows you to set up the details of the job (where to pull the code from, how to trigger the build, which build scripts to execute,  how to publish results, and who should receive email notifications).  Note: I did find a limitation when working with NAnt build scripts.  A job will only execute one NAnt script.  This isn’t too bad of a limitation, you will just need to aggregate some targets in a single target of your build file.

HudsonConfigureJob

Conclusion

Comparing this with other CI tools I’ve used in the past, Hudson is the easiest and has the fewest limitations.  I have used tools that required heavy custom xml configuration, had severe limitations (would not poll source control for changes), or were only built for one platform.  Hudson walks you through all necessary configuration on its UI, without being a hindrance to getting things done.  It is very flexible in what it can do, and has amazing support with a variety of plugins.  Finally, it is not just set up for one platform.  Although it requires Java to execute, there is support for a variety of platforms and languages.

Thursday, February 5, 2009

Continuous Integration: Should we always use it?

I had a conversation with a friend last week that got me thinking a lot about Continuous Integration.  I was explaining, with pride, that I had configured Hudson to build, run unit tests, and deploy SharePoint web parts for my current project.  His response went something like this... "Yeah, Continuous Integration is ok, but it's not really for everything."  His tone showed that he thought its place was in the minority of projects.

That really surprised me.  In 2009, should we be skeptical over the use of Continuous Integration?  Has the case for it not already been made?  This statement was from someone with a similar background to mine, so I was left wondering if I was missing something.

Certainly, there must be a case where we don't need Continuous Integration.  Maybe if you are the only developer on a project and you can build everything yourself.  Wait a minute!  That basically describes my current project!  I am the only person building web parts.  I really value the security of having my code built, tested, and deployed in a an automated fashion on a machine other than my own.  This at least gets me out of the "well, it worked on my machine" excuse.  I also like the fact that Hudson provides a complete history of past builds.

Were there other possible reasons to not use Continuous Integration.  Maybe there is a Return on Investment argument that could be made.  If the amount of effort exceeds the benefits produced, maybe it's not worth the work.  I can immediately see a few holes in this argument.  A tool like Hudson makes the effort invested negligible.  As long as you can script whatever you want to run in CI, Hudson lets you just plug it right in.  If scripting your build and deployment is so expensive that CI isn't worth it, you're probably looking at a symptom of other problems on your project.

In all my reading on Continuous Integration, I don't think I've come across arguments that were just simply against it.  I have seen some arguments that it is part of an evolution, and it does not quite solve all of our problems in its current form.  However, that is more of an argument that we haven't taken it far enough yet.  That's not an argument against using it at all.

So, basically, my conclusion is that Continuous Integration has a place on any professional software development project.  The tools available make the price of entry fairly low.  The benefits by far outweigh the cost of implementing CI.  I didn't really intend for this entry to detail all of the benefits.  This topic has been well articulated in several books, papers, and and many other blog entries.  If you want further reading on the topic, start with Martin Fowler's article.  Books available include Pragmatic Project Automation and Continuous Integration: Improving Software Quality and Reducing Risk.  In the end, I believe its the job of any responsible software developer to ensure their projects take advantage of the benefits of CI.