<?xml version="1.0"?><rss version="2.0"><channel><title>Cruise &gt; Cruise Blog</title><link>http://community.thoughtworks.com/hives/f6df20cb3a</link><description>What the Cruise team is thinking about</description><language>en-us</language><copyright>Copyright 2006, HiveLive Inc.</copyright><pubDate>Tue, 15 Sep 2009 09:25:27 +0000</pubDate><lastBuildDate>Tue, 15 Sep 2009 09:25:27 +0000</lastBuildDate><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Making Cruise Work With TFS (3 Comments)</title><link>http://community.thoughtworks.com/posts/3504623661</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/85ce7690d9&quot;&gt;Li Yanhui&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;Cruise doesn&apos;t support &lt;a href=&quot;http://en.wikipedia.org/wiki/Team_Foundation_Server&quot; rel=&quot;nofollow&quot;&gt;TFS&lt;/a&gt; directly. But if you are using TFS as your source control system, and you want to try Cruise, there is a good solution: &lt;a href=&quot;http://www.codeplex.com/SvnBridge&quot; rel=&quot;nofollow&quot;&gt;SvnBridge&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Basically, &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt; acts as a bridge between a Subversion client and a TFS server, translating subversion commands to TFS ones. In this way you can use Cruise&apos;s built-in Subversion support to access TFS repositories.&lt;/p&gt;
&lt;h3&gt;More&lt;/h3&gt;&lt;p&gt;There are two ways to setup &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;standalone utility&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;padding-left:30px;&quot;&gt;This is a simple way to try &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt;. What you need to do is just download the utility and run it. Choose a listening port as the svn server port. That&apos;s it. Now you can use the following svn url to access your TFS repository:&lt;br /&gt;
&lt;a class=&quot;externalLink&quot; title=&quot;External link to http://localhost:[port]/[TFS-hostname]/[your-project-name&quot; href=&quot;http://localhost/%5BTFS-hostname%5D/%5Byour-project-name&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://localhost:[port]/[TFS-hostname]/[your-project-name&lt;/a&gt;]&lt;br /&gt;
&lt;br /&gt;
Note: with this approach you can only use it on localhost. The &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt; exposed svn repository is not available for remote access. That means you can&apos;t use remote agents on Cruise to access your TFS repository.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;application service running in IIS&lt;/p&gt;
&lt;p&gt;This can be your production choice. In this case the &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt; runs in IIS on the same host with your TFS server. So download the &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt; server application and install it following the instruction in the website. Make sure you have .Net 2 (or better) framework installed before that.&lt;br /&gt;
&lt;br /&gt;
Two things, which are a little different with the official instruction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the location of aspnet_isapi.dll is in your %windir%, not always c:\winnt, depends on your OS.&lt;/li&gt;
&lt;li&gt;for the authentication methods instruction, the recommended digest authentication doesn&apos;t work with svn command line, but it works with basic authentication.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;
After installation, you can use the following url to access the exposed svn repository from anywhere: &lt;a class=&quot;externalLink&quot; title=&quot;External link to http://[server-host]:[port]/[your-project-name&quot; href=&quot;http:/%5Byour-project-name&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt;http://[server-host]:[port]/[your-project-name&lt;/a&gt;]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, once you have setup &lt;span class=&quot;tiddlyLink tiddlyLinkNonExisting&quot;&gt;SvnBridge&lt;/span&gt; successfully, you got an svn interface for the TFS repository. You can just use it as an svn repository in Cruise. Following the Cruise instruction you can easily setup an svn pipeline to work with your TFS repository.&lt;/p&gt;
&lt;h3&gt;Keywords&lt;/h3&gt;TFS,svnbridge</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/3504623661</guid><pubDate>Thu, 03 Sep 2009 07:18:08 +0000</pubDate></item><item><title>Use resource-matching to get stage grouped by Cruise APIs (1 Comment)</title><link>http://community.thoughtworks.com/posts/4dac4a8fac</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/3b59f5aa54&quot;&gt;Qiao Liang 乔梁&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;A team wants two stages in one pipeline to run as group. The reason is:&lt;/p&gt;
&lt;p&gt;They have three stages in one pipeline, and the first stage for unit test, the second one for&amp;nbsp; server deployment, and the last one for functional test which will hit the servers that deployed in the previous stage &apos;deployServer&apos;.&lt;/p&gt;
&lt;p&gt;The unit test stage runs faster than the other two, so it is possable to deploy a new version of the application at the time the functional test is running if checkin frequently.&lt;/p&gt;
&lt;p&gt;It could handle this case by cruise-resource-matching and ruby script with cruise Json APIs:&lt;/p&gt;
&lt;p&gt;Setup a job in &apos;FunctionTest&apos; stage called &apos;checkJob&apos; and it needs the same resource with the job in &apos;deployServer&apos; stage and will treat the script as a task.&lt;/p&gt;
&lt;p&gt;When the third stage is running, &apos;checkJob&apos; will occupy the resource and run a task which is a ruby script to check whether the other jobs in &apos;FunctionTest&apos; stage are finished or not. If other jobs are finished, &apos;checkJob&apos; is going will finish immidately. Once &apos;checkJob&apos; finishes, the resource will release, and the new version could start to run on &apos;deployServer&apos; stage agent.&lt;/p&gt;
&lt;p&gt;The attachment is an example, including a rake file and a section of cruise-config.xml. &lt;em&gt;However&lt;/em&gt; You have to modify them to feed your pipeline and check in the rake file to your repository if you want to use them. Also the script needs &apos;json-1.1.3.gem&apos;.&lt;/p&gt;
&lt;p&gt;Notes: It works with 1.3.&lt;/p&gt;
&lt;h3&gt;Keywords&lt;/h3&gt;stage group, resource matcher&lt;h3&gt;File&lt;/h3&gt;&lt;a href=&quot;http://community.thoughtworks.com/files/c151255f80/stage-group.rar&quot; class=&quot;HL_View_IconAndText HL_Link_File HL_Link_File_ZIP&quot; target=&quot;_file&quot;&gt;stage-group.rar&lt;/a&gt; &lt;span class=&quot;count&quot;&gt;(1KB)&lt;/span&gt;</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/4dac4a8fac</guid><pubDate>Mon, 18 May 2009 02:00:54 +0000</pubDate></item><item><title>Personal Builds with Cruise and Mercurial</title><link>http://community.thoughtworks.com/posts/8c7619f15c</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/296931f394&quot;&gt;Chris Stevenson&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;A Personal Build allows a developer to send their changes to a continuous integration server to find out if all the tests are passing before they commit them to the central repository. Personal builds can increase developer productivity by allowing them to continue developing while a large or slow test suite is running. It can also improve the productivity of the team by ensuring that when code changes are checked in they do not break the build.&lt;/p&gt;
&lt;p&gt;This post talks about how we use Mercurial and Cruise to implement personal builds.&lt;/p&gt;
&lt;h3&gt;Image&lt;/h3&gt;&lt;img src=&quot;http://community.thoughtworks.com/files/a25eede7de/personal-build-diagram.png&quot; alt=&quot;&quot; width = &apos;470&apos; height = &apos;355&apos;  class =&quot;dynImage maxSize_550x416&quot; /&gt;&lt;h3&gt;More&lt;/h3&gt;&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;The problem&lt;/h2&gt;
&lt;p&gt;Ideally a developer will run all the tests before they check into a central repository. But sometimes this is not practical. For example the product under development may need to run on many platforms. Running all the tests on all the possible environments would be prohibitively slow.&lt;/p&gt;
&lt;p&gt;On Cruise we have Servers and Agents, each of which are supported on Linux (Ubuntu, Redhat and CentOS), Solaris, MacOSX and Windows. The Web UI is supported on Firefox (2/3) Safari and&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;IE 7&lt;/span&gt;/8 (not 6 thankfully).&lt;/p&gt;
&lt;p&gt;All of this is tested of course. We have unit and integration tests which we run on Linux and Windows, and regression tests that run in&amp;nbsp;&lt;a href=&quot;http://studios.thoughtworks.com/twist-agile-test-automation&quot; rel=&quot;nofollow&quot;&gt;Twist&lt;/a&gt;&amp;nbsp;on both Linux and Windows. But all of this can take a lot of time. This is particularly so for us since as a continuous integration product we do a lot of spawning external commands on the various platforms and SCMs and waiting for them to complete.&lt;/p&gt;
&lt;p&gt;We parallelize our test suites using&amp;nbsp;&lt;a href=&quot;http://community.thoughtworks.com/posts/4dd1349735&quot; rel=&quot;nofollow&quot;&gt;test load balancer&lt;/a&gt;&amp;nbsp;and the whole stage takes less than 10 minutes, but even this feels very slow when you are in the middle of something interesting.&lt;/p&gt;
&lt;p&gt;We like checking in often and mercurial makes it very easy for us to do this. Mercurial is a distributed source control management system (DSCM) which means that every developer has their own local repository. We can check in locally many times a day, merge changes from the central repository, and later on decide to commit a set of changes (possibly more than one changeset) back to the central repository. This is particularly useful for those of us who are working in San Francisco, since our central repository is in Beijing, and non-distributed SCMs are painfully slow in this scenario.&lt;/p&gt;
&lt;p&gt;It is useful to run tests very often, and indeed we do that. But when you have a long or complicated test suite it becomes painful to have to wait, and the effect is that we batch up larger changes, or run the tests less often. Even a 10 minute build is too long if you want to check in every few minutes.&lt;/p&gt;
&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;The personal pipeline&lt;/h2&gt;
&lt;p&gt;In this scenario it would be nice to have a build that could run comprehensive tests in the background while we keep developing the next feature. If the comprehensive tests expose a bug then we can go back and fix that bug quickly before checking the changes into the central repository. (It is possible to do this using mercurial queues)&lt;/p&gt;
&lt;p&gt;Since we are using a&amp;nbsp;&lt;span class=&quot;caps&quot;&gt;DSCM&lt;/span&gt;&amp;nbsp;this is actually very easy to implement. Mercurial can push changes from a repository to any other related repository. there are no ‘privileged’ repositories. It is a convention that we always push to the central repository. In fact we often push or pull changes to other developer repositories if there are changes that we want to work on that we don’t yet want to send to the central repository.&lt;/p&gt;
&lt;p&gt;So to set up a personal build, all a developer needs to do is create a local clone of the repository, start an hg server, and create a pipeline in Cruise that monitors that repository. When the developer wants to run the tests on their current set of changes they push their changes to that local clone.&lt;/p&gt;
&lt;p&gt;Cruise automatically picks up the changes and runs the pipeline. If the tests fail we go back and fix the problem, and then repeat the process. Once our work is complete we push the full set of changes to the central repository, and the main Cruise pipeline runs.&lt;/p&gt;
&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;Using Cruise Free Edition to run personal builds&lt;/h2&gt;
&lt;p&gt;The new 1.3 release of Cruise allows you to run more than one Agent on a single machine. The Cruise free edition license allows you to run as many of these local Agents as you like (but no remote Agents). So it is possible to set up a personal build server with a few Agents using the Cruise free edition.&lt;/p&gt;
&lt;p&gt;This is actually what we do in the Cruise team (partly to dogfood Cruise itself). We have a 4 core Ubuntu machine that runs 8 local Agents and a Cruise Server with a free license. There is a pipeline for each pairing station (yes we pair on everything) and we use this regularly to test our changes before we check in to the central repository.&lt;/p&gt;
&lt;h2 style=&quot;font-size:1.5em;&quot;&gt;Example&lt;/h2&gt;
&lt;p&gt;Create a local clone of the repository:&lt;/p&gt;
&lt;pre style=&quot;color:#000000;font-family:Verdana, Arial, Helvetica, sans-serif;font-size:small;margin:8px;&quot;&gt;
$ hg clone cruise cruise-personal
&lt;/pre&gt;
&lt;p&gt;Run hg serve:&lt;/p&gt;
&lt;pre style=&quot;color:#000000;font-family:Verdana, Arial, Helvetica, sans-serif;font-size:small;margin:8px;&quot;&gt;
$ cd cruise-personal
$ hg serve -v
listening at http://X.X.X.X:8000/ (bound to *:8000)
&lt;/pre&gt;
&lt;p&gt;Set up a pipeline with the new personal build:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://community.thoughtworks.com/files/9630d94c8b/personal-build.png&quot; alt=&quot;Personal build pipeline&quot;  class=&quot;dynImage&quot;  width=&quot;200&quot;/&gt;&lt;/p&gt;
&lt;p&gt;The personal build config looks like this:&lt;/p&gt;
&lt;pre style=&quot;color:#000000;font-family:Verdana, Arial, Helvetica, sans-serif;font-size:small;margin:8px;&quot;&gt;
&amp;lt;pipeline name=&quot;CCEDev05-X.X.X.X&quot;&amp;gt;
  &amp;lt;materials&amp;gt;
    &amp;lt;hg url=&quot;http://X.X.X.X:8000&quot; /&amp;gt;
  &amp;lt;/materials&amp;gt;
  &amp;lt;stage name=&quot;fast&quot;&amp;gt;
    &amp;lt;jobs&amp;gt;
      &amp;lt;job name=&quot;fast-1&quot;&amp;gt;
        &amp;lt;tasks&amp;gt;
          &amp;lt;ant target=&quot;-Drun=all -Divy.default.ivy.user.dir=target/ivy 
            -Dhelp.skip=true clean ut ft&quot;&amp;gt;
          &amp;lt;/ant&amp;gt;
        &amp;lt;/tasks&amp;gt;
        &amp;lt;resources&amp;gt;
          &amp;lt;resource&amp;gt;personal&amp;lt;/resource&amp;gt;
        &amp;lt;/resources&amp;gt;
      &amp;lt;/job&amp;gt;
     &amp;lt;/jobs&amp;gt;
  &amp;lt;/stage&amp;gt;
&amp;lt;/pipeline&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;Thanks to WPC and the Mingle team for their work on their build grid (which deserves a post of its own) and informed a lot of what we do with our personal builds.&lt;/p&gt;
&lt;h3&gt;Keywords&lt;/h3&gt;cruise mercurial personal&lt;h3&gt;File&lt;/h3&gt;&lt;a href=&quot;http://community.thoughtworks.com/files/9630d94c8b/personal-build.png&quot; class=&quot;HL_View_IconAndText HL_Link_File HL_Link_File_Image&quot; target=&quot;_file&quot;&gt;personal-build.png&lt;/a&gt; &lt;span class=&quot;count&quot;&gt;(40KB)&lt;/span&gt;</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/8c7619f15c</guid><pubDate>Thu, 18 Jun 2009 23:57:40 +0000</pubDate></item><item><title>a simple tool to manage artifacts repository with Cruise</title><link>http://community.thoughtworks.com/posts/e746dd83df</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/3b59f5aa54&quot;&gt;Qiao Liang 乔梁&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; Li Jian (TWer in China office) took few days to write ruby code to clean the artifacts repository of cruise automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; It is ruby code on google code (svn checkout http://cruisetools.googlecode.com/svn/trunk/ ). Anyone can check out to use.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; You can run it to clean the artifacts under the artifacts folder. If some files/folders need to be kept, just put the relative path of files/folders in the file &apos;foldersToBeKept.txt&apos; (One path in each line)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; Then run the script &apos;rake dirname=/var/lib/cruise-server/logs/pipelines time=1w&apos;, it will delete all folders which are generated 1 week ago except for the folders in the kept list.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; the param &apos;dirname&apos; is the absolute path for the repository,&lt;br /&gt;
&amp;nbsp;&amp;nbsp; the param &apos;time&apos; could be 1w, 2w, ....&amp;nbsp; (means to delete the folders n weeks ago)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1m, 2m, ....&amp;nbsp; (means to delete the folders n months ago)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2009-05-01 ... (meams to delete the folders before 2009-05-01)&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; you can run cron task to clean it. And&amp;nbsp; our approach is following.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;More&lt;/h3&gt;&lt;p&gt;We setup a pipeline called &apos;cleanArtifacts&apos; to clean the folder which is generated 1 week ago except for the ones in the list of folderToBeKept.txt.&lt;/p&gt;
&lt;p&gt;And the job in this pipeline will be run by the agent which is running on the same box of&amp;nbsp; Cruise server.&lt;/p&gt;
&lt;p&gt;We only want to keep the important artifacts and get rid of others. So we setup a subversion repository&amp;nbsp; say &apos;http://xx.xx.xx.xx:8080/svn/artifactsmanagement&apos;. And only one file &apos;foldersToBeKept.txt&apos; in the repository.&lt;/p&gt;
&lt;p&gt;&amp;lt;pipeline name=&quot;cleanArtifacts&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;materials&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;svn url=&quot;http://cruisetools.googlecode.com/svn/trunk/artifactsmanagement/lib&quot; dest=&quot;app&quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;svn url=&quot;http://xx.xx.xx.xx:8080/svn/artifactsmanagement/trunk&quot; username=&quot;yyy&quot; password=&quot;xxx&quot; dest=&quot;keptfolder&quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/materials&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;stage name=&quot;defaultStage&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;jobs&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;job name=&quot;clean&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tasks&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;exec command=&quot;/bin/bash&quot; args=&quot;-c &amp;amp;quot; cp&amp;nbsp; foldersToBeKept.txt ../app&amp;amp;quot;&quot; workingdir=&quot;keptfolder&quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;rake target=&quot;dirname=/var/lib/cruise-server/logs/pipelines time=1w&quot; workingdir=&quot;app&quot; /&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tasks&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/job&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/jobs&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/stages&amp;gt;&lt;br /&gt;
&amp;lt;/pipeline&amp;gt;&lt;/p&gt;
</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/e746dd83df</guid><pubDate>Wed, 17 Jun 2009 13:41:07 +0000</pubDate></item><item><title>使用Cruise和Mercurial实现PersonalBuild</title><link>http://community.thoughtworks.com/posts/3568de62df</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/3b59f5aa54&quot;&gt;Qiao Liang 乔梁&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;什么是个人预提交（Personal build）?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Personal build简单来说，就是开发人员在代码提交之前，先要自己在本地运行一次构建和测试代码，保证本地没有测试失败后，再将其提交到中央代码仓库。&lt;/p&gt;
&lt;h3&gt;More&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Personal build的痛处在哪里？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“提交代码之前，必须在本地运行并通过单元测试”是敏捷团队的原则之一。而随着新功能的增加，我们的单元测试越来越多，运行时间当然也就越来越长，那么开发人员等待的时间就长。&lt;/p&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;因此，正如在&lt;a href=&quot;http://www.infoq.com/cn&quot; rel=&quot;nofollow&quot;&gt;InfoQ&lt;/a&gt;&amp;nbsp;上的一篇&lt;a href=&quot;http://www.infoq.com/cn/articles/thoughtworks-practice-partv&quot; rel=&quot;nofollow&quot;&gt;关于持续集成实践的文章&lt;/a&gt;&amp;nbsp;所 述，我们在每台PairStation上都安装了一个虚拟机来运行自己提交前的单元测试。然而，每台虚拟机都运行自己的单元测试，也就是说，在运行时间上没有什么大的改进，还是需要三十分钟左右（因为还是在一台机器上运行），其好处是执行本地单元测试的同时，开发人员可以继续他们自己的工作，但本地单元测 试的时间并未缩短，反馈时间长的问题还是存在。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;如何解决这个问题？&lt;/strong&gt;&amp;nbsp;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;在一台机器上新安装一个&lt;a href=&quot;http://studios.thoughtworks.com/cruise&quot; rel=&quot;nofollow&quot;&gt;Cruise&lt;/a&gt;&amp;nbsp;，并在Pairstation的虚拟机上安装了一个&lt;a href=&quot;http://blog.csdn.net/tony1130/archive/2009/03/14/3989617.aspx&quot; rel=&quot;nofollow&quot;&gt;Cruise Agent&lt;/a&gt;&amp;nbsp;，让它连上这个Cruise，这样就成了个人构建持续集成服务器。&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;另外，在&lt;a href=&quot;posts/dd40aad8f9&quot; rel=&quot;nofollow&quot;&gt;目前尚未发布的Cruise R1.3&lt;/a&gt;&amp;nbsp;中，有个新功能就是：多个Agent可以运行于同一个机器上。因此，在那台安装有CruiseServer的PersonalBuild服务器上同时又启动了四个Agent。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;个人构建持续集成服务器就有至少八台Agent可以同时工作啦。如图1所示。
&lt;div&gt;
&lt;div id=&quot;jtay&quot; style=&quot;text-align:center;&quot;&gt;
&lt;div id=&quot;ypcr&quot;&gt;&lt;img style=&quot;width:600px;height:473px;border:0px;&quot; src=&quot;https://docs.google.com/File?id=dhpzzznh_3jtnnw2hg_b&quot; alt=&quot;&quot;  class=&quot;dynImage&quot;  width=&quot;200&quot;/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;&lt;em&gt;图1&lt;/em&gt;&amp;nbsp;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;由于团队使用的是&lt;a href=&quot;http://www.infoq.com/cn/articles/thoughtworks-practice-partiv&quot; rel=&quot;nofollow&quot;&gt;Mercurial&lt;/a&gt;&amp;nbsp;（分布式版本控制服务器），所以开发人员所要做的准备工作就是：&lt;/div&gt;
&lt;div&gt;（１）在自己的机器上再Clone一个本地的Repository，运行hg serve 启动该Repository的http服务。&lt;/div&gt;
&lt;div&gt;（２） 在Personalbuild Server上建立自己的一个Pipeline，该Pipeline的materials指向这个新建的Repository。且Pipeline上只有 一个Stage，同时利用Test-load-balancer将单元测试分成多个Job加入到该Stage中。&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;这样，利用Cruise的Job并行化和Agent的分布化，以及Mercurial的特点，使得每个人都相当于拥有八台Agent为其工作。&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;而建立PersonialBuild后的开发流程大致为如下步骤(见图2)：&lt;/div&gt;
&lt;div&gt;（１）开发人员对本地代码进行修改；&lt;/div&gt;
&lt;div&gt;（２）开发人员将代码放到本地预提交仓库中；&lt;/div&gt;
&lt;div&gt;（３）个人构建服务器发现本地预提交仓库的代码变化，触发个人的Pipeline进行构建；&lt;/div&gt;
&lt;div&gt;（４）开发人员重复（１）和（２），并关注自己的个人构建Pipeline的运行结果；&lt;/div&gt;
&lt;div&gt;（５）个人构建服务器重复（３）；&lt;/div&gt;
&lt;div&gt;（６）开发人员使自己的最后一次提交在个人构建服务器上通过所有测试；&lt;/div&gt;
&lt;div&gt;（７）开发人员将所有修改提交到中央代码仓库中；&lt;/div&gt;
&lt;div&gt;（８）团队集成构建服务器发现这些变化的代码，触发团队Pipeline的构建。&amp;nbsp;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;div id=&quot;faeo&quot; style=&quot;text-align:center;&quot;&gt;&lt;img style=&quot;width:631px;height:511px;border:0px;&quot; src=&quot;https://docs.google.com/File?id=dhpzzznh_4ctncqrpc_b&quot; alt=&quot;&quot;  class=&quot;dynImage&quot;  width=&quot;200&quot;/&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;&lt;em&gt;图2&lt;/em&gt;&amp;nbsp;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;其好处在于：&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;(1) 不需要太多的准备工作(原本就使用Mecurial)；&lt;/div&gt;
&lt;div&gt;(2) Cruise的分布式加快了个人构建与测试的反馈速度；&lt;/div&gt;
&lt;div&gt;(3) 更大的灵活性(开发人员可以有选择性的向中央代码库提交任意指定的本地版本)；&lt;/div&gt;
&lt;div&gt;(4) 促进开发人员频繁提交，运行测试；&lt;/div&gt;
&lt;div&gt;(5) 在团队持续集成环境中，失败的次数会大大减少；&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;具体准备工作：&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;(1) 建立本地代码库的复本&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hg clone cruise cruise-personal&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cd cruise-personal&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hg serve&lt;br /&gt;
(2) 启动一个agent，指向PersonalBuild 服务器&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mkdir cruise-personal-agent&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cp cruise/target/cruise-agent-1.3/* cruise-personal-agent&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cd cruise-personal-agent&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; java -jar agent-bootstrapper.jar ${your personal build IP address}&lt;br /&gt;
&lt;br /&gt;
(3) 在建立一个pipeline，使其Materials指向第1步中建立的本地代码库复本&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;具体工作过程：&lt;/strong&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;(1)&amp;nbsp; 频繁向本地checkin代码；&lt;/div&gt;
&lt;div&gt;(2) 需要个人构建时，使用命令&apos;hg push ../cruise-personal&apos;&lt;/div&gt;
&lt;div&gt;(3)个人构建服务器会发现代码的改变而构建。&lt;/div&gt;
&lt;div&gt;(4) 当需要向中心代码库提交时，使用命令&apos;hg pull --rebase&apos;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;注意：&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;
当 我们想要运行个人构建时，如果使用命令 &apos;hg push ../cruise-personal&apos;，你会得到信息说‘creating multiple heads’。假如你使用命令 &apos;hg push -f ../cruise-personal&apos; (注意那个 -f)，就会强制Push并创建multiple heads。&lt;/div&gt;
&lt;div&gt;在中心代码库上建立多个head是非常不好的。但是，对于个人的本地复本来说，无所谓。实际上，Cruise会发现并更新到最新的head上，而忽略旧的head。&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/3568de62df</guid><pubDate>Wed, 27 May 2009 05:11:06 +0000</pubDate></item><item><title>Cruise in the news</title><link>http://community.thoughtworks.com/posts/e88abe9881</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/c925478e94&quot;&gt;Jez Humble&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In an exciting milestone for us, we had &lt;a href=&quot;http://ruprict.wordpress.com/2009/04/16/cruise-the-next-ci-framework/&quot; rel=&quot;nofollow&quot;&gt;our first blog review&lt;/a&gt; from somebody who has never worked at ThoughtWorks.&lt;/p&gt;
&lt;p&gt;Also Julian Simpson, who runs a blog called &lt;a href=&quot;http://www.build-doctor.com/&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-style:italic;&quot;&gt;The Build Doctor&lt;/span&gt;&lt;/a&gt;, has put up a video interview (with transcription) he did with me a couple of weeks back. We discuss &lt;a href=&quot;http://timothyfitz.wordpress.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/&quot; rel=&quot;nofollow&quot;&gt;continuous deployment&lt;/a&gt;, the value proposition of Cruise, the competition, and a bit about Cruise&apos;s history and our future plans. It&apos;s in &lt;a href=&quot;http://www.build-doctor.com/2009/04/16/continuous-interviews-jez-humble-cruise&quot; rel=&quot;nofollow&quot;&gt;two&lt;/a&gt; &lt;a href=&quot;http://www.build-doctor.com/2009/04/21/continuous-interviews-jez-humble-part-ii&quot; rel=&quot;nofollow&quot;&gt;parts&lt;/a&gt;.&lt;/p&gt;
</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/e88abe9881</guid><pubDate>Tue, 28 Apr 2009 20:57:17 +0000</pubDate></item><item><title>Parallelize your junit tests with the test load balancer</title><link>http://community.thoughtworks.com/posts/4dd1349735</link><description>&lt;p&gt;&lt;em&gt;Entry by &lt;a href=&quot;http://community.thoughtworks.com/people/85ce7690d9&quot;&gt;Li Yanhui&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Entry&lt;/h3&gt;&lt;p&gt;&lt;em&gt;&lt;span style=&quot;font-style:normal;&quot;&gt;One of Cruise&apos;s most valuable features is that it&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://studios.thoughtworks.com/cruise-continuous-integration/multi-platform-testing&quot; rel=&quot;nofollow&quot;&gt;&lt;span style=&quot;font-style:normal;&quot;&gt;runs jobs in parallel.&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-style:normal;&quot;&gt;&amp;nbsp;To make long running test suites go faster, you can simply split your long running test suite into multiple suites and create jobs for each one. Given enough build agents, Cruise can run all jobs within a specified stage simultaneously, which means your long running testing can be done in a snap.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But wait, why do I need to &lt;strong&gt;manually&lt;/strong&gt; split my test suites? Enter&amp;nbsp;the&amp;nbsp;&lt;a href=&quot;http://code.google.com/p/test-load-balancer/&quot; rel=&quot;nofollow&quot;&gt;test load balancer&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;More&lt;/h3&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For example, I have a unit-test target in my ant build script which includes more than 100 tests. Those tests are organized by corresponding packages, so it&apos;s hard to split them in an easy way. It&apos;s a burden to users of Cruise.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;What is the test load balancer?&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The TLB (test load balancer) is a custom ant task that can split test suites written in junit for you. With TLB, you can simply specify in Cruise how many batches you want to split your test suite into. TLB talks to Cruise to work out how many batches your suits is split into and which of these batches the current job should do.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;How do I use it?&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
First, download&amp;nbsp;&lt;a href=&quot;http://code.google.com/p/test-load-balancer&quot; rel=&quot;nofollow&quot;&gt;test load balancer&lt;/a&gt;&amp;nbsp;jar file and add it to the classpath of ant build script.&lt;br /&gt;
&lt;br /&gt;
Then, change your build.xml as following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;&lt;strong&gt;typedef&lt;/strong&gt;&amp;nbsp;name=&quot;filter-fileset&quot; classname=&quot;com.googlecode.tlb.support.junit.FilterFileSet&quot; classpathref=&quot;classpath&quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;junit&amp;gt;&lt;br /&gt;
&amp;lt;batchtest todir=&quot;target/test-results&quot;&amp;gt;&lt;br /&gt;
&amp;lt;&lt;strong&gt;filter-fileset&lt;/strong&gt;&amp;nbsp;dir=&quot;target/test-classes&quot; includes=&quot;**/*Test.class&quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/batchtest&amp;gt;&lt;br /&gt;
&amp;lt;classpath refid=&quot;classpath&quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/junit&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Third, change your Cruise configuration. You will need to create a job for each batch of tests you want to run. Cruise makes sure these jobs will run in parallel. You need to make each job run the same ant task - the one you put the typedef above into. But you use a naming convention so that the TLB can recognize them.&lt;/p&gt;
&lt;p&gt;For example, say you have a unit test job running on Linux environment named &apos;ut-linux&apos; that has 100 tests and takes 10 minutes. You want to split it to three batches. You simply replace the old &apos;ut-linux&apos; job with three jobs: &apos;ut-linux-1&apos;, &apos;ut-linux-2&apos;, &apos;ut-linux-3&apos;. Each job should do exactly the same thing as the original ut-linux job.&lt;/p&gt;
&lt;p&gt;That&apos;s it - you&apos;re done! Now&amp;nbsp;you can get the benefits of faster, parallelized test running with no changes to your junit test suite.&lt;/p&gt;
&lt;p&gt;Further information about the&amp;nbsp;&lt;a href=&quot;http://code.google.com/p/test-load-balancer/&quot; rel=&quot;nofollow&quot;&gt;test load balancer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description><guid isPermaLink="true">http://community.thoughtworks.com/posts/4dd1349735</guid><pubDate>Tue, 14 Apr 2009 04:46:07 +0000</pubDate></item></channel></rss>