New Continuous Integration Servers
Jeffrey Frederick, who is organizing the CITCON conference in London, sent out a message today asking if folks had seen or used any of the newer CI servers that are becoming available. It is pretty amazing that over the past few years so much has been done in this area. Check out this huge feature comparison matrix.
Personally, I have only used CruiseControl, CC.Net, and at one point I did a trial install of AntHill. Of those, I have been the most impressed with CC.Net. I found it easy to install and configure, powerful, and flexible. It's been a long time since I looked at AntHill, so I bet that has gotten better too. It would be fun to look at some of these new ones. I'm especially intrigued by the new Java tools that can work with Maven. The dependency conglomeration they do seems like it might be a lot more flexible and robust than the system I described in my post on enterprise continuous integration. That system has been working extremely well on my current set of projects, but I think I might have more difficulties if we scaled up to a larger more distributed team. Some of the tools that Jeffrey mentioned specifically include
National Debt
CITCON London, October 6-7, 2006
Continuous Integration and testing conference
Paul Julius and Jeffrey Fredrick are hosting another version of the Continuous Integration and Testing Conference, this time in London, October 6th and 7th. The first one in Chicago was impossible for me to go to, this one is just rubbing salt in the wound for me!
The last one sounded like a great success. They ran it using the 'open spaces' conference style that I am seeing more and more. Here's hoping that this one gathers lots of folks and leads to lots of good information sharing. If you are interested, register (it's free once you get there!) at the citcon website. Even if you are not going, check out the wiki from the last conference.
Upgraded blog tools
I just upgraded from Pebble 1.9 to Pebble 2.0 RC1. It came with a new theme, as you can see - perhaps I will change that to my own theme at some point. In any case, the upgrade took a while. In the process, I also had to upgrade the version of Tomcat I was running as well. It may be a few days before everything is working properly again!
Shipping pdb files in release mode
<VisualStudioProject>
<CSHARP ...>
<Build>
<Settings … >
<Config
Name = "Debug"
…
DebugSymbols = "true"
…
/>
<Config
Name = "Release"
…
DebugSymbols = "false"
…
/>
</Settings>
...for each .csproj file in this directory and any subdirectory { change the XML at the path /VisualStudioProject/CSHARP/Build/Settings/Config[@Name='Release']/@DebugSymbols to 'true' }
@echo off for /R %%i in (*.csproj) do @xmlpoke %%i "/VisualStudioProject/CSHARP/Build/Settings/Config[@Name='Release']/@DebugSymbols" true
@echo off :: this is a batch file to call nant and run the xmlpoke command on an file, changing the existing value at xpath to a new value :: parameters must be given: :: path and name of xml file :: xpath expression :: new value :: nant.exe must be on the path or setnant.bat must be on the path setlocal set _ERROR= call setnant.bat > NUL echo. if .%1.==.. echo XML input file must be specified & set _ERROR=1 if .%2.==.. echo XPath must be specified, and might need quotes around it & set _ERROR=1 if .%3.==.. echo newvalue must be specified & set _ERROR=1 if defined _ERROR goto ERRORif not exist %1 echo the XML input file '%1' could not be found & set _ERROR=1 if defined _ERROR goto ERRORset xpath=%2 set xpath=%xpath:"=%echo. echo poking value [%3] echo into xpath %xpath% echo inside file %1 echo. nant.exe -D:filename=%1 -D:xpath=%xpath% -D:value=%3 -buildfile:%~dp0xmlpoke.build | findstr /C:" [xmlpoke]" goto :EOF:ERROR echo. echo syntax: echo xmlpoke ["input.xml"] ["xpath"] ["newvalue"] echo.
<?xml version="1.0" encoding="utf-8" ?> <project name="xmlpoke" default="go" xmlns="http://nant.sf.net/release/0.85-rc3/nant.xsd"> <target name="go" description="run xmlpoke using properties that have to be set on the command line"> <xmlpoke file="${filename}" xpath="${xpath}" value="${value}" /> </target></project>
even more FitNesse GoodNesse
running all your suites on a regular basis
<project name="nightly_fitnesse"> <webURL>http://buildserver/ccnet/Controller.aspx?_action_ViewProjectReport=true&server=buildserver&project=nightly_fitnesse</webURL> <triggers> <scheduleTrigger time="23:30" buildCondition="ForceBuild" /> </triggers> <sourcecontrol type="svn"> <executable>c:program filessubversionbinsvn.exe</executable> <trunkUrl>svn://codeserver/fitnesse/trunk/</trunkUrl> <tagBaseUrl>svn://codeserver/fitnesse/tags/</tagBaseUrl> <workingDirectory>d:workfitnesse-trunk</workingDirectory> <tagOnSuccess>false</tagOnSuccess> <autoGetSource>true</autoGetSource> <username>cruisecontrol.net</username> <password>ccnetpassword</password> </sourcecontrol> <tasks> <nant> <executable>D:workdependencies-trunkexternalnantNAnt.exe</executable> <baseDirectory>d:workfitnesse-trunk</baseDirectory> <buildFile>AustinNightlyFitnesse.build</buildFile> <targetList> <target>fit</target> </targetList> <!-- this build timeout is fairly long, since these tests can get long. --> <buildTimeoutSeconds>1500</buildTimeoutSeconds> </nant> </tasks> <publishers> <merge> <files> <file>D:workfitnesse-trunkresults*.xml</file> </files> </merge> <xmllogger /> </publishers> </project>
<?xml version="1.0" encoding="utf-8" ?> <project name="AustinNightlyFitnesse" default="fit" xmlns="http://nant.sf.net/release/0.85-rc3/nant.xsd"> <property name="fit.server" value="localhost" /> <property name="fit.port" value="8080" /> <property name="results.dir" value="results" /> <target name="fit" description="run fit tests"> <property name="FitRegressionFailureSummary" value="0" /> <delete dir="${results.dir}" failonerror="false" /> <mkdir dir="${results.dir}" /> <property name="fit.suite" value="GuideEngine.SuiteRegressionTests" /> <property name="fitlibs.dir" value="c:fitnessedotnetGuideEngine" /> <call target="runFitSuite" /> <property name="fit.suite" value="LookupWeb.SuiteRegressionTests" /> <property name="fitlibs.dir" value="c:fitnessedotnetLookupWeb" /> <call target="runFitSuite" /> <property name="fit.suite" value="FireFly.SuiteRegressionTests" /> <property name="fitlibs.dir" value="c:fitnessedotnetFireFly" /> <call target="runFitSuite" /> <property name="fit.suite" value="ShareDoc.SuiteRegressionTests" /> <property name="fitlibs.dir" value="c:fitnessedotnetShareDoc" /> <call target="runFitSuite" /> <fail message="${FitRegressionFailureSummary} Fitnesse Regression test(s) failed." if="${int::parse(property::get-value('FitRegressionFailureSummary')) != 0}" /> </target> <target name="runFitSuite" > <!-- same basic steps, but these must all pass, or the build fails --> <property name="fit.testrunner" value="${fitlibs.dir}TestRunner.exe" /> <echo message="running fit regression tests at http://${fit.server}:${fit.port}/${fit.suite} using ${fit.testrunner}" /> <exec program="${fit.testrunner}" commandline="-results ${results.dir}Fit-${fit.suite}.html ${fit.server} ${fit.port} ${fit.suite}" failonerror="false" resultproperty="FitRegressionResult" /> <!-- now transform those results from html to xml, and then fail if there were any errors. Fitnesse helpfully returns that as a number. --> <exec program="java.exe" commandline="-cp binfitnessefitnesse.jar fitnesse.runner.FormattingOption ${results.dir}Fit-${fit.suite}.html xml ${results.dir}Fit-${fit.suite}.xml ${fit.server} ${fit.port} ${fit.suite}" failonerror="false"/> <property name="FitRegressionFailureSummary" value="${int::parse(property::get-value('FitRegressionFailureSummary')) + int::parse(property::get-value('FitRegressionResult'))}" /> <echo message="${FitRegressionResult} Fitnesse Regression test(s) in ${fit.suite} failed." /> <echo message="So far, a total of ${FitRegressionFailureSummary} Fitnesse Regression test(s) failed." /> </target> </project>
ThinkGeek :: Bluetooth Laser Virtual Keyboard
Derek Cicerone Installing...: heat.exe - making setup easier
interesting new service
Capistrano: Automating Application Deployment
Application deployment is one of those things that becomes more and more complicated as the scale of your application increases. With just a single box running your database and your application, it’s quite simple. But when you start putting your database on a different server, and then separating your web servers from your app servers, and eventually splitting your database into master and slave servers… It can get to where you almost don’t want to deploy your application any more. SwitchTower is a standalone utility that can also integrate nicely with Rails. You simply provide SwitchTower with a deployment “recipe” that describes your various servers and their roles, and voila! You magically have single-command deployment. It even allows you to roll a bad version out of production and revert back to the previous release. It should be stated that the concepts that SwitchTower uses and encourages are not specific to Rails, or even Ruby. They are common-sense practices that are applicable to a variety of environments. In fact, you’ll find that there is very little that is Rails-specific about SwitchTower, aside from the fact that it is in Rails that it found its genesis. No matter where you are or what environment you are using, SwitchTower can probably help ease your deployment pains.We have done some interesting things around automating our deployment, but this project looks interesting. Here is what we currently do though. Currently we have our CruiseControl build creating 2 zip files at build time (one for the App server and one for the web server) that have the correct directory structure. We also include a nAnt build file. The zip file is then checked into subversion. To get those installed, We have CruiseControl.net installed on the servers, and have a project set up so that by triggering a build (it has to be done manually), CC downloads the latest zip files from subversion, unzips them, and then runs the nant build to install them. It has taken us from what was sometimes a 2 hour ordeal to being able to deploy the latest version in less than a minute.
