Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Continuous Integration
New Posts  All Forums:Forum Nav:

Continuous Integration

post #1 of 3
Thread Starter 
I saw a post about source control systems, and thought I would throw a quick post up about CI (Continuous Integration). It is a wonderful thing to have in your development environment. It really helps with consistant builds and versioning. We use a combination of SVN and CruiseControl.NET as our CI platform. The SVN is one of several source control systems that you can use. We just like the simplicity of SVN.

The basic idea of CI is that developers perform code tasks on development machines, and the build server takes care of the compilation. If you have multiple developers all compiling code on different machines there could be issues as every machine will eventually differ in one way or another. The installation includes a web interface so that any projects can be built on demand from anywhere on the network.

The installation of CC.NET is very basic, the configuration can be a little hairy.

The basis for the server lies in the configuration file. This is just an xml file that defines the projects you want to manage. It has a few basic parts.

  • Project Name
  • Trigger information
  • Source information
  • Tasks

Another piece of the confguration are some global variables here are some of mine...
Code:
<cb:define BUILD="D:\Build\" />
  <cb:define ARTIFACT="D:\Build\Artifact\" />
  <cb:define MSBUILD ="C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" />
  <cb:define MSBUILDLOGGER ="D:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll" />
  <cb:define LABELPATTERN ="(major).(minor).(build).(revision)" />

Here is one of my projects
Code:
<project>
      <name>Build Project</name>
      <artifactDirectory>PATHHERE<artifactDirectory>
      <triggers/>
      <sourcecontrol type="svn">
        <trunkUrl>URL</trunkUrl>
        <workingDirectory>PATH</workingDirectory>
        <checkExternals>true</checkExternals>
      </sourcecontrol>
      <tasks>
        <msbuild>
          <executable>$(MSBUILD)</executable>
          <workingDirectory>$(SOURCE)</workingDirectory>
          <projectFile>$(CLASS).sln</projectFile>
          <buildArgs>/p:Configuration=Release /v:diag</buildArgs>
          <targets>Clean;Rebuild</targets>
          <timeout>900</timeout>
          <logger>$(MSBUILDLOGGER)</logger>
        </msbuild>
        <exec>
          <executable>svn</executable>
          <buildArgs>commit -m "Automated Commit from Build Server" "$(SOURCE)Assemblies"</buildArgs>
        </exec>
      </tasks>
    </project>

What we have here is a basic .net project. Notice there are no triggers defined, this project is manually executed. The source section will pull the HEAD revision and perform any number of tasks. Here the tasks are to execute MSBUILD to compile the assembly based on some arguments. In this case, the assembly that gets created also gets commited to source.

We have a couple of other projects that require a more complex build. Not only do I need to build an assembly, but I also need to create an installer. No problem, this is what that task could look like..
Code:
<exec>
          <executable>cmd</executable>
          <buildArgs>
            /C "$(BATSCRIPTS)ISCmdBld.bat"
          </buildArgs>
          <environment>
            <variable name="ISCmdBld" value="$(ISCMDBLD)" />
            <variable name="ISM" value="D:\Client.ism" />
            <variable name="Configuration" value="Main" />
          </environment>
        </exec>

It also has a plugin system so you can make your own task blocks. In our company we don't like using the standard .NET build revision system (1.0.0.*). What we wanted was a system that we could set the Major, Minor and Build numbers but use the SVN revision number as the final piece. That way we can easily trace code back to the source if there are any issues.

So why does this help? Let's look at a trigger block.
Code:
<triggers>
        <projectTrigger project="Build Project" />
      </triggers>

This tells the server that whenever the "Build Project" project gets built, then this one needs to get built as well. We have several in-house assemblies that we use in most of our projects, some of them extend a base assembly. When that base assembly needs to change, then a handful of other projects need to get rebuilt. CI takes care of all of that.

Here is another handy trigger
Code:
<triggers>
        <intervalTrigger name="continuous" seconds="30" buildCondition="IfModificationExists" initialSeconds="30" />
      </triggers>
This one only fires off when a change has been comitted to source. So your developers only have to check in thier changes and the new build happens automatically. You can also schedule nightly builds.

I only touched on a small portion of what can be done. Take a look and try it out!
Main Rig
(15 items)
 
  
Reply
Main Rig
(15 items)
 
  
Reply
post #2 of 3
Does this only work on .NET programming languages?

Also in my experience (limited as it may be) most problems when coding on different machines come at run time (for example: system max for integers or floating points) and not compiling.

Mind enlightening me a situation of when when compiling is an issue with different machines? because the only thing I can think of off the top of my head would be lack of imported files like classes when trying to run code dependent on other code that may not be present or fully updated at compile/run time.

Other than that I do see major advantages of having one system to do everything as all code should be up to date and everything would be where it should be.
Bob's Computer
(16 items)
 
  
CPUMotherboardGraphicsRAM
Intel i5 2500K MSI P67A-G45 MSI 6970 Lightning 2GB G Skill Ripjaws X (2x4GB) 1866mhz 9-10-9-28 
Hard DriveOptical DriveCoolingOS
Corsair Force 3 SSD (60GB), X1 WD5000AAKS, X1 W... ASUS DRW-24B1ST/BLK/B/AS Black SATA 24X DVD Burner Noctua NH-C14 Windows 7 64 bit 
MonitorKeyboardPowerCase
Asus VH238H Logitech G510 HALE90 750W NZXT Phantom Black 
MouseMouse PadAudioOther
Logitech G9x SteelSeries 4HD ASUS Xonar DGX / Audio-Technica ATH-AD700 Hauppauge! HVR-1250 TV Tuner 
  hide details  
Reply
Bob's Computer
(16 items)
 
  
CPUMotherboardGraphicsRAM
Intel i5 2500K MSI P67A-G45 MSI 6970 Lightning 2GB G Skill Ripjaws X (2x4GB) 1866mhz 9-10-9-28 
Hard DriveOptical DriveCoolingOS
Corsair Force 3 SSD (60GB), X1 WD5000AAKS, X1 W... ASUS DRW-24B1ST/BLK/B/AS Black SATA 24X DVD Burner Noctua NH-C14 Windows 7 64 bit 
MonitorKeyboardPowerCase
Asus VH238H Logitech G510 HALE90 750W NZXT Phantom Black 
MouseMouse PadAudioOther
Logitech G9x SteelSeries 4HD ASUS Xonar DGX / Audio-Technica ATH-AD700 Hauppauge! HVR-1250 TV Tuner 
  hide details  
Reply
post #3 of 3
Thread Starter 
While CruiseControl.NET is certainly meant and primarily used by .NET developers it is not only for .NET. This particular version is a port of Cruise Control and will utililze a number of builders as plugins or anything that can be compilied via command line.

Obviously, you are correct that most problems arrise from differences in the client machine. However, using CI unequivocally rules out issues with the compilation of your program. Compilers have a large number of options that the developer must choose when compiling. Let's say that a software was developed using an architecture neutral method; meaning it will let the OS decide how to execute. If one developer inadvertently compiles the code as x86 or x64 the exact same code may execute differently when deployed to a client. Anyone who has ever tried to debug an intermittant software bug will rejoice at the chance to completely rule out ANYTHING.

Some SDKs install thier assemblies in a global directory. These types of installations often mean that the developer with the SDK is the only one that can compile the application. What happens when that developer is out of reach and a build needs to be compilied? Licensing comes into play here as well. In my company we have one person that primarily handles the GUI development and another that will often work on the back-end classes. To properly license a third-party control you would need two licenses for each developer. Expand that to a larger team where you have multiple developers that will not use the GUI controls, why should you have to buy licenses for them? In a build-server environment you only need licenses for the developers actually using the tools and one for the build-server itself. Many licensing schemes either include a build-server license or offer one at a reduced cost.

I think the overall reason is that it is considered best practice. In most cases I wouldn't suggest that a person do something only because everyone else is doing it. However, best-practices are "best" for a reason. Sometimes it is good to follow the crowd, especially if that crowd has hundreds of years of combined development and industry experience.

I think that why is a great point, that I should have done a better job with in the initial post. There are several reasons for using a dedicated build server and CI. However, a single developer might not experience some of the pains that a development group will have to endure. It certainly won't hurt to start from the beginning with the way things are "supposed" to be done. Your development projects are never too small to do properly (ouch, the sting of hypocrisy hurt a bit when writing that).
Main Rig
(15 items)
 
  
Reply
Main Rig
(15 items)
 
  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Coding and Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Continuous Integration