Expert Delivery Using NAnt and CruiseControl.NET 109
Expert .NET Delivery Using NAnt and CruseControl.NET | |
author | Marc Holmes |
pages | 400 |
publisher | Apress |
rating | 10 |
reviewer | Jim Holmes |
ISBN | 1590594851 |
summary | Automate your .NET software build and delivery process |
Disclaimer: I got this book free as a giveaway for our .NET Developers Group. Some folks might think this could influence my opinion, but they'd be wrong. Also, Marc Holmes is in no way related to me. (Well, we're both humans inhabiting the Earth, descended from Adam and Eve or the same biological soup depending on your beliefs, so I suppose that's not completely true.)
Note: To avoid possible confusion due to our same last names, through the review I'm going to refer to the author as "Marc ," not "Holmes."
I got this book because I'm an independent software geek who loves having automated, repeatable processes. I don't have a QA department to double-check every drop I send to customers, nor do I have a separate process department to run checklists every time I need to gather up some statistics on testing, code complexity, etc. I need all these sorts of tasks wrapped up into stable, repeatable, automated processes so that I don't have to constantly worry whether I've forgotten something. (Worse yet, I work from home while taking care of two young children. Automated processes let me focus my meager remaining concentration on software construction while having stuffed animals tossed on my keyboard and drums bashed behind my work chair.) I've had a solid background in Ant and NAnt, but wanted real-world detail on how to generate an end-to-end process for continuous integration and delivery.
This book is part of Apress' "Expert" series which includes books on Oracle, .NET development, web services, and Network Time Protocol. (And who among us hasn't frequently needed an expert book on NTP when we're trying to remember some details of symmetric passive mode?)
Two mantras run centrally through this book: Marc's quip "Design for Delivery," and the importance of standards-based processes. It's not enough to cobble together an automated system which may get one from end-to-end. A team needs a system which gets software built, tested, reported, and packaged in a form read to drop into a customer's environment. Having the mindset of "Design for Delivery" helps focus the team on meeting the goal of getting their software out the door in best fashion. Approaching an automated build system with a thought to standardization means that the team shoots for systems applicable to many projects. Each new project's solution shouldn't require a large amount of rework to get the build/deploy system up and running. Marc is emphatic about this throughout the book, constantly refactoring build and deploy scripts to keep them as abstract as possible.
Marc approaches the task of creating an automated delivery process with the same mindset of designing software: a few use cases with expected outcomes which are used as guidelines for building up the various scripts needed to get delivery tasks done, standards for wider implementations are considered, then the scripts themselves are built in an iterative fashion.
This book isn't a fluff-filled overview of tools. Marc dives down deep into the guts of several very useful tools, showing readers how to solve tough, real-world problems. Simplistic build and deployment systems which do nothing more than run a compiler and zip the resulting output are, well, simple to build.
Theory and details of how a tool (or tools) might be used are fine, but then reality in implementation hits. Marc matter-of-factly states that his approach to a delivery system may not work for everyone. Many of the tools he demonstrates offer multiple approaches to solving problems, such as NAnt's ability to use different build files via inclusion or as separate targets. Marc almost always discusses these options and discusses the rationale for his selection.
Marc also includes some great "Further Reading" sections at the end of most chapters. He points readers to some terrific additional reading such as McConnell's Code Complete, 2nd ed., Ambler's Agile Database Techniques: Effective Strategies for the Agile Software Developer, and Newkirk's Test Driven Development in Microsoft .NET.
The book's flow is very sensible and straightforward. Marc opens with a good discussion on creating a delivery system, then moves on in chapter two to a example of one company's project which he carries through the entire book. The example project is expanded during subsequent chapters as Marc builds up the build and deployment scripts as he covers that chapter's topic. I found this particularly useful since it's a great guide to building one's own automated system. It's easier to follow one example through an evolutionary process rather than having different examples thrown out piecemeal.
The book's laid out in ten chapters plus two appendices. After the first chapter's introduction, each chapter covers one key concept in the build system. Chapter ten closes out the book with "Closing Thoughts."
Chapter 1, "A Context for Delivery," lays out Marc's ideas on why automated, standardized build systems are so critical. Marc doesn't waste time detailing examples of train wrecks due to bad delivery processes. He has a short blurb on the business benefits of automation, then gives an overview of his example company, Etomic, and its products.
Marc continues by discussing potential processes for delivery, covering potential problem issues with each option, laying out his case for standardization and automation in the delivery cycle. Readers who are looking for rescue from a chaotic build and delivery process should hopefully have an epiphany moment or two in this section. So may readers who already have some process in place.
Chapter 2, "Dissecting NAnt," gives an introduction to NAnt and discusses its basic features. The ubiquitous "Hello, World" example is used, then the chapter moves on to discuss the details of creating build files, and variations for invoking NAnt from the command line. There's some good detail on using loggers to generate and merge output from NAnt into an XML log file, important for tracking exact execution details. NAnt's all-important properties, configuration file options for controlling NAnt's execution, are also covered in good detail.
Marc finishes the chapter by creating a skeleton build file for the fictitious Etomic corporation. This skeleton is expanded upon in following chapters as Marc discusses other tools and processes.
Chapter 3, "Important NAnt Tasks," is where Marc gets into the weeds of NAnt's execution. NAnt tasks are chunks of functionality contained in NAnt's libraries. Tasks give NAnt users support for things like interfacing to CVS for source code control, calling NDoc to create documentation from XML comment files, and reading values from the Windows registry. Marc selects several groups of tasks to cover, including conditional tasks for controlling build flow (if, ifnot, fail, e.g.), file management (attrib, copy, mkdir, get), and the fundamental build tasks (asminfo, exec, mkiisdir, solution, csc).
Marc also introduces NAnt-contrib, a second library of tasks written by other NAnt community developers. These tasks, which haven't yet made it into NAnt's framework, provide critical, additional functionality such as interfacing to Visual Source Safe for configuration management.
While he details important tasks in clear fashion, Marc makes it clear that his book is not a reference for the tools he covers. He emphatically points users to the tools' sites for more current and detailed information.
Marc carries this theme throughout the book: he focuses on what's necessary to get the job done, briefly describes potential enhancements or other possibilities, then points the reader to sources for more information.
Chapter 4, "A Simple Case Study," finally gets to the "real world" implementation. Marc begins to fill in the skeleton developed in Chapter 3 with tasks for testing via NUnit, documentation via NDoc, and error handling via NAnt's 'nant.onfailure' property which points the build process to an error-handling task.
Versioning software during a build can be difficult, but Marc has a section in this chapter devoted to handling versioning. He also shows opportunities for refactoring the build file from its klunky initial form to something less brittle and more easily extended. He also leaves the build file behind to begin development of a separate deployment script. He admits his initial deployment script is overly simple and suitable only for basic Windows applications; however, he continues to enhance and expand the deployment script as the book progresses.
Chapter 5, "Process Standards ," seems misnamed to me. Marc does spend some time discussing naming conventions and source control organization at the start of the chapter; however, most of this short chapter centers on refactoring the single build file into separate chunks.
Additionally, he covers a more complex build and deployment example with a custom-written Visual Source Safe Manager component which utilizes COM interoperability and is installed as a Windows service. Both these features are some of the more complex issues one might tackle in real-world deployments, so Marc's text here is very useful.
A semi-hidden gem in this chapter is Marc's discussion of a tip for getting around the less-than-helpful structure of a Web application in Visual Studio .NET 2003. Microsoft forces developers to hack up virtual links to an IIS server's web publishing folder, then scatters Web Application files between the .NET solution's directory and the web folder. This causes great difficulty when trying to use NAnt to build and deploy web apps. Marc points readers to Fritz Onion's wiki site where a clearly explained procedure for changing VS.NET's web application behavior awaits.
Chapter 6, "Continuous Integration ," pulls CruiseControl.NET (CC.NET) into the picture. Marc starts the chapter with great discussion on the benefits of Continuous Integration (CI), then begins detailing the tools. Marc chooses CC.NET, but he also gives a short bit of coverage to two options, Draco.NET and Hippo.NET. His "Further Reading" section for this chapter also points out other options.
Marc's coverage of CC.NET is much as his coverage of NAnt: targeted, detailed discussion of the features needed only to implement his build and deployment system. He writes about the Web Dashboard and the useful cctray applications, then moves to basic configuration and setting up the server. There's brief but adequate coverage given to configuring triggers, source control integration, and publishers, plus Marc points out what changes are needed for the NAnt build scripts. Marc closes the chapter with summary screens and output from CC.NET runs, then mentions how CC.NET is easily extendable if one needs additional functionality - providing a good transition to the next chapter.
Chapter 7, "Extending NAnt" is a great tutorial on how to write your own tasks to cover jobs not in NAnt or NAnt-contrib's libraries. Marc uses 'mkdir', 'copy', 'version', and 'exec' to help readers learn the basics of writing their own tasks in NAnt. He discusses NAnt attributes, crucial to NAnt's framework, then moves to how individual tasks interact with the master build file for capturing events, reading properties, etc.
Marc's first example of extending NAnt to incorporate FxCop is educational, but has been overcome by events: FxCop support is included in NAnt-contrib version 0.85rc3. Regardless, it's very useful to see how simple it is to write one's own task in NAnt.
Chapter 8, "Database Integration" is by far the longest and intricate chapter. Right off the bat Marc lists some of the hardest problems to solve when integrating databases into a build system: lack of source control, the amount of detail one must pay attention to, and how to deal with data in the database itself.
Marc puts forth examples of shared and local database development, then moves on to build/deploy tasks involved in integrating databases. He also covers how these tasks thread into the continuous integration process. Next he covers modifying the build and deploy scripts to integrate the database tasks.
The brunt of chapter 8 revolves around wrapping Red Gate's SQL Bundle, a commercial tool package, into the processes. Marc shows how Red Gate's tools enable the process to automatically detect database schema changes, create merge or update files, and compare database instances. This chapter alone might make the book worth its price if readers are involved with any projects needing substantial database development.
Chapter 9, "Code Generation," makes use of CodeSmith, a code generation package in both freeware and commercial formats. Marc espouses code generation as a way to alleviate problems in complex build environments.
Specifically, Marc identifies three troublesome topics: separation of concern (intertwining of process and configuration information), specific system steps (unavoidable hard-wiring in of file names for NDoc's documentation, for example), and administration overhead (the work required to keep the build/deploy systems operational or portable to new projects).
Marc's use of CodeSmith demonstrates how code generation can solve these problems and wrap directly into the build process. He uses short, clear examples on how to tie CodeSmith into both NAnt and CruiseControl.NET.
Chapter 10, "Closing Thoughts," is Marc's summary. It's a walkthrough of the territory the book just covered, laying out the material in brief form. Context, motivation, mechanics, consequences (pros/cons), and results all get concise summaries. The author also lays out a very useful Best Practices list for processes, standards, NAnt, CruiseControl.NET, and other factors. He also spends a very few paragraphs on the direction Microsoft is taking with their upcoming Build Server and its potential impact on the NAnt community.
The mechanics and format of this book are terrific for the most part. The author's writing style is clear, easy-going, and humorous without being campy. The index appears to be very complete and covered the few things I needed to reference.
On the negative side, a few of the screenshots weren't framed or cropped very well, leaving me looking for a magnifying glass to try to figure out bits the author referenced in his text. However, this was the case with only a few graphics. Most were very clear and viewable.
Additionally, the versions of tools covered in this book are somewhat outdated, but the author makes that very clear in several places through the book. All his examples work for the versions referenced in the book. Additionally, a complete download of all the various build files, tools, and source code examples is available from Apress's website.
This is a terrific book for folks in the .NET arena looking to establish an automated build and delivery system. It's a very good book for folks looking to enhance an existing automated system, particularly if you're looking to solve the really difficult problem of wrapping database integration into your system.
Lastly, I'd say it's a very good book for anyone interested in automated build and delivery processes, regardless of the environment you're working in. Java developers can get great material from this book, just as I got great ideas from Loughran's Java Development with Ant.
You can purchase Expert .NET Delivery Using NAnt and CruseControl.NET from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
Too many words (Score:2, Funny)
Re:Too many words (Score:1)
Automated delivery??? (Score:2, Funny)
Isn't that what spyware/adware uses??
Re:Automated delivery??? (Score:2)
No, spyware/adware uses corn delivery, or as the Native Americans called it "Maize-pawah". Corn power is coming of age and once my corn-fed robots are complete I'm going to put you all in cages!
Seriously though, this is about automating your build process for "delivery". The build process and configuration management are weak points in a lot of software development processes, so this type focus is important for quality in the end product.
Build Process? (Score:2)
Please help me out... (Score:4, Funny)
If the review of the review shows that the review is worthwhile, and it is ultimately favorable to the book, I may then read the book.
Re:Please help me out... (Score:2, Funny)
Re:Please help me out... (Score:2, Funny)
Review of review (Score:1)
Re:Please help me out... (Score:2)
Re:Please help me out... (Score:1)
Re:Please help me out... (Score:1, Funny)
I try not to judge qualitatively.
I think i just mini-puked in my mouth (Score:2, Funny)
Wow does that conjure up horrible images of my car showing the BSOD right before I realize I can't get out of cruise control...
*shudder*
Re:I think i just mini-puked in my mouth (Score:3, Funny)
[Clippy appears] "It looks like you are about to be involved in a collision with another vehicle. Would you like help? Did you know Microsoft will handle your insurance claim as well? Click here to find out more!"
Static analysis of C# (Score:4, Interesting)
Seems both useful and doable, but Googling a bit only turned up commercial tools...
Re:Static analysis of C# (Score:3, Informative)
Parsing the source code might be a bit tricky since you'll need to check for semantic problems which have already been fixed by the time the bytecode has been generated. Parsing the bytecode might have the additional benefit of being able to do some peephole optimization and such; you could write a static analysis tool that also does some work to reduce bytecode s
Re:Static analysis of C# (Score:2)
Very nice, looks like the message board [gotdotnet.com] for that project is hopping, too.
But is it open source? This is the EULA [gotdotnet.com]; and I don't see a source download... maybe I'm just missing it...
Re:Static analysis of C# (Score:1)
Re:Static analysis of C# (Score:1)
NDepend (Score:3, Informative)
Re:NDepend (Score:1)
With thirty seconds on The Mighty Google: (Score:1)
- pd
Re:With thirty seconds on The Mighty Google: (Score:1)
Yup, but is it open source?
Re:Static analysis of C# (Score:2)
Here's the Wikipedia entry [wikipedia.org], and here's a code example:
Re:Static analysis of C# (Score:2, Informative)
There are also other tools out there, but these are a reasonable start.
Re:Static analysis of C# (Score:1)
Re:Static analysis of C# (Score:2)
Re:Static analysis of C# (Score:1)
Might be somewhat easier.
I know it works in java, because eclipse is kind enough to point things like uncalled private methods, unreferenced locals, useless assignments, and more...
Build Systems Are Often Overlooked (Score:5, Interesting)
Integration into larger enterprise architectures would also be a critical subject, as most of us develop in some kind of larger environment that has it's own tools, standards, and processes. In other words, I get the feeling from the review that the book is more "blank sheet" build control than "big corporate" build control. There's a difference.
Giant Bathroom Sponge Found Orbiting Saturn! Film at Eleven [whattofix.com]
Re:Build Systems Are Often Overlooked (Score:2)
I think the CruiseControl products are popular to target for authors since they are more config file focused than the more graphical tools. Text is easier to write about than saying, "then you would go to screen X and set these values..."
Re:Build Systems Are Often Overlooked (Score:2)
Found here: http://www.pragmaticprogrammer.com/starter_kit/aut o/index.html [pragmaticprogrammer.com]
Re:Build Systems Are Often Overlooked (Score:2)
It fires automatically every minute or two whether there have been any source changes at all - even if another cruise control is still running - and commences a checkout of the entire repository.
I've seen it bury Quad processor machines doing this. Had a few support problems until I realized what it was doing (one person had 10 CC's running simultaneously an
Re:Build Systems Are Often Overlooked (Score:2)
This is only true if it is poorly configured. The more popular configuration is 'checks' for source changes every XX number of minutes, and only perform a GET or checkout if there has been a source change. It's also unusual to run so many instances on a single box.
Counts (Score:1, Informative)
Delivery: 19
Review of the Review (Score:1, Informative)
Although, elegantly spoken, the review lacks content. The review seems to be nothing more but chapter summaries taken straight from the book. The only unique information the author seems to present is that the book is a great read if you are a
Version control... (Score:2, Offtopic)
Re:let me get this straight... (Score:2)
http://www.jaredrichardson.net/blog/2005/06/15/ [jaredrichardson.net]
Saltmines? (Score:2)
The thing is, I agree that Stevens' book is a classic. It laid out POSIX compliant systems for me in a coherent way that no man pages ever could. But your point is lost in demagoguery about Microsoft's evil.
But I see you've been modded down to 0 as a troll.
spell check (Score:1)
PDF from Apress = half price (Score:2, Informative)
.NET? (Score:3, Funny)
Isn't
Re:.NET? (Score:2)
No. Mono is an open source implementation of most parts of
Try harder (Score:2)
Then there's the knotty problem of scheduling. If you're building a r
Re:Try harder (Score:2)
How do you do assemble the components now? By hand? I hope not! Even if you do, creating a build script that consumes the output from other builds is not rocket science. Maven 2 will have this built in.
Then there's the knotty problem of scheduling.
Not really... Continuous Integration builds only when the code changes. At the end of the week, you have a collection of up to d
Re:Try harder (Score:2)
The problem we have is that I have to schedule builds on every damn server rather tha
Re:Try harder (Score:2)
Gotcha. In that case I'd use CC to trigger the builds, but use your existing system
Re:Try harder (Score:2)
* validate - validate the project is correct and all necessary information is available
* compile - compile the source code of the project
* test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
* package - take the compiled code and package it in its distributable format, such as a JAR.
* integration-test - process and deploy the package if nec
Re:Try harder (Score:2)
You're killing me! :) Maven is soooo open source! Hop on the development list http://maven.apache.org/maven2/> and talk through these issues. If you need it, assume others do as well.
Honestly, the ability to test an installed product is (in my opinion) much more valuable than unit testing. Both are important, but unit test success doesn't matter if the installed product doesn't run properly. Other people need to focus on the same issues you nee
Why CC.net? (Score:1)
Tell me one thing you can do with CruiseControl that you can't using Nant/NantContrib and a job/scheduled task. With Nant you can get-latest (also by label and autobuild), it h
Re:Why CC.net? (Score:3, Informative)
Also, check out VS.net 2005. For better or worse, almost all of these tools are provided by Microsoft in the next Visual Studio Release.
For starters, it includes:
MSBuild [microsoft.com] (so long NAnt!)
Unit Testing [microsoft.com] (so long NUnit)
Build Automation (so long CruiseControl) [microsoft.com]
Refactoring [microsoft.com] (so long Resharper ) [jetbrains.com]
Re:Why CC.net? (Score:1)
MSBuild (so long NAnt!)
Unit Testing (so long NUnit)
Build Automation (so long CruiseControl)
Refactoring (so long Resharper )
And Bugs! [google.com] (so long release schedule)
Re:Why CC.net? (Score:2)
So I built my masterbuild script, which would calculate the build number, label the source in SCM, get it and then execute a systembuild script found in the project space. Then on completion, take all the logs bundle them up with the build in a particular place.
Then I thought maybe I should have a flag where it only builds if there have been changes
Cruise control sounds good (Score:2)
bookpool (Score:2)
Databse integration chapter is a free pdf download (Score:1)
Ah, but that chapter can be had for free from Apress website [apress.com]. That chapter indeed is a good read. I had looked for good solution to this problem a month ago and found none close to my satisfaction.
What's wrong with make? (Score:1)
That being said, can anybody tell me what's wrong with make that we need half a dozen other tools to control builds? The fact the Windows doesn't come with a real shell out of the box doesn't count. If you're gonna download a build tool, you might as well pick up cygwin/mingw/sfu while you're at it.
I think make's syntax is much cleaner that ant's XML, and since every
.net (Score:1)
Re:Oh No (Score:2)
Re:Oh No (Score:5, Informative)
"If I have seen further it is by standing on ye shoulders of Giants." --Isaac Newton
MS has nothing to do with CruiseControl.net or NAnt. These are fully Open Sourced projects built on the backs of other Open Source projects.
I thought it was about information sharing and freedom. Not bias and bullshit. But I could be wrong.
Re:Oh No (Score:1)
Re:Oh No (Score:1, Funny)
This often misused quote was actually a perjorative Newton used against a competing physicist of short stature.
Re:Oh No (Score:1)
Re:Hooray. (Score:2)
Good (Score:1)
Re:Automated build = bad... (Score:2)
Automated build can be for users though. When a version is released it can be built by an automated system with consistency, this is how all major development houses ship their products. Otherwise you may throw the monkey wrench of human error into the mix. Good build systems can deliver full end products, including fully burned CD-Roms/DVDs, programmed IC's, etc.
Of course it's up the development team to determine if this process is worth the cost.
Re:Automated build = bad... (Score:2)
Re:Automated build = bad... (Score:1)
an automated delivery system. Is civility a concept you understand? Perhaps you might consider it as more than just an outdated concept.
Re:Automated build = bad... (Score:2)
I'm curious why you think the software that is released would be different from what the what the testers tested.
Seriously dude, are you a developer? Say it aint so.
Re:Automated build = bad... (Score:2)
The idea of a different library breaking the code is a very real thing, like you showed. But that does not mean automated builds are a bad thing. An automated build system can guarantee that the package that you develop is the same package that gets tested and eventually released to the user. But outside dependencies cannot be controlled by this type of build system.
Re:Automated build = bad... (Score:1)
I haven't been able to come up with any answer to
the 'outside dependencies break my code'. Well,
other than the obvious one, remove all outside
dependencies. Which isn't always very useful since
a program with no outside dependencies is not
very useful (other than games). Since I see
many other systems experiencing it too, I guess
they haven't either (or just haven't addressed
it).
Have a good one.
Re:Automated build = bad... (Score:4, Insightful)
No kidding! Can you imagine what would happen if you automated builds to make sure the pieces fit together? You think things are bad now, wait till you automatically know if there is a problem!!! The book even talks about automated testing. Are they bloody crazy!!!! Can you imagine the problems caused by automatically finding errors/issues in code without spending hundreds of man-hours manually going through every test for every build????? I hope this never comes to pass!!!!
Can I now be modded "Interesting" for saying absolutly retarded shit to? (No disrespect meant to the mentally handicapped by grouping them with parent)
Re:Automated build = bad... (Score:4, Insightful)