Since Team Foundation Server 2010 came out, I’ve been wanting to set up a continuous integration environment, particularly for two public websites that have sat for a LONG time. I’d like to do something different with both of them, and re-write them in MVC this time. They are robertseder.com and sedersoftware.com
So, I’ve been using TFS for a while, and installed CruiseControl.net a few weeks ago. First, let me get my complaining over with:
CruiseControl.NET and Open Source:
<rant inflamatoryLevel="medium"> This is a pretty perfect example of the reason why I so strongly dislike open-source. It’s because I’m a “professional developer” and I have “certain standards” of where I think “production” code should be. I think an application should be written so that it is robust, and gracefully fails, or even better – doesn’t fail that often. I’ve often said “there’s a big difference between writing a program, and releasing a product”.
Converse to that thinking, it would seem that open source projects are filled with developers of widely varying skill-sets, that all have the best-intentions. I can’t fault them for that. However, the resultant “product” is often far from acceptable. CruiseControl.NET is “mostly” acceptable, in my opinion, in that it runs if everything is perfect. However, if there is a problem in the config file for example, the whole Windows Service bombs, and you have to hunt down the problem in the event viewer. By the way, I didn’t see that written anywhere, I just eventually figured that out. Put another way, open source seems to always be “good enough” software in the loosest sense, in that it “mostly runs, for most common scenarios”. I guess for most people, that is OK – but for me, it’s not really. But, since it is free – I am “getting what I’m paying for” – and it does do the job. So unless/until I either buy a real product, or write a better one, I’ll shut up about it going forward. If you need more reasons to not like open source, go watch Richard Stallman for a while, this is his doctrine after all.</rant>
OK – with that said, assuming you have products that work, how do you go about setting up continuous integration – like, in theory? Well, after looking at what TFS can do, and then seeing what CCNET can do, I came up with a loose plan. First, here are the capabilities, as far as I can tell:
TFS build capabilities:
- You can have TFS build when all files are checked in, rolling builds, gated check-ins, or on a schedule (day and time)
- The build runs on the TFS machine and you can specify a single output directory. It also includes e-mail notification too, if you’d like.
- You can pretty much do anything – trigger by monitoring a folder, trigger by monitoring TFS (doesn’t support TFS2010 though), etc.
- You can run msbuild, run executables, merge files, publish the results of the build, etc. There are plugins for many products, or you if you can run it from the command-line, you can have CCNET run it.
So, I started from what I wanted, which is:
- Builds to the automatic, when everything is checked in.
- MSTest unit tests get run, if failure, then abort.
- FxCop gets run, if failure, then abort.
- StyleCop gets run, if failure, then abort.
- Do a build for dev, if successful – migrate to dev web server.
- Do a build for qa, if successful – migrate to qa web server.
- Do a build for production, if successful – ftp to the www server.
I explicitly want to do a build for each environment, because I want to make sure the config file is valid, and doesn’t break the build. Also, I want the non-debug version of the .dll’s to get deployed too. So this will take a little time, but I’m OK with that. So basically, I want to make a change to a site, and when I check in the last file – I want the build and deployment to be automatic, so long as there are no errors or problems.
If I take what I wanted, and overlay that on the capabilities of these products, here’s basically what I came up with:
- Do a “Continuous Integration” build with TFS.
- Have CCNET monitor the binDev directory for changes (I use custom configuration management with scripts that copy the right file, based on the configuration)
- CCNET does the following:
- MSBuild: Dev
- MSBuild: StyleCop-only (StyleCop doesn’t have an .exe)
- Exec: FxCop
- Exec: MSTest
- MSBuild: QA
- MSBuild: Prod
- If successful, then CCNET runs publishers:
- Deploy to Dev
- Deploy to QA
- Deploy to WWW
Now, I don’t know if this is the right way to do this, and I’m also not sure I like this. It would seem it would be ideal to have dev run a build + fxcop + stylecop + unit tests (so I can see results on the web portal), if that’s successful, then it kicks off QA and deploys, then kicks off production build, and deploys that. Although, I’m not quite sure how to do that elegantly, with CCNET. I’ll continue to mess with it – meanwhile, if you have any thoughts or opinions, shoot me an e-mail or leave a comment…