Home | About Us | Stelligent  

TestEarly Weblog
Jay Flowers

Jay Flowers

Senior Software Consultant
Stelligent Incorporated
As a Senior Software Consultant for Stelligent Incorporated, Jay helps customers design and implement continuous integration environments, automated build and deployment environments and test driven development. He is an experienced software engineer with a focus on the .NET development platform. Early in his career, he found an affinity for Continuous Integration (CI) and unit testing. He quickly became known for getting the development team up and running with CI and Test Driven Development (TDD). He gained extensive experience in the open source community having contributed to and extended NAnt, CruiseControl.NET, MbUnit, and Reflector. Jay has created his own open source projects as well: CI Factory and Doubler. Beyond open source contributions Jay collaborated on the book, "Windows Developer Power Tools" (O'Reilly, 2007), authoring the section on CI Factory. He has written several papers, articles and is a frequent blogger on such topics as CI, unit testing, and software engineering in general. In addition to writing, Jay speaks at conferences and user groups on CI and unit testing.
Build Management and Continuous Integration and /Flowers01 Oct 2007 04:55 pm

I think one of the reasons that I have had great success with CI Factory when introducing teams to CI is polish, or ease of use.  Some of that polish comes with CI Factory out of the box, this post is about that extra that I have found myself adding of late.

 

I like to provide a script that will get developers all setup from the get go.  Recently I have found the best place to locate this script to be on the CCNet dashboard.

 

CropperCapture[1]

 

The workspace setup script should check for the needed source control client, create the directory structure needed, and get the latest from the source control repository.  Lastly it opens a Windows Explorer window to the Product directory:

 

CropperCapture[22]

 

From here the developer can run a build by double clicking the Build.bat.  I have gotten to including a check for required software at the beginning of the personal build.  For example if Visual Studio 2005 SP1 is required I check for it and prompt the developer about it if missing.  Where possible I have the script install missing software with the developers permission.

 

CropperCapture[23]

 

Once all the required software checks pass the rest of the build runs as normal.  The last bit to be polished is the cctray install.  In CI Factory the cctray download is a zip not a setup.exe.  I like to turn this into a self extracting zip and include a pre-configured settings.xml file.  This way when cctray starts up for the first time it is already configured.

In my experience these things leave developers the head room to focus on things that deserve their attention.  Communicating this through actions like polish go a long way to demonstrating how CI can have an affect on the quality of their lives.

To add download links to the main web dashboard edit the file:

C:\Projects\<project name>\Current\Build\dashboard\templatesFarmSideBar.vm

<table width="100%">
  #foreach ($link in $links)
  <tr><td><a href="$link.Url" class="$link.LinkClass">$link.Text</a></td></tr>
  #end
  <tr>
    <td>
      <a href="WorkspaceSetup/CreateWorkspace.bat.txt" >
        Workspace Setup Script
        <br/>Save As .bat
      </a>
    </td>
  </tr>
</table>

Here is an example of some NAnt script added to the personal build that checks for VS 2005 SP1:

<property name="VisualStudioServicePack" value=""/>
<readregistry hive="LocalMachine"                  
              key="SOFTWAREMicrosoftDevDivVSServicing8.0SP" 
              property="VisualStudioServicePack" failonerror="false"/>
 
<ifnot test="${VisualStudioServicePack == ‘1′}">
  <ask answer="Answer" 
question="It looks like Visual Studio 2005 SP1 is not installed.  Do you wish to continue?" 
      caption="Proceed Without Required Software?" 
      showdialog="true" >
    <options>
      <string value="Continue"/>
      <string value="Stop and Install SP1"/>
      <string value="Exit"/>
    </options>
  </ask>
  <ifthenelse test="${Answer == ‘Stop and Install SP1′}">
    <then>
      <asyncexec program="cmd" 
      commandline=/C " explorer http://msdn2.microsoft.com/en-us/vstudio/bb265237.aspx" 
          createnowindow="true" 
          redirectoutput="false" 
          useshellexecute="true" 
          waitforexit="false" />
      <fail message="Installing VS 2005 SP1!" />
    </then>
    <elseif if="${Answer == ‘Exit’}">
      <fail message="Please install VS 2005 SP1!" />
    </elseif>
  </ifthenelse>
</ifnot>

The batch file for creating the workspace is a little clunky compared to NAnt script.  I have been mulling around the idea of including NAnt in a self extracting zip and executing a script instead of this batch file fun:

echo off

set ProjectName=CI Factory

set ProjectCodeLineName=Current

set ProjectCodeLineDirectory=C:\Projects\%ProjectName%\%ProjectCodeLineName%

set ProductDirectory=%ProjectCodeLineDirectory%\Product

set SVN.URL=https://ci-factory.googlecode.com/svn/%ProjectCodeLineName%

mkdir "%ProjectCodeLineDirectory%"

SET /P Anonymous="Do you wish to do an anonymous checkout of the source? Yes for patch creators, No for submitters:(y,n)"

IF %Anonymous%==y set SVN.URL=http://ci-factory.googlecode.com/svn/%ProjectCodeLineName%

IF EXIST "%ProgramFiles%\TortoiseSVN\bin\TortoiseProc.exe" GOTO UseTortoise

svn –version

IF NOT %ERRORLEVEL%==0 (set PATH=%PATH%;%ProgramFiles%\Subversion\bin) ELSE GOTO UseSubversion

svn –version

IF NOT %ERRORLEVEL%==0 (set PATH=%PATH%;%ProgramFiles%\CollabNet Subversion Server\bin) ELSE GOTO UseSubversion

svn –version

IF %ERRORLEVEL%==0 (GOTO UseSubversion) ELSE GOTO NoSubversion

:UseSubversion

IF %Anonymous%==n SET /P SvnUserName="What is the user name you wish to use to checkout the source?"

set Credentials=

IF DEFINED SvnUserName set Credentials=–username "%SvnUserName%"

svn checkout %Credentials% "%SVN.URL%" "%ProjectCodeLineDirectory%"

IF %ERRORLEVEL%==0 (GOTO OpenFolder) ELSE GOTO END

:NoSubversion

echo I can’t find where you have Subversion installed!

GOTO END

:UseTortoise

"%ProgramFiles%\TortoiseSVN\bin\TortoiseProc.exe" /command:checkout /url:"%SVN.URL%" /path:"%ProjectCodeLineDirectory%"

IF %ERRORLEVEL%==0 (GOTO OpenFolder) ELSE GOTO END

:OpenFolder

explorer "%ProductDirectory%"

:END

Build Management and Continuous Integration and /Flowers17 Sep 2007 07:41 am

There are two general ways in which you can structure a build pipeline: one cuts across the product and the other across validation.

I was recently asked about breaking up the build by having a build hierarchy that mirrored the product’s package dependency tree. I have seen this done, and done it myself, in a very coarse way, dividing along lines strongly marked both by organization and architecture. There is a even a well known pattern on this: Named Stable Bases. It should be made clear that this is a form of deferred integration. Yes, yes, the ill consequences of deferred integration are the very things that continuous integration is working to alleviate. Just because deferred integration has been abused in the past is no good reason not to wield it wisely now. So lets take a look at how it alters the dynamics of a build system. To show this I have created a loop diagram, see this post for more details on loop diagrams and remember that the "s" means varies the same and "o" means varies the opposite.

CropperCapture[16]

The entire product is not built, even compiled, all at one time; it is spread out over time. Many times there can be a significant delay between when a dependency is built and when a dependant consumes that new build. This breaking up of the build has the effect of decreasing the size of the Codeline which ultimately shows the effect of increasing the rate of change to the Codeline. This is a short sighted view, remember that we are building a whole product and that we have deferred some integration. The key here is some, not all. So the question is will the things effected positively out weigh the deferred integration? I have illustrated the forces at play here in a well know pattern or archetype in Systems Thinking named Fixes That Fail.

Fixes That Fail (^)

The Fixes That Fail structure consists of a balancing loop and a reinforcing loop. These two loops interact in such a way that the desired result initially produced by the balancing loop is, after some delay, offset by the actions of the reinforcing loop.

The internal balancing loop operates in the standard balancing loop fashion. The Action that influences the migration of the Current State also influences, after some delay, some Unintended Consequences. These Unintended Consequences subsequently impede the migration of the Current State in the intended direction.

One of the dangers I see with this approach is how it shifts the focus away from the product and the overall build systems to the product components and their smaller builds. It is more difficult to see the big picture and foresee the repercussions of actions in the small on the large. This type of build pipeline shifts the delay of feedback from an individual integration duration to the push or pull between individual builds. For example there is an uncomfortable delay in getting a developer feedback when the build of an entire product takes 45 minutes. One might feel a good solution is to break up this single build into 3 builds one for the common libs, one for the server, and one for the client. Now when a developer of the client submits to the build they get feedback in 8 minutes. Here is the deception of this model, the overwhelming majority of the time the client build is working against old versions of the common libs and server. The delay is getting the build output of the common libs and server integrated into the client build.

In my experience most people start down the path of splitting a build in this fashion by first seeing a waist in recompiling packages that don’t need to be recompiled. This is a valid observation and fruitful optimization, and I think that in most cases division of build process to realize this benefit yields a net negative in consequences. I have only seen this structure work well as a means to compensate for organizational issues. For example when the web front end team has little contact with the back end service team. The web front end team may experience interruptions due to changes in the back end that impede progress. One means to compensate for this is to accept regular stable deliveries of the back end. This allows for uninterrupted progress, flow, and regular planned integrations to the new version of the back end.

I have experienced great success with division of the build across validation as apposed to across the product. In the past I have referred to this as creating developer, release, tester, and customer facing builds. Let’s generalize that a little to: role facing builds. Before I explain remember that the desired state is rapid feedback and the gap is perceived delay in feedback. When we take into account the different roles on the team we realize that they each have different desires. The developers are accepting of less comprehensive feedback in exchange for quicker execution times. The testers in contrast are accepting of longer execution times in exchange for more comprehensive feedback. The developers are not interested in creation of an installer, verses everyone else is extremely interested in an installer. If you continue down this path of inquiry you will have a set of values that will help you shape a build pipeline. I bet that you would find only the developers perceive a delay in feedback. Creating role facing builds can be quite liberating in what you can do and what you don’t need to do in a build. It is the don’t need to do that has the greatest affect on the developer facing build. You don’t need to do a clean build, an incremental or dirty build can be very quick. You don’t need to execute long running tests. You don’t need to create an installer.

This is not a perfect solution, there is no such thing. So what about the negative consequences? A successful build from a developer facing build can give a developer the illusion that all is well. They need to remain engaged and interested in the results of the cascaded builds. I have not seen any other generic issues with this approach, here is an example of an issue with how it is implemented: It is important that the developer be able to easily execute all parts of any build in the system that can cause a failure and or create build artifacts. If for example a developer can not run a test that is causing a build to fail they will not be very likely to jump right on it. There will be negatives in what ever implementation you conceive of. You need to be alert to them as you will not be able to foresee them all. There are many ways in which to mitigate and or alleviate there impact.

Creating a loop diagram of your build system can be a tremendous help in this regard. Here is a picture of a generic build system to help illustrate the value:

CropperCapture[17]

Here is a link to the free software that I drew this with and the diagram itself:

http://www.simtegra.com

Diagram CI.msys

WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1]
SELECT COUNT(DISTINCT ID) FROM