<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>teamcity &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/teamcity/</link>
	<description>Feed of posts on WordPress.com tagged "teamcity"</description>
	<pubDate>Tue, 08 Dec 2009 00:10:14 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Concept to handle minimal and maximal tests in a maven project]]></title>
<link>http://ahoehma.wordpress.com/2009/11/26/concept-to-handle-minimal-and-maximal-tests-in-a-maven-project/</link>
<pubDate>Thu, 26 Nov 2009 13:03:29 +0000</pubDate>
<dc:creator>Andreas Höhmann</dc:creator>
<guid>http://ahoehma.wordpress.com/2009/11/26/concept-to-handle-minimal-and-maximal-tests-in-a-maven-project/</guid>
<description><![CDATA[In real world applications we have all too often external dependencies in test cases. Sometimes thes]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In real world applications we have all too often external dependencies in test cases. Sometimes theses third party are not always available (i.e. remote webservices).</p>
<p>For continuous integration I want check a minimal set of tests but for my local development i want check a maximal set of tests. I want run my tests on command line (via <a href="http://maven.apache.org/" target="_blank">maven</a>) and in eclipse (via <a href="http://testng.org/doc/eclipse.html" target="_blank">testng-plugin</a>).</p>
<p>Here is my idea to do that &#8230;</p>
<p>My project super pom defines 2 profiles:</p>
<ul>
<li>test-min
<ol>
<li> active by default</li>
<li>exclude testng groups (online-tests, thirdparty-tests,&#8230;)</li>
</ol>
</li>
<li>test-max
<ol>
<li>run a defined testng suite</li>
<li>the suite defines a maximal set of test (all testng groups)</li>
</ol>
</li>
</ul>
<pre class="brush: xml;">
&#60;profiles&#62;
  &#60;profile&#62;
    &#60;id&#62;test-min&#60;/id&#62;
    &#60;activation&#62;
      &#60;activeByDefault&#62;true&#60;/activeByDefault&#62;
    &#60;/activation&#62;
    &#60;build&#62;
      &#60;plugins&#62;
        &#60;plugin&#62;
          &#60;artifactId&#62;maven-surefire-plugin&#60;/artifactId&#62;
          &#60;inherited&#62;true&#60;/inherited&#62;
          &#60;configuration&#62;
            &#60;excludedGroups&#62;${excludedTestGroups}&#60;/excludedGroups&#62;
          &#60;/configuration&#62;
        &#60;/plugin&#62;
      &#60;/plugins&#62;
    &#60;/build&#62;
  &#60;/profile&#62;
  &#60;profile&#62;
    &#60;id&#62;test-max&#60;/id&#62;
    &#60;build&#62;
      &#60;plugins&#62;
        &#60;plugin&#62;
          &#60;artifactId&#62;maven-surefire-plugin&#60;/artifactId&#62;
          &#60;inherited&#62;true&#60;/inherited&#62;
          &#60;configuration&#62;
            &#60;suiteXmlFiles&#62;
              ${basedir}/src/test/resources/Testsuite.xml
            &#60;/suiteXmlFiles&#62;
          &#60;/configuration&#62;
        &#60;/plugin&#62;
      &#60;/plugins&#62;
    &#60;/build&#62;
  &#60;/profile&#62;
&#60;/profiles&#62;
&#60;properties&#62;
  &#60;excludedTestGroups&#62;online,integration,thirdparty&#60;/excludedTestGroups&#62;
&#60;/properties&#62;
</pre>
<p>Each subproject must define a testng <strong>src/test/resources/Testsuite.xml</strong>:</p>
<pre class="brush: xml;">
&#60;!DOCTYPE suite SYSTEM &#34;http://testng.org/testng-1.0.dtd&#34;&#62;
&#60;suite name=&#34;TestSuite for Foobar&#34;&#62;
  &#60;test name=&#34;Online Tests&#34;&#62;
    &#60;packages&#62;
      &#60;package name=&#34;de.foobar.*&#34; /&#62;
    &#60;/packages&#62;
    &#60;groups&#62;
      &#60;run&#62;
        &#60;include name=&#34;online&#34; /&#62;
      &#60;/run&#62;
    &#60;/groups&#62;
  &#60;/test&#62;
  &#60;test name=&#34;Integration Tests&#34;&#62;
    &#60;packages&#62;
      &#60;package name=&#34;de.foobar.*&#34; /&#62;
    &#60;/packages&#62;
    &#60;groups&#62;
      &#60;run&#62;
        &#60;include name=&#34;integration&#34; /&#62;
      &#60;/run&#62;
    &#60;/groups&#62;
  &#60;/test&#62;
  &#60;test name=&#34;Thirdparty Tests&#34;&#62;
    &#60;packages&#62;
      &#60;package name=&#34;de.foobar.*&#34; /&#62;
    &#60;/packages&#62;
    &#60;groups&#62;
      &#60;run&#62;
        &#60;include name=&#34;thirdparty&#34; /&#62;
      &#60;/run&#62;
    &#60;/groups&#62;
  &#60;/test&#62;
  &#60;!-- Each project can define MORE groups: i.e. &#34;interactive&#34; --&#62;
  &#60;test name=&#34;Other Tests&#34;&#62;
    &#60;packages&#62;
      &#60;package name=&#34;de.foobar.*&#34; /&#62;
    &#60;/packages&#62;
    &#60;groups&#62;
      &#60;run&#62;
        &#60;exclude name=&#34;online&#34; /&#62;
        &#60;exclude name=&#34;integration&#34; /&#62;
        &#60;exclude name=&#34;thirdparty&#34; /&#62;
        &#60;!-- Each project can define MORE groups: i.e. &#34;interactive&#34; --&#62;
      &#60;/run&#62;
    &#60;/groups&#62;
  &#60;/test&#62;
&#60;/suite&#62;
</pre>
<p>If the sub project defines more exclude groups (i.e. a additional &#8220;interactive&#8221; group) then the pom must overwrite the excludedTestGroups property:</p>
<pre class="brush: xml;">
&#60;properties&#62;
  &#60;excludedTestGroups&#62;online,integration,thirdparty,interactive&#60;/excludedTestGroups&#62;
&#60;/properties&#62;
</pre>
<p>To check the correct configuration of the two profiles we can use <strong>help:effective-pom</strong>:</p>
<p><code>mvn -Ptest-min help:effective-pom &#124; less</code></p>
<pre class="brush: xml;">
&#60;plugin&#62;
  &#60;artifactId&#62;maven-surefire-plugin&#60;/artifactId&#62;
  &#60;configuration&#62;
    &#60;excludedGroups&#62;online,integration,thirdparty,interactive&#60;/excludedGroups&#62;
  &#60;/configuration&#62;
&#60;/plugin&#62;
</pre>
<p><code>mvn -Ptest-max help:effective-pom &#124; less</code></p>
<pre class="brush: xml;">
&#60;plugin&#62;
  &#60;artifactId&#62;maven-surefire-plugin&#60;/artifactId&#62;
  &#60;configuration&#62;
    &#60;suiteXmlFiles&#62;
      &#60;suiteXmlFile&#62;d:\foobar\src/test/resources/Testsuite.xml&#60;/suiteXmlFile&#62;
    &#60;/suiteXmlFiles&#62;
  &#60;/configuration&#62;
&#60;/plugin&#62;
</pre>
<p>Now I can run min/max tests for each project which depend on the above super-pom. The test-min is the default profile and would be used on the continuous integration system (i.e. <a href="http://www.jetbrains.com/teamcity/">TeamCity</a>).</p>
<p>Try it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Configuring TeamCity for Subversion]]></title>
<link>http://unstableterrain.wordpress.com/2009/10/14/configuring-teamcity-for-subversion/</link>
<pubDate>Tue, 13 Oct 2009 23:00:40 +0000</pubDate>
<dc:creator>Trent</dc:creator>
<guid>http://unstableterrain.wordpress.com/2009/10/14/configuring-teamcity-for-subversion/</guid>
<description><![CDATA[At work, we&#8217;ve just started using TeamCity as our continuous integration server. The app itsel]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>At work, we&#8217;ve just started using <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> as our <a href="http://en.wikipedia.org/wiki/Continuous_integration">continuous integration</a> server. The app itself is very slick, but the documentation is spotty. There doesn&#8217;t seem to be a simple example of how to set up TeamCity 4.5.x with <a href="http://subversion.tigris.org/">subversion</a> anywhere on their site (or on the net either, although they&#8217;re probably hidden away inside nabble or something). Happily, I can remedy this.</p>
<h3>Setting up a VCS Root</h3>
<p>You&#8217;ll need to set up a new VCS root for each project. Let&#8217;s say we&#8217;re setting up SVN for a project called <tt>unstableterrain</tt>. Setting up the project itself is simple, so I&#8217;ll assume you&#8217;re up to the challenge.</p>
<p>For the sake of brevity, let&#8217;s imagine the subversion repository is set up like so:</p>
<pre>root
  &#124;---- trunk
  &#124;---- branches
  &#124;      &#124;---- ...
  &#124;      &#124;---- v04.02.00b
  &#124;      &#124;---- v04.02.01b
  &#124;      &#124;---- v04.02.02b
  &#124;      &#124;---- v04.03.00b
  &#124;      \---- ...
  \----tags
         &#124;---- v04.02.00.1
         &#124;---- v04.02.00.2
         &#124;---- ...
         \---- v04.03.00.266</pre>
<p>So, onto the instructions.</p>
<ol>
<li> Add a VCS root:
<ul>
<li>name = &#8216;unstableterrain via SVN&#8217;</li>
<li> type = Subversion</li>
<li>URL = <tt>http://my.svn.server:9001/svn/unstableterrain/</tt></li>
<li>set your username and password accordingly (if your svn server allows anonymous checkouts and your build script doesn&#8217;t check anything in, then you can skip this entirely)</li>
<li>Labelling rules: Add trunk, and a rule for every branch you plan on using. This, unfortunately, is manual in the version I&#8217;m using (4.5) because wildcards don&#8217;t work. In this example, you&#8217;d enter
<dl>
<dd><tt>+:trunk=&#62;tags</tt></dd>
<dd><tt>+:branches/v04.02.00b=&#62;tags</tt></dd>
<dd><tt>+:branches/v04.02.01b=&#62;tags</tt> </dd>
<dd><tt>+:branches/v04.02.02b=&#62;tags</tt></dd>
<dd><tt>+:branches/v04.03.00b=&#62;tags</tt></dd>
<dd>&#8230; you get the idea</dd>
</dl>
</li>
<li>Test the connection</li>
<li>Save; you&#8217;re done.</li>
</ul>
</li>
</ol>
<h3>Attaching your VCS root to a project configuration</h3>
<p>Say we&#8217;re setting up a project config called &#8220;unstableterrain v04.03.00 snapshot&#8221;. You want to check out this branch and run builds against it, incrementing the build label and tagging.</p>
<ol>
<li>Add general details
<ul>
<li> build number format = v04.03.00.{0}</li>
<li> Artifact paths: these map from the results of your build to directories under the artifacts node, e.g.:
<dl>
<dd><tt>build/dist/*.war =&#62; dist</tt> </dd>
<dd><tt>build/emma/all/**/*.html =&#62; emma</tt> </dd>
<dd><tt>build/tmp/checkstyle/**/*.html =&#62; checkstyle</tt> </dd>
</dl>
</li>
</ul>
</li>
<li>Add VCS settings
<ul>
<li>Attach the existing VCS root you specified earler (i.e. &#8216;unstableterrain via SVN&#8217;)</li>
<li>Edit checkout rules on the VCS, since we want to tell SVN which branch to checkout for this configuration:
<dl>
<dd><tt>+:branches/v04.03.00b/=&#62;.</tt> </dd>
</dl>
</li>
<li>VCS checkout mode = automatically on agent</li>
<li>VCS Labelling mode = Successful only</li>
<li>VCS Labelling pattern = v04.03.00.%system.build.number%</li>
<li>Choose VCS roots to label: &#8216;unstableterrain via SVN&#8217; VCS root</li>
</ul>
</li>
<li>Edit build runner
<ul>
<li>add your settings</li>
</ul>
</li>
<li>Build Triggering
<ul>
<li>add your settings</li>
</ul>
</li>
<li>Save</li>
</ol>
<p>And that&#8217;s it.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Continuous Integration with Hudson, TeamCity]]></title>
<link>http://boymeetstechnology.wordpress.com/2009/10/08/continuous-integration-with-hudson-teamcity/</link>
<pubDate>Thu, 08 Oct 2009 23:26:02 +0000</pubDate>
<dc:creator>Stephen</dc:creator>
<guid>http://boymeetstechnology.wordpress.com/2009/10/08/continuous-integration-with-hudson-teamcity/</guid>
<description><![CDATA[This was an interview question for me two jobs ago: &#8220;Have you heard of Continuous Integration?]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This was an interview question for me two jobs ago: &#8220;Have you heard of Continuous Integration?&#8221; &#8211; my answer was &#8220;No sir, but the project I worked on was a large scale integration effort and I have been involved in some serious technology &#38; team integrations rather continuously &#8211; is that close enough?&#8221;.</p>
<p>The interviewer said &#8211; &#8220;no, that&#8217;s not that, if you haven&#8217;t heard of it then you should look into it&#8221;.</p>
<p>And now &#8211; two jobs later. I have been involved in setting up some form of CI process for my current and past two projects. I have to say, I&#8217;m a big fan of the whole processes now. I can&#8217;t imagine any projects these days running without some sort of CI</p>
<p>Here&#8217;s the definition by Martin Fowler the UML guru:</p>
<p><em>Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily &#8211; leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. This article is a quick overview of Continuous Integration summarizing the technique and its current usage. </em></p>
<p>(If your project doesn&#8217;t have a CI you should seriously consider adding it. It&#8217;ll keep your code cleaner, your product much better. More than that, it&#8217;ll make your life and the life of every one involved in the project so much easier.)</p>
<p>I have worked with a couple of products so far &#8211; JetBrain&#8217;s <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> and <a href="https://hudson.dev.java.net/">Hudson</a>.</p>
<p>Hudson is completely free &#8211; it&#8217;s simple &#38; straight forward. Easy to manage configurations, and the whole concept is rather simple. Very easy to get it up and running in no time. Team City on the other hand is from JetBrains. I have heard intelliJ from JetBrains is the best IDE in the world, but I haven&#8217;t had a chance to play with it yet. I can&#8217;t speak for intelliJ, but I can really speak for TeamCity.</p>
<p>TeamCity is just awesome. The product description goes like this &#8220;<strong>Distributed Build Management and Continuous Integration Server</strong>&#8221; (we techies love all things distributed, yes). The product comes with a free and commercial version, the free version supports 3 build agents (for distributed builds) and 20 users. For small teams this is good enough.</p>
<p>The best part about TeamCity is it&#8217;s Eclipse plugin and the RemoteRun feature. The plugin lets you select a subset of files you have updated since your last checkout and submit them for a remote build run &#8211; the server &#8220;does a fresh checkout of the entire code base, overwrites the files you submitted and runs through the compile/test, etc&#8221;. And all the while you could be watching the live server logs in your Eclipse plugin &#8211; life can&#8217;t get any better than this.</p>
<p>I am using Hudson now and I like it so far. One small limitation &#8211; it doesn&#8217;t let me checkout two projects from two different branches. The only way of doing this is through two separate projects one lined up after another, or use command line checkout using the &#8220;Execute shell&#8221; option. The documentation says Hudson is also a Distributed server, but I haven&#8217;t configured Build agents so I can&#8217;t speak for it. Any one has any experience on this?</p>
<p>Anyways&#8230;.. Go Continuous Integration&#8230;.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Start with continuous integration]]></title>
<link>http://implementingagile.wordpress.com/2009/10/02/start-with-continuous-integration/</link>
<pubDate>Fri, 02 Oct 2009 14:56:14 +0000</pubDate>
<dc:creator>Paul Harrington</dc:creator>
<guid>http://implementingagile.wordpress.com/2009/10/02/start-with-continuous-integration/</guid>
<description><![CDATA[Hi all, it&#8217;s been a few weeks and there&#8217;s been quite a lot going on chez Harrington. My ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Hi all, it&#8217;s been a few weeks and there&#8217;s been quite a lot going on chez Harrington.</p>
<p>My last day at <a href="http://www.uswitch.com">uSwitch</a> has come and gone and I found it harder to leave than I thought I would. They have an amazing group of developers and managers and it&#8217;s still a fantastic place to work but ulitmately I think it was time for me to move on. Incidentally, for anyone reading this, if you get an opportunity to work there then grab it with both hands!</p>
<p>So I’ve had some time off as I don’t start with my new company for another 10 days (after a well deserved holiday in Lanzarote) but I did want to catch up with them before I went away so I headed over to their offices for an afternoon this week.</p>
<p>My first impressions of the company, team and general set up was excellent – a friendly bunch who clearly want to make their software great. The developers working there seem like good guys, skilled and eager to pick up Agile practices and processes and I&#8217;m really excited about seeing how far we can take Agile.</p>
<p>So where will I start?</p>
<p>Well, I’m not going to give my entire game plan away (gotta keep the reader interested for future instalments) but I’ve got a whole barrel load of ideas around <a href="//subversion.tigris.org/">Subversion</a> branching strategies, <a href="//www.martinfowler.com/bliki/TestDrivenDevelopment.html">TDD</a> (test driven development), <a href="//behaviour-driven.org/">BDD</a> (behaviour driven development) and of course <a href="//martinfowler.com/articles/continuousIntegration.html">continuous integration</a>.</p>
<p>Of these I think (and it’s an opinion shared by a lot of my colleagues) continuous integration is the obvious starting point when trying to make any shift towards agile. Because once you’ve got it installed and running, you’re always aware of when your build breaks due to subversion merging issues. And once you start to introduce unit tests, you’ll get real time feedback if you’ve broken any logic in your code. This is the foundation you need in order to have confidence in your system moving forward, allowing you to continue to work and refactor as you need.</p>
<p>So we’ve ordered <a href="//www.jetbrains.com/teamcity">TeamCity</a> for our build server and I’m planning on learning more about <a href="//martinfowler.com/articles/rake.html">Rake</a> as our build language as it is clearly more flexible than NAnt and I’d like more of a chance to learn Ruby. On a side note we’ve also ordered <a href="//www.jetbrains.com/resharper">ReSharper</a> as our refactoring tool (because Visual Studio is essentially unusable without it).</p>
<p>All in all, I’m confident these tiny changes will give us the start we need to take our first steps down the agile road. There&#8217;s a lot more we can do but as the cliché goes, I’m not going to try and run before we can walk.</p>
<p>I&#8217;ll keep you updated on how we&#8217;re getting on.</p>
<p>Until next time</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TeamCity - Using Personal Builds to help improve cycle time]]></title>
<link>http://devblog.point2.com/2009/09/03/teamcity-using-personal-builds-to-help-improve-cycle-time/</link>
<pubDate>Fri, 04 Sep 2009 00:16:53 +0000</pubDate>
<dc:creator>brianrichardson</dc:creator>
<guid>http://devblog.point2.com/2009/09/03/teamcity-using-personal-builds-to-help-improve-cycle-time/</guid>
<description><![CDATA[So you are working on a large project, many developers committing regularly to the same code base, y]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>So you are working on a large project, many developers committing regularly to the same code base, you run all the unit tests, commit and you break the build. Now everyone on your team is angry (As they should be!). How could this have happened when you ran all of the tests? The reason is that you did not update before running tests locally and committing. The problem is that constantly updating and building can waste a lot of time. Even if you do update, run all tests, then commit, there is still a chance another developer made a commit during that cycle. The solution: Team City Personal Builds.</p>
<h4>Personal Builds</h4>
<p>The great people at <a href="http://www.jetbrains.com/">JetBrains</a> have a feature in <a href="http://www.jetbrains.com/teamcity/index.html">TeamCity</a> that allows you to use your build server build agents for &#8220;Personal Builds&#8221;. More great news is that TeamCity plugins that make use of this interesting TeamCity feature are available for IDEs such as IntelliJ and Visual Studio. </p>
<p>So now when you use your IDE tool with the TeamCity plugin you would use the &#8220;Remote Run&#8221; option to make your commit. TeamCity will then spin up a personal build, apply your code changes to a fresh checkout of the repository, build, and run all unit tests. If your &#8220;Personal Build&#8221; passes, your code changes will be committed. Now, here is the great part, if it fails, your code changes will NOT be committed, and you will be notified of the failure.</p>
<p>This feature of TeamCity allows developers to get out of the update, run all tests, and commit cycle and offload some of that work to their TeamCity server. </p>
<h4>IntelliJ Plugin Setup</h4>
<ul>
<li>File-&#62;Settings-&#62;Plugins</li>
<li>Click on the &#8220;Available&#8221; tab</li>
<li>In the search box enter &#8220;TeamCity&#8221; (The option JetBrians TeamCity Plugin should show up in the list)</li>
<li>Right click on the plugin and select &#8220;Download and install&#8221;</li>
<li>You should see a TeamCity option on your IntelliJ toolbar</li>
<li>Enter your TeamCity credentials, setup your notifications</li>
</ul>
<p>So now, when you commit use TeamCity &#8211; &#62; Remote Run rather than using the Version Control menu. You will be notified if your commit is accepted or rejected.</p>
<h4>Visual Studio Plugin Setup</h4>
<p>To download the Plugin, login to your TeamCity server, go to the &#8220;My Settings &#38; Tools&#8221; page. You will find a download link for the plugin in the &#8220;TeamCity Tools&#8221; panel on the righthand side of the page.</p>
<p>by <a href="http://devblog.point2.com/author/brianrichardson/">Brian Richardson</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Voice Build notification plug-in for TeamCity]]></title>
<link>http://kain64b.wordpress.com/2009/08/30/108/</link>
<pubDate>Sun, 30 Aug 2009 04:48:44 +0000</pubDate>
<dc:creator>kain64b</dc:creator>
<guid>http://kain64b.wordpress.com/2009/08/30/108/</guid>
<description><![CDATA[Idea: make a plugin for TeamCity integration server that can say after build: &#8220;WTF!!! Project ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Idea: make a plugin for TeamCity integration server  that can say after build: &#8220;WTF!!! Project XXX build is failed!!!&#8221; or &#8220;Good job!&#8221;.
</p>
<ol>
<li>I have writen a small program using Microsoft speech object library on C#:
</li>
<p>Open text file and read all text from file aloud:
</p>
<p>[CODE language="csharp"]<br />
class Program {<br />
     static void Main(string[] args) {<br />
         if (args.Length != 1)<br />
            throw new InvalidOperationException(&#8220;1 pameter&#8221;);<br />
         var text = File.ReadAllText(args[0]);<br />
         var spVoice = new SpVoice();<br />
         spVoice.Speak(text, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);<br />
      }<br />
   }<br />
[/CODE]</p>
<p>
 </p>
<p>
<li>And I have writen notification plugin:</li>
</ol>
<p>Notifier class must implement jetbrains.buildServer.notification.Notificator.
</p>
<p>Notifier contains:
</p>
<ul>
<li>notifyBuildStarted &#8211; called when build started,
</li>
<li>notifyBuildSuccessful – called when build succeed,
</li>
<li>notifyBuildFailed &#8211; called when build  failed,
</li>
<li>notifyBuildFailing &#8211; called when build failing (for example on 1-st test fail in build),
</li>
<li>notifyBuildProbablyHanging &#8211; called if somebody make hang operation in out build.
</li>
</ul>
<p> It&#8217;s necessary to prepare artifacts for building plugin. I&#8217;m using Maven2 for missing artifact resolving. </p>
<p> User must define output file name (with build result information) and reader program in web form.
</p>
<p><img src="http://kain64b.files.wordpress.com/2009/08/083009_0448_1.png">
	</p>
<p>Two editable fields are created  in constructor:
</p>
<p>[CODE language="java"]<br />
public SoundNotificator(NotificatorRegistry notificatorRegistry) throws IOException {<br />
        ArrayList&#60;UserPropertyInfo&#62; userProps = new ArrayList&#60;UserPropertyInfo&#62;();<br />
       userProps.add(new UserPropertyInfo(_OUTPUT_FILE, _OUTPUT_FILE)); &#8212;&#8212;&#8212;&#8212;text box for outputfile<br />
        userProps.add(new UserPropertyInfo(_READER_PROGRAM, _READER_PROGRAM)); &#8212;- text box for reader program<br />
        notificatorRegistry.register(this, userProps);<br />
<    }<br />
[/CODE]</p>
<p>To read values from that text fields I create NotificatorPropertyKey&#8217;s and send 2 parametrs to constructor: 1<sup>st</sup> &#8211; string plugin type, 2<sup>nd</sup> &#8211; string that are passing into UserPropertyInfo object, when properties are registered in Notificator ctor. And finaly we can run reader app from plugin &#8220;Process p = Runtime.getRuntime().exec(executeProgram);&#8221;
</p>
<p>Notifier full source code:<br />
<a href="http://code.google.com/p/soundnotification">http://code.google.com/p/soundnotification</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Building .NET Solution with Rake and TeamCity]]></title>
<link>http://andypike.wordpress.com/2009/08/08/building-net-solution-with-rake-and-teamcity/</link>
<pubDate>Sat, 08 Aug 2009 22:33:41 +0000</pubDate>
<dc:creator>Andy</dc:creator>
<guid>http://andypike.wordpress.com/2009/08/08/building-net-solution-with-rake-and-teamcity/</guid>
<description><![CDATA[I&#8217;ve been reading through my Ruby books and came across Rake. Rake is a Ruby build program sim]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been reading through my Ruby books and came across Rake. Rake is a Ruby build program similar to NAnt or MSBuild but instead of writing XML, you use Ruby instead. Now that opens all sorts of doors, so I thought I&#8217;d see if I could get Rake to build a .NET solution and take it from there.</p>
<p>First things first, if you want to do this you will need to <a href="http://www.ruby-lang.org/en/downloads/" target="_blank">download and install Ruby</a>, luckily for us, Rake is included. You will need to reboot after to ensure your PATH is updated.</p>
<p>Now we are ready to rumble. First thing I wanted to try was just compiling a solution – nice and simple. There were a few samples around the interweb, and I soon created the following:</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">DOT_NET_PATH = <span style="color:#006080;">"#{ENV["</span>SystemRoot<span style="color:#006080;">"]}\\Microsoft.NET\\Framework\\v3.5"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">SOURCE_PATH = <span style="color:#006080;">"../src"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">CONFIG = <span style="color:#006080;">"Release"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">task :<span style="color:#0000ff;">default</span> =&#62; [<span style="color:#006080;">"build:all"</span>]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :all =&#62; [:compile]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    desc <span style="color:#006080;">"Build solution using MSBuild."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :compile <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Compiling Solution..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        solutions = FileList[<span style="color:#006080;">"#{SOURCE_PATH}/**/*.sln"</span>]</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        solutions.each <span style="color:#0000ff;">do</span> &#124;solution&#124;</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">          sh <span style="color:#006080;">"#{DOT_NET_PATH}/msbuild.exe /p:Configuration=#{CONFIG} #{solution} /t:Rebuild"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">end</pre>
</div>
</div>
<p>Save this file as <strong>“rakefile.rb”</strong> and put it in a folder called <strong>“build”</strong> which is at the same level as the <strong>“src”</strong> folder. Then at a command prompt, navigate to the build folder and use the following command:</p>
<pre>C:\MyRakeSample\build&#62;rake</pre>
<p>It worked!</p>
<p>Inside the Rake file we define the default build task as the <strong>:all </strong>task that is inside our <strong>build</strong> namespace. This task currently consists of one task <strong>:compile. </strong>The <strong>:compile</strong> task searches the <strong>src</strong> folder for any solution files and the builds them using MSBuild in release.</p>
<p>That was pretty easy and worked without a hitch. So next, I wanted to list the things I wanted my new build script to do:</p>
<ol>
<li>Get the current SVN revision number</li>
<li>Update all AssemblyInfo.cs files with a new version number that contains this SVN rev number</li>
<li>Build the solution (as above)</li>
<li>Run NUnit tests</li>
<li>Create test coverage report</li>
<li>Copy all the files that need to be deployed (excluding those that don’t)</li>
<li>Zip up these files into a deployment package</li>
<li>Integrate as much as possible with TeamCity</li>
<li>Should be able to run the same build script locally as well as with TeamCity</li>
</ol>
<p>It took a little but I got it working. <a href="http://aardvark-cms.googlecode.com/svn/trunk/build/rakefile.rb" target="_blank">You can see the full file here</a>. Below is a breakdown of each section:</p>
<h4></h4>
<h3>Getting the current SVN revision number</h3>
<p>First off, you’ll need to get the <a href="http://www.collab.net/downloads/subversion/" target="_blank">SVN command line client downloaded and installed</a>. You will need to reboot after to ensure your PATH is updated.</p>
<p>I decided to add a new :init task that should clean up, create folders and get the SVN HEAD revision number. So here is the new code I’ve added:</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">require <span style="color:#006080;">'rexml/document'</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">....</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">OUTPUT_PATH = <span style="color:#006080;">"output"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">SVN_LOG_PATH = <span style="color:#006080;">"#{OUTPUT_PATH}/svn_log.xml"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">ARTIFACTS_PATH = <span style="color:#006080;">"#{OUTPUT_PATH}/artifacts"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">SVN_URL = <span style="color:#006080;">"http://aardvark-cms.googlecode.com/svn/trunk/"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">VERSION_MAJOR_MINOR_BUILD = <span style="color:#006080;">"0.1.0"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :all =&#62; [:init, :compile]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    ....</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    desc <span style="color:#006080;">"Perform the required initial tasks."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :init <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Performing Initialization..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Creating folders..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        Dir.mkdir(OUTPUT_PATH)</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        Dir.mkdir(ARTIFACTS_PATH)</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Getting SVN revision number and saving to #{SVN_LOG_PATH}..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        sh <span style="color:#006080;">"svn log --xml --revision HEAD #{SVN_URL} &#62; \"#{SVN_LOG_PATH}\""</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        log = REXML::Document.<span style="color:#0000ff;">new</span> File.<span style="color:#0000ff;">new</span>(SVN_LOG_PATH)</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        logEntry = log.root.elements[<span style="color:#006080;">"logentry"</span>]</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        $svn_revision = logEntry.attributes[<span style="color:#006080;">"revision"</span>]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        $svn_message = logEntry.elements[<span style="color:#006080;">"msg"</span>].text</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        VERSION = <span style="color:#006080;">"#{VERSION_MAJOR_MINOR_BUILD}.#{$svn_revision}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Revision #{$svn_revision} found with message: #{$svn_message}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">end</pre>
</div>
</div>
<p>There are a bunch of new constants and I’ve included the an xml parser at the top. Then I’ve added a new task called <strong>:init</strong> and added it to the <strong>:all</strong> task before the <strong>:compile</strong> task.</p>
<p>Inside the <strong>:init</strong> task we create some folders, then we use the SVN command line tool to request the HEAD revision information from the repository url and save it as xml to the output folder that is inside our build folder.</p>
<p>Once there, we can read the details from this xml file and create a version number for our application.</p>
<h3>Updating AssemblyInfo.cs with new version number</h3>
<p>Now that we have the SVN revision number and have generated a version number for the current build we need to apply it to our assemblies. We do that by rewriting the AssemblyInfo.cs file for each assembly in our solution. That calls for a new task:</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">PROJECT_NAME = <span style="color:#006080;">"Aardvark"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">COPYRIGHT = <span style="color:#006080;">"Copyright 2009 1minus1 Ltd. All rights reserved."</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :all =&#62; [:init, :writeAssemblyInfo, :compile]</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    ....</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    desc <span style="color:#006080;">"Write AssemblyInfo.cs with current svn revision."</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :writeAssemblyInfo =&#62; [:init] <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    puts <span style="color:#006080;">"Writing AssemblyInfo Files..."</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        assemblyInfoFiles = FileList[<span style="color:#006080;">"#{SOURCE_PATH}/**/AssemblyInfo.cs"</span>]</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        assemblyInfoFiles.each <span style="color:#0000ff;">do</span> &#124;filePath&#124;</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            puts <span style="color:#006080;">"AssemblyInfo file found at: #{filePath}"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file = File.<span style="color:#0000ff;">new</span>(filePath, <span style="color:#006080;">"w"</span>)</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"//This file was generated by the rakefile.rb build script"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"using System.Reflection;"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"using System.Runtime.InteropServices;\r\n"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyTitle(\"#{PROJECT_NAME} for .NET 3.5\")]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyDescription(\"\")]"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyConfiguration(\"\")]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyCompany(\"\")]"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyProduct(\"#{PROJECT_NAME}\")]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyCopyright(\"#{COPYRIGHT}\")]"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyTrademark(\"\")]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyCulture(\"\")]"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: ComVisible(false)]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyVersion(\"#{VERSION}\")]"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.puts <span style="color:#006080;">"[assembly: AssemblyFileVersion(\"#{VERSION}\")]"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            file.close</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">end</pre>
</div>
</div>
<p>This is pretty straightforward, we search for all the AssemblyInfo.cs files and then loop through them overwriting them as we go with a new set of attributes. We’ve defined a couple of new constants at the top to use, but the important thing is the use of the newly generated version number.</p>
<p>We add this new <strong>:writeAssemblyInfo</strong> task to the <strong>:all</strong> build task before we compile to ensure that every build will include the correct revision number.</p>
<h3>Run NUnit Tests</h3>
<p>Now we have built our solution, we need to run the tests. Here we need to do something a bit extra as we want to use the TeamCity NUint runner if it is TeamCity running the build. Otherwise we want to use the normal NUnit console for when we are running the build locally.</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">TEAMCITY_NUNIT_RUNNER = ENV[<span style="color:#006080;">"teamcity.dotnet.nunitlauncher"</span>]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">NUNIT_EXE = <span style="color:#006080;">"../tools/NUnit/nunit-console.exe"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :all =&#62; [:init, :writeAssemblyInfo, :compile, :test]</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    ...</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    desc <span style="color:#006080;">"Runs tests with NUnit only (without coverage)."</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :test =&#62; [:compile] <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        puts <span style="color:#006080;">"Running Tests..."</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        tests = FileList[<span style="color:#006080;">"#{SOURCE_PATH}/**/#{CONFIG}/*.Tests.dll"</span>].exclude(/obj\<span style="color:#008000;">//)</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        #Select the correct test runner</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        <span style="color:#0000ff;">if</span>(TEAMCITY_NUNIT_RUNNER == nil)</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            sh <span style="color:#006080;">"#{NUNIT_EXE} #{tests} /nologo /exclude:Acceptance /xml=#{OUTPUT_PATH}/TestResults.xml"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        <span style="color:#0000ff;">else</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            sh <span style="color:#006080;">"#{TEAMCITY_NUNIT_RUNNER} v2.0 x86 NUnit-2.4.6 /category-exclude:Acceptance #{tests}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">end</pre>
</div>
</div>
<p>In this task we first get a list of all the test assemblies based on our naming convention (they end in .Tests.dll) and make sure we exclude any from the obj folders. Then if the TeamCity NUnit runner environment variable is available we use that to run the tests, otherwise, use the NUnit console program that we store in a <strong>tools</strong> folder. At present we are excluding out WatiN acceptance tests, but more on this later.</p>
<p>Using the TeamCity NUnit runner is important to us as it will ensure that the TeamCity test UI and data are updated correctly.</p>
<h3>Create test coverage report</h3>
<p>This is where it gets interesting for me. Adding test coverage reports is a good way to ensure that you (or someone else) hasn’t been lazy and written some code without a test first. I don’t think that you should have a fixed percentage that must be covered, be pragmatic.</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">NCOVER_EXE = <span style="color:#006080;">"../tools/NCover/NCover.Console.exe"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">NCOVER_EXPLORER_EXE = <span style="color:#006080;">"../tools/NCoverExplorer/NCoverExplorer.Console.exe"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">COVERAGE_ASSEMBLIES = <span style="color:#006080;">"OneMinusOne.Aardvark.Web;OneMinusOne.Aardvark.Framework;OneMinusOne.Aardvark.Entities;OneMinusOne.Aardvark.Core"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">task :<span style="color:#0000ff;">default</span> =&#62; [<span style="color:#006080;">"build:all"</span>]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :all =&#62; [:init, :writeAssemblyInfo, :compile, :test, :coverage]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    ...</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    desc <span style="color:#006080;">"Run tests with NUnit and NCover for coverage. NCoverExplorer is used to format the coverage results into html."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :coverage =&#62; [:compile] <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Running Tests with Coverage..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        tests = FileList[<span style="color:#006080;">"#{SOURCE_PATH}/**/#{CONFIG}/*.Tests.dll"</span>].exclude(/obj\<span style="color:#008000;">//)</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        sh <span style="color:#006080;">"#{NCOVER_EXE} #{NUNIT_EXE} #{tests} /nologo /exclude:Acceptance /xml=#{OUTPUT_PATH}/TestResults.xml //reg //x #{OUTPUT_PATH}/Coverage.xml //l #{OUTPUT_PATH}/Coverage.log //ea System.CodeDom.Compiler.GeneratedCodeAttribute //a #{COVERAGE_ASSEMBLIES}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        sh <span style="color:#006080;">"#{NCOVER_EXPLORER_EXE} #{OUTPUT_PATH}/Coverage.xml /r:ModuleClassFunctionSummary /p:#{PROJECT_NAME} /q /h /so:2 /m:80 /h:#{OUTPUT_PATH}/CoverageReport.html"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">end</pre>
</div>
</div>
<p>This is a pretty short task. First we use NCover to profile the code while it’s tests are run, then we use NCover Explorer to generate a nice html report. We’ve stored these two programs in our tools folder so you don’t need them installed and it’s easier to get the build running.</p>
<p>You need to do a few extra things in TeamCity to get this to work and show up on a new tab. Here’s what you need to do:</p>
<ol>
<li>Ensure that the build agent service is logged in as an administrator. Otherwise NCover will not be able to profile the tests and you’ll see the error “Profiler connection not established” in your build log.</li>
<li>Add the html report that NCover Explorer generates to your TeamCity artifacts under a folder called Reports.</li>
<li>Edit the TeamCity main-config.xml file <a href="http://www.jetbrains.net/confluence/display/TCD3/Including+Third-Party+Reports+in+the+Build+Results" target="_blank">as shown here</a> to add a tab for your html report.</li>
</ol>
<h3>Create a deployment package</h3>
<p>The last thing that I want my Rake build to do is to collect together the files I need to deploy and zip them up for me.</p>
<div style="color:black;border-left:1px solid gray;border-bottom:1px solid gray;line-height:12pt;background-color:#f4f4f4;width:97.5%;">
<div style="line-height:12pt;background-color:#f4f4f4;width:100%;">
<pre style="line-height:12pt;background-color:white;width:100%;">ARTIFACTS_PATH = <span style="color:#006080;">"#{OUTPUT_PATH}/artifacts"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">WEB_PROJECT_PATH = <span style="color:#006080;">"../src/OneMinusOne.Aardvark.Web"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">ZIP_EXE = <span style="color:#006080;">"../tools/7Zip/7za.exe"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">task :<span style="color:#0000ff;">default</span> =&#62; [<span style="color:#006080;">"build:all"</span>]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"><span style="color:#0000ff;">namespace</span> :build <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    task :all =&#62; [:init, :writeAssemblyInfo, :compile, :test, :coverage, :package]</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    ...</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    desc <span style="color:#006080;">"Package the required artifacts."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    task :package =&#62; [:compile] <span style="color:#0000ff;">do</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        puts <span style="color:#006080;">"Preparing package files..."</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        Dir.mkdir <span style="color:#006080;">"#{ARTIFACTS_PATH}/bin"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        FileUtils.cp_r FileList[<span style="color:#006080;">"#{WEB_PROJECT_PATH}/bin/*.dll"</span>], <span style="color:#006080;">"#{ARTIFACTS_PATH}/bin"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        FileUtils.cp_r <span style="color:#006080;">"#{WEB_PROJECT_PATH}/Content"</span>, <span style="color:#006080;">"#{ARTIFACTS_PATH}"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        FileUtils.cp_r <span style="color:#006080;">"#{WEB_PROJECT_PATH}/Views"</span>, <span style="color:#006080;">"#{ARTIFACTS_PATH}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        FileUtils.cp_r FileList[<span style="color:#006080;">"#{WEB_PROJECT_PATH}/*.aspx"</span>], <span style="color:#006080;">"#{ARTIFACTS_PATH}"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        FileUtils.cp_r FileList[<span style="color:#006080;">"#{WEB_PROJECT_PATH}/*.asax"</span>], <span style="color:#006080;">"#{ARTIFACTS_PATH}"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        FileUtils.cp_r FileList[<span style="color:#006080;">"#{WEB_PROJECT_PATH}/*.config"</span>], <span style="color:#006080;">"#{ARTIFACTS_PATH}"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        delete_svn_folders(ARTIFACTS_PATH)</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        puts <span style="color:#006080;">"Creating zip package"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        zipFolder(ARTIFACTS_PATH, <span style="color:#006080;">"#{OUTPUT_PATH}/#{PROJECT_NAME}-v#{VERSION}.zip"</span>);</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;"></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">    def delete_svn_folders(folder)</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">        Find.find(folder) <span style="color:#0000ff;">do</span> &#124;path&#124;</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">            <span style="color:#0000ff;">if</span>(path =~ /\.svn$/ &#124;&#124; path =~ /\_svn$/)</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">                puts <span style="color:#006080;">"Deleting: #{path}"</span></pre>
<pre style="line-height:12pt;background-color:white;width:100%;">                FileUtils.rm_r path, :force =&#62; <span style="color:#0000ff;">true</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">            end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        end</pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;"></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    def zipFolder(folderPath, zipPath)</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">        sh <span style="color:#006080;">"#{ZIP_EXE} a #{zipPath} .\\#{folderPath}\\*"</span></pre>
<pre style="line-height:12pt;background-color:#f4f4f4;width:100%;">    end</pre>
<pre style="line-height:12pt;background-color:white;width:100%;">end</pre>
</div>
</div>
<p>As this is a <a href="http://www.castleproject.org" target="_blank">Castle MonoRail</a> application, I start this new <strong>:package</strong> task by copying all the required web files to an <strong>artifacts</strong> folder that is inside the <strong>output</strong> folder we created earlier. This ensures that we only have the files required to run the application and we exclude all other files.</p>
<p>Once the files are copied I noticed that because we were copying folders, the hidden .svn folders were being copied too. The only way I could see was to then delete these folders from the artifacts folder. This is where the <strong>delete_svn_folders</strong> function comes in. It just loops through and deletes any path that ends with either .svn or _svn as either can be used.</p>
<p>The final thing is to zip these files up. I use the <a href="http://www.7-zip.org/download.html" target="_blank">7zip command line tool</a> to do this and I’ve added this to the tools folder again to make it as easy as possible to run the build. The zip file is saved to the output folder and is named with the project name and version number.</p>
<h3>Finishing up</h3>
<p>That’s it really, you can see the <a href="http://aardvark-cms.googlecode.com/svn/trunk/build/rakefile.rb" target="_blank">full build file here at Google Code</a>. There are some extra bits and pieces in this build like coping the files to the development server, requesting an installer page on the site that will install the database and populate it with data but that was a bit specific for our needs so I didn’t add it here.</p>
<p>The advantage I can see here using Rake over NAnt or MSBuild is that you can program your build <em>using code</em> rather than xml which I find a lot easier and a lot more powerful.</p>
<p>The one thing that is missing from the build is the ability to run our acceptance tests that are written using <a href="http://watin.sourceforge.net/" target="_blank">WatiN</a>. I found <a href="http://stackoverflow.com/questions/488443/running-watin-on-teamcity" target="_blank">this post on Stack Overflow</a> and <a href="http://www.jetbrains.net/devnet/message/5242725" target="_blank">this post on JetBrains forum</a> which may point me in the right direction.</p>
<p>I hope that has helped, Rake is the future…</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Entorno de desarrollo de Jeremy D. Miller]]></title>
<link>http://fravelgue.wordpress.com/2009/08/03/entorno-de-desarrollo-de-jeremy-d-miller/</link>
<pubDate>Mon, 03 Aug 2009 17:46:46 +0000</pubDate>
<dc:creator>fravelgue</dc:creator>
<guid>http://fravelgue.wordpress.com/2009/08/03/entorno-de-desarrollo-de-jeremy-d-miller/</guid>
<description><![CDATA[Jeremy D. Miller usa como entorno (infraestructura?) de desarrollo: TeamCity + SVN + NUnit + Rake (v]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Jeremy D. Miller usa como entorno (infraestructura?) de desarrollo: TeamCity + SVN + NUnit + Rake (<a href="http://codebetter.com/blogs/jeremy.miller/archive/2009/07/27/the-tfs-mvp-kerfluffle.aspx">via</a>)</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TeamCity - Using Personal Builds to help improve cycle time]]></title>
<link>http://myadventuresincoding.wordpress.com/2009/07/31/teamcity-using-personal-builds-to-help-improve-cycle-time/</link>
<pubDate>Fri, 31 Jul 2009 19:35:10 +0000</pubDate>
<dc:creator>Brian</dc:creator>
<guid>http://myadventuresincoding.wordpress.com/2009/07/31/teamcity-using-personal-builds-to-help-improve-cycle-time/</guid>
<description><![CDATA[So you are working on a large project, many developers committing regularly to the same code base, y]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>So you are working on a large project, many developers committing regularly to the same code base, you run all the unit tests, commit and you break the build. Now everyone on your team is angry (As they should be!). How could this have happened when you ran all of the tests? The reason is that you did not update before running tests locally and committing. The problem is that constantly updating and building can waste a lot of time. Even if you do update, run all tests, then commit, there is still a chance another developer made a commit during that cycle. The solution: Team City Personal Builds.</p>
<h4>Personal Builds</h4>
<p>The great people at <a href="http://www.jetbrains.com/">JetBrains</a> have a feature in <a href="http://www.jetbrains.com/teamcity/index.html">TeamCity</a> that allows you to use your build server build agents for &#8220;Personal Builds&#8221;. More great news is that TeamCity plugins that make use of this interesting TeamCity feature are available for IDEs such as IntelliJ and Visual Studio. </p>
<p>So now when you use your IDE tool with the TeamCity plugin you would use the &#8220;Remote Run&#8221; option to make your commit. TeamCity will then spin up a personal build, apply your code changes to a fresh checkout of the repository, build, and run all unit tests. If your &#8220;Personal Build&#8221; passes, your code changes will be committed. Now, here is the great part, if it fails, your code changes will NOT be committed, and you will be notified of the failure.</p>
<p>This feature of TeamCity allows developers to get out of the update, run all tests, and commit cycle and offload some of that work to their TeamCity server. </p>
<h4>IntelliJ Plugin Setup</h4>
<ul>
<li>File-&#62;Settings-&#62;Plugins</li>
<li>Click on the &#8220;Available&#8221; tab</li>
<li>In the search box enter &#8220;TeamCity&#8221; (The option JetBrians TeamCity Plugin should show up in the list)</li>
<li>Right click on the plugin and select &#8220;Download and install&#8221;</li>
<li>You should see a TeamCity option on your IntelliJ toolbar</li>
<li>Enter your TeamCity credentials, setup your notifications</li>
</ul>
<p>So now, when you commit use TeamCity &#8211; &#62; Remote Run rather than using the Version Control menu. You will be notified if your commit is accepted or rejected.</p>
<h4>Visual Studio Plugin Setup</h4>
<p>To download the Plugin, login to your TeamCity server, go to the &#8220;My Settings &#38; Tools&#8221; page. You will find a download link for the plugin in the &#8220;TeamCity Tools&#8221; panel on the righthand side of the page.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[MSBuildCommunityTasks and Versioning]]></title>
<link>http://escapologist.wordpress.com/2009/07/30/autogenerate-version-numbers/</link>
<pubDate>Thu, 30 Jul 2009 10:51:11 +0000</pubDate>
<dc:creator>boggin</dc:creator>
<guid>http://escapologist.wordpress.com/2009/07/30/autogenerate-version-numbers/</guid>
<description><![CDATA[Auto-versioning our assemblies in TeamCity using MSBuild was more fiddly than I expected but ultimat]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Auto-versioning our assemblies in TeamCity using MSBuild was more fiddly than I expected but ultimately a very clean implementation.</p>
<p>I&#8217;m using TeamCity for continuous integration and MSBuild to run our project&#8217;s solution file (.sln) as the build script. I wanted each of our builds to have a version number on the assembly (.exe) so that testers would know what they were dealing with. The format for the version number is the familiar dotted quad of Major.Minor.Build.Revision where the Build would be the build number from TeamCity and the Revision would be our version control system (VCS) revision number (our VCS is Perforce). </p>
<p>I use Scrum for Agile software construction, in an OpenUP project management process, so I&#8217;ve decided our Major number is the number of the release to the customer and the Minor is the iteration (Sprint) that produced the build. For example, my first build with this system was 0.8.282.11066 which means: we&#8217;ve yet to make a release to the customer (0); the build was from the eighth two-week Sprint (8); TeamCity has completed 282 builds; and Perforce is up to revision 11066.</p>
<p>MSBuildCommunityTasks includes an AssemblyInfo task. These are the steps I used to get this working:<br />(1) added MSBuildCommunityTasks to our &#8220;ExternalTools&#8221; folder in Perforce and submitted the MSBuild.Community.Tasks.dll and MSBuild.Community.Tasks.Targets files.<br />(2) integrated the MSBuildCommunityTasks items from step 1 into the solution&#8217;s &#8220;tools&#8221; folder.<br />(3) updated the MSBuild.Community.Tasks.Targets file to the correct path to the MSBuildCommunityTasksLib (in our &#8220;tools&#8221; folder from step 2).<br />(4) imported the Targets file from step 3 into the project file (.csproj).</p>
<p><code>&#60;MSBuildCommunityTasksTargets&#62;..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets&#60;/MSBuildCommunityTasksTargets&#62;<br />&#60;Import Project="$(MSBuildCommunityTasksTargets)" /&#62;<br /></code><br />(5) created the properties for the parts of the version number so it is easy to update for releases and works both on the developer&#8217;s machine, where the Build number and Revision number are set to 0, and on TeamCity which provides environment variables for the TeamCity build number and the VCS revision number.</p>
<p><code>&#160; &#60;PropertyGroup&#62;<br />&#160;&#160;&#160; &#60;!-- Release --&#62;<br />&#160;&#160;&#160; &#60;Major&#62;0&#60;/Major&#62;<br />&#160;&#160;&#160; &#60;!-- Iteration --&#62;<br />&#160;&#160;&#160; &#60;Minor&#62;9&#60;/Minor&#62;<br />&#160;&#160;&#160; &#60;Build&#62;0&#60;/Build&#62;<br />&#160;&#160;&#160; &#60;Build Condition="'$(BUILD_NUMBER)' != ''"&#62;$(BUILD_NUMBER)&#60;/Build&#62;<br />&#160;&#160;&#160; &#60;Revision&#62;0&#60;/Revision&#62;<br />&#160;&#160;&#160; &#60;Revision Condition="'$(BUILD_VCS_NUMBER)' != ''"&#62;$(BUILD_VCS_NUMBER)&#60;/Revision&#62;<br />&#160;&#160;&#160; &#60;Version&#62;$(Major).$(Minor).$(Build).$(Revision)&#60;/Version&#62;<br />&#160; &#60;/PropertyGroup&#62;<br /></code><br />(6) deleted the current AssemblyInfo.cs from the source and the VCS.<br />(6) add the AssemblyInfo task that will autogenerate the AssemblyInfo.cs for each build</p>
<p><code>&#160; &#60;Target Name="BeforeBuild"&#62;<br />&#160;&#160;&#160; &#160;&#60;AssemblyInfo CodeLanguage="CS"&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OutputFile="$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs" <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyTitle="MyProduct" <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyDescription="My Product"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyConfiguration=""<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyCompany="MyCompany Ltd"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyProduct="MyProduct"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyCopyright="Copyright © MyCompany  Ltd 2009"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyTrademark=""<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ComVisible="false"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CLSCompliant="true"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Guid="884276aa-6859-4318-8bb9-073f68a66057"<br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AssemblyVersion="$(Version)" /&#62;<br />&#160; &#60;/Target&#62;<br /></code><br />Now I need to create a WiX project to build a release version and expose it as an artifact in TeamCity so our testers can easily pick up a build themselves.</p>
<p>Technorati Tags: <a class="performancingtags" href="http://technorati.com/tag/MSBuildCommunityTasks%20AssemblyInfo%20TeamCity%20MSBuild" rel="tag">MSBuildCommunityTasks AssemblyInfo TeamCity MSBuild</a></p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=48d54cad-f072-876c-8889-6b6c28670183" /></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Updated TeamCity WebHooks plugin available]]></title>
<link>http://netwolfuk.wordpress.com/2009/07/04/updated-teamcity-webhooks-plugin-available/</link>
<pubDate>Sat, 04 Jul 2009 08:15:02 +0000</pubDate>
<dc:creator>netwolfuk</dc:creator>
<guid>http://netwolfuk.wordpress.com/2009/07/04/updated-teamcity-webhooks-plugin-available/</guid>
<description><![CDATA[Version 0.6.13.11 of the tcWebHooks plugin is available for download. It&#8217;s mainly a bugfix rel]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Version 0.6.13.11 of the <a title="My TeamCity Plugins page" href="http://netwolfuk.wordpress.com/teamcity-plugins/">tcWebHooks</a> plugin is available for <a title="Download from SourceForge" href="http://sourceforge.net/projects/tcplugins/files/">download</a>. It&#8217;s mainly a bugfix release and some tidy up of the user interface.</p>
<p><strong>Fixes:</strong><br />
- Fix for newly created WebHooks not being persisted to plugin-settings.xml until re-edited.<br />
- Plugin JSPs loaded using getPluginResourcesPath(), so plugin dir can be anything, and not hard-coded to &#8220;webhook&#8221;.<br />
- webHookUrl form input style fix for linux (or large fonts in general). URL input field was too wide for div.</p>
<p><strong>Features:</strong><br />
- WebHook blurb updated. A new link can be added to the &#8220;Further reading&#8221; section of the blurb by adding a &#60;info&#62; line to the &#60;webhooks&#62; section of the main-config.xml<br />
- Enabled events are now listed in Tabs and Edit pages, eg. Build Started, Build Changed Status, Build Interrupted, Build Almost Completed, Build Responsibility Changed</p>
<p><strong>Links:</strong></p>
<p><a title="My TeamCity Plugins page" href="http://netwolfuk.wordpress.com/teamcity-plugins/">More Info</a> &#124; <a title="Download from SourceForge" href="http://sourceforge.net/projects/tcplugins/files/">Download</a> &#124; <a title="View the docs in Trac" href="http://sourceforge.net/apps/trac/tcplugins/">Install and usage docs</a></p>
<p>I welcome any and all feedback.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Official JetBrains Git Plugin for TeamCity]]></title>
<link>http://chukovskij.wordpress.com/2009/06/30/official-jetbrains-git-plugin-for-teamcity/</link>
<pubDate>Tue, 30 Jun 2009 15:19:26 +0000</pubDate>
<dc:creator>chukovskij</dc:creator>
<guid>http://chukovskij.wordpress.com/2009/06/30/official-jetbrains-git-plugin-for-teamcity/</guid>
<description><![CDATA[Good news! Git plugin for TeamCity from JetBrains guys is available at http://www.jetbrains.net/conf]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Good news! Git plugin for TeamCity from JetBrains guys is available at http://www.jetbrains.net/confluence/display/TW/Git. This plugin is much better than 3rd party git plugin for TC. Git Plugin isn&#8217;t bundled in TeamCity 4.5, but it is easy to install it. See instructions and documentation at http://www.jetbrains.net/confluence/display/TW/Git</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Developing for TeamCity in Eclipse]]></title>
<link>http://netwolfuk.wordpress.com/2009/06/28/developing-for-teamcity-in-eclipse/</link>
<pubDate>Sun, 28 Jun 2009 13:25:02 +0000</pubDate>
<dc:creator>netwolfuk</dc:creator>
<guid>http://netwolfuk.wordpress.com/2009/06/28/developing-for-teamcity-in-eclipse/</guid>
<description><![CDATA[This document assumes you are running the TeamCity package from JetBrains, which includes Tomcat. If]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This document assumes you are running the TeamCity package from JetBrains, which includes Tomcat. If you are running your own Tomcat install, you may need to hunt out the files yourself. This document is based on Linux. I&#8217;ve tried to point out what you need to change on Windows, but I don&#8217;t have a Windows box to test with.</p>
<p>My TeamCity home  is <em>/opt/TeamCity</em></p>
<h4>Enable JSP development mode in Tomcat.</h4>
<p>This setting alows you to hot delpoy JSPs, and Tomcat will re-compile them for you without a restart.  Edit <em>&#60;TeamCityHome&#62;</em>/conf/web.xml and find the <strong>JspServlet</strong> section. Change the development mode to <strong>true</strong> as per the section below.</p>
<pre>&#60;servlet-name&#62;jsp&#60;/servlet-name&#62;
   &#60;servlet-class&#62;org.apache.jasper.servlet.JspServlet&#60;/servlet-class&#62;
     &#60;init-param&#62;
       &#60;param-name&#62;development&#60;/param-name&#62;
       &#60;param-value&#62;true&#60;/param-value&#62;
     &#60;/init-param&#62;
  ...</pre>
<h4>Enable Java code hot-swapping with a debugger</h4>
<p>We have enabled JSP hot-compile in the previous, now we need to configure Tomcat so that Eclipse can load new Java code into the JVM from within the Eclipse debugger.</p>
<p>For Linux, edit <em>&#60;TeamCityHome&#62;</em>/bin/teamcity-server.sh and insert the commands needed to start Tomcat with the debugger enabled. I added the TEAMCITY_DEBUG_OPTS variable, and then added it to the CATALINA_OPTS line.</p>
<pre>TEAMCITY_DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"

 CATALINA_OPTS="$CATALINA_OPTS $TEAMCITY_SERVER_OPTS $TEAMCITY_DEBUG_OPTS -server $TEAMCITY_SERVER_MEM_OPTS -Dlog4j.configuration=file:$BIN/../conf/teamcity-server-log4j.xml -Dteamcity_logs=../logs/ -Djava.awt.headless=true"</pre>
<p>For Windows, edit &#60;TeamCityHome&#62;\conf\teamcity-server.bat and insert the debug commands. I added the TEAMCITY_DEBUG_OPTS variable, and then added it to the CATALINA_OPTS line.</p>
<pre>:server_mem_opts_done
SET TEAMCITY_DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
SET CATALINA_OPTS=%TEAMCITY_SERVER_OPTS% %TEAMCITY_DEBUG_OPTS% -server %TEAMCITY_SERVER_MEM_OPTS_ACTUAL% -Dlog4j.configuration=file:../conf/teamcity-server-log4j.xml -Dteamcity_logs=../logs/</pre>
<h4>Start Tomcat</h4>
<p>Stop Tomcat if it&#8217;s running and then start it by running &#60;TeamCityHome&#62;/bin/teamcity-server.sh start (or &#60;TeamCityHome&#62;\bin\teamcity-server.bat start on Windows).</p>
<p>Have a look in <em>&#60;TeamCityHome&#62;</em>/logs/catalina.out  There should be a line similar to the one below indicating that Tomcat is running with the debug port open.</p>
<pre>Listening for transport dt_socket at address: 8000</pre>
<h4><strong>Configure Eclipse</strong></h4>
<p>In Eclipse, create a new Debug Configuration (In the Java perspective, it&#8217;s under the Run menu).</p>
<p>Find Remote Java Application, and click the new button.  In the <strong>Connect</strong> tab, set:</p>
<ul>
<li>Connection Type: Standard Socket (Attach)</li>
<li>Connection Properties:
<ul>
<li>Host: localhost (assuming your TeamCity instance is on your local machine)</li>
<li>Port: 8000</li>
</ul>
</li>
</ul>
<p>In the <strong>Source</strong> tab, I added my Java source directory.</p>
<h4>Connect to Tomcat in Eclipse</h4>
<p>Run the new Debug Config, and change to the Debug perspective. A quote from the <a href="http://www.jetbrains.net/confluence/display/TCD4/Development+Environment">TeamCity dev page</a> is relevant here.</p>
<blockquote><p>if you do not change code affecting plugin initialization and change only body of the methods, you can attach to the server process with a debugger and hot-swap the code</p></blockquote>
<p>So if you change your registers or constructors, you need to restart Tomcat.</p>
<h4>Deploy your JSPs</h4>
<p>When TeamCity starts, it copies the JSPs from your plugin into <em>&#60;TeamCityHome&#62;</em>/webapps/ROOT/plugins/<em>&#60;YourPluginName&#62;</em>/</p>
<p>Therefore, you can copy updated JSPs to here. This might be best acheived with a simple ANT script.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TeamCity WebHooks plugin beta available]]></title>
<link>http://netwolfuk.wordpress.com/2009/06/22/teamcity-webhooks-plugin-beta-available/</link>
<pubDate>Mon, 22 Jun 2009 16:33:28 +0000</pubDate>
<dc:creator>netwolfuk</dc:creator>
<guid>http://netwolfuk.wordpress.com/2009/06/22/teamcity-webhooks-plugin-beta-available/</guid>
<description><![CDATA[Announcing a beta release (version 0.5.5.5) of a plugin for TeamCity which enhances TeamCity to prov]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Announcing a beta release (version 0.5.5.5) of a plugin for <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> which enhances TeamCity to provide <a href="http://webhooks.pbworks.com/">WebHook</a> functionality. With the <a href="/teamcity-plugins">tcWebHooks plugin</a> installed, you can tell TeamCity to trigger a webhook POST request as build events occur.</p>
<p>WebHooks are configured on a project basis, and when events occur in the build process, a POST request is submitted to the URL. You can configure as many URLs as you like (within reason) and which events will trigger the request.</p>
<p>There is support for proxies in this version, and webhooks are configured in the TeamCity UI. There are a few outstanding items to tidy up, but the core functionality is working.</p>
<p>The project is on SourceForge at <a href="http://tcplugins.sourceforge.net/">tcplugins.sourceforge.net</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Brief overview of Maven, Archiva, Subversion and Team City]]></title>
<link>http://boymeetstechnology.wordpress.com/2009/06/10/brief-overview-of-maven-archiva-subversion-and-team-city/</link>
<pubDate>Wed, 10 Jun 2009 22:28:54 +0000</pubDate>
<dc:creator>Stephen</dc:creator>
<guid>http://boymeetstechnology.wordpress.com/2009/06/10/brief-overview-of-maven-archiva-subversion-and-team-city/</guid>
<description><![CDATA[Last week was fun&#8230; I setup Continuous Integration for my project using Team City. The project ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Last week was fun&#8230;</p>
<p>I setup Continuous Integration for my project using Team City. The project source is in Subversion and it&#8217;s a Maven project, so that was pretty easy to configure in Team City. Also had to install a Repository Manager Archiva to host maven dependencies. Team City is just awesome, can&#8217;t say enough about it. I did briefly look at other CI server products, but nothing as slick and team city.Team City&#8217;s &#8220;Remote Run&#8221; is THE feature any developer could ask for.</p>
<p>When all is done, I even prepared a little presentation with a brief overview of all the tools:</p>
<p><!-- SlideShare error: doc is missing or has illegal characters /[^-_a-zA-Z0-9]/ --></p>
<p><em>A disclaimer about the presentation: All (or most) of the images or text are either from product documentation or other articles I gathered.</em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Implementing TeamCity For .Net Projects]]></title>
<link>http://esersahin.wordpress.com/2009/05/18/implementing-teamcity-for-net-projects/</link>
<pubDate>Mon, 18 May 2009 07:34:35 +0000</pubDate>
<dc:creator>esersahin</dc:creator>
<guid>http://esersahin.wordpress.com/2009/05/18/implementing-teamcity-for-net-projects/</guid>
<description><![CDATA[Evolving Your Build Automation Solution Implementing TeamCity for .Net Projects,Part1:Just Build It!]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://codeprogression.blogspot.com/2009/03/implementing-teamcity-for-net-projects.html">Evolving Your Build Automation Solution</a><br />
<a href="http://codeprogression.blogspot.com/2009/04/implementing-teamcity-for-net-projects.html">Implementing TeamCity for .Net Projects,Part1:Just Build It!(A Simple Build Configuration)</a><br />
<a href="http://codeprogression.blogspot.com/2009/04/implementing-teamcity-for-net-projects_15.html">Implementing TeamCity for .Net Projects,Part2:Triggering Builds</a><br />
<a href="http://codeprogression.blogspot.com/2009/04/implementing-teamcity-for-net-projects_19.html">Implementing TeamCity for .Net Projects,Part3 : Running Test,Nightly Builds and Creating Artifacts</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[TestComplete integration into TeamCity]]></title>
<link>http://kain64b.wordpress.com/2009/04/23/testcomplete-integration-into-teamcity/</link>
<pubDate>Thu, 23 Apr 2009 08:31:50 +0000</pubDate>
<dc:creator>kain64b</dc:creator>
<guid>http://kain64b.wordpress.com/2009/04/23/testcomplete-integration-into-teamcity/</guid>
<description><![CDATA[TestComplete integration into TeamCity We use TestComplete for GUI testing in our work. For faster t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><a href="http://www.automatedqa.com/products/testcomplete/">TestComplete</a> integration into <a href="http://www.jetbrains.com/teamcity/">TeamCity</a></p>
<p style="text-align:justify;">We use TestComplete for GUI testing in our work. For faster tests execution we use several PC&#8217;s with TestComplete. A unique part of full task list runs on each PC.</p>
<p style="text-align:justify;">But how can we split task for maximum workload of PC? How to combine results without manual work?</p>
<p style="text-align:justify;">It also would be good to include GUI testing in to continuous integration process. As a continuous integration server we use TeamCity. TestComplete can be simply integrated into native AutomatedQA continuous integration server. But this server doesn&#8217;t fit our needs. It&#8217;s payware and doesn&#8217;t support pre-tested commit.</p>
<p style="text-align:justify;">We need to create this:</p>
<p style="text-align:justify;"><img src="http://kain64b.files.wordpress.com/2009/04/042309-0831-testcomplet1.png" alt="" /></p>
<p style="text-align:justify;">
<p style="text-align:justify;">TeamCity runs GUI tests on all TestComplete clients. <a href="http://www.nunit.org/">NUnit </a>runner will be used as a program which starts distributes tests. All test results will be combining in TestFixture ctor. All TestComplete PC&#8217;s has a small web service to handle TeamCity request on test.</p>
<p style="text-align:justify;">Let&#8217;s start. On all TestComplete PC we run web service. TeamCity contains project that contains Nunit TestFixture for distributed test run. Web service runs application by client&#8217;s parameters. Message sequence on initialization and run test.</p>
<p style="text-align:justify;">
<p style="text-align:justify;"><img src="http://kain64b.files.wordpress.com/2009/04/042309-0831-testcomplet2.png" alt="" /></p>
<p style="text-align:justify;">
<p style="text-align:justify;">As a dispatcher algorithm we use &#8220;round robin&#8221;.  We need simply thread manager for controlling active thread count and providing simple algorithm of synchronization.</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Threading;</p>
<p>namespace ThreadLib {<br />
   ///interface for thread result<br />
   public interface IThreadResult { }</p>
<p>   public delegate T FuncDelegate<T>() where T : IThreadResult;//wrapper for delegate</p>
<p>   public class ThreadControler<T> where T : IThreadResult {<br />
      private class ThreadParam {<br />
         public string Id;<br />
         public FuncDelegate<T> Delegate;<br />
      }<br />
      ///delegates for execution<br />
      private readonly Dictionary<string, FuncDelegate<T>> Delegates = new Dictionary<string, FuncDelegate<T>>();<br />
      ///results<br />
      private readonly Dictionary<string, T> Results = new Dictionary<string, T>();<br />
      private int _MaxParalelThreadCount;<br />
      private static Semaphore Semaphore;</p>
<p>      public ThreadControler(int maxParalelThreadCount) {<br />
         MaxParalelThreadCount = maxParalelThreadCount;<br />
      }</p>
<p>      public T GetResult(string key) {<br />
         if (!Results.ContainsKey(key))<br />
            throw new ArgumentException(string.Format(&#8220;no result by this key {0}&#8221;, key));<br />
         return Results[key];<br />
      }</p>
<p>      public void AddDelegate(string key, FuncDelegate<T> @delegate) {<br />
         Delegates.Add(key, @delegate);<br />
      }<br />
      public int MaxParalelThreadCount {<br />
         get { return _MaxParalelThreadCount; }<br />
         set {<br />
            if (value < 1)<br />
               throw new ArgumentException(&#8220;value<1");<br />
            _MaxParalelThreadCount = value;<br />
         }<br />
      }<br />
///wrapper for delegate<br />
      public void ThreadFunc(object param) {<br />
         var threadParam = (ThreadParam)param;<br />
         var result = threadParam.Delegate();<br />
         lock (Results) {<br />
            Results.Add(threadParam.Id, result);<br />
         }<br />
         Semaphore.Release();<br />
      }<br />
///run all delegate in parallel mode<br />
      public void Run() {<br />
         if (Delegates.Count == 0)<br />
            throw new InvalidOperationException(&#8220;No Thread for Start&#8221;);<br />
         if (MaxParalelThreadCount < 1)<br />
            throw new InvalidOperationException(&#8220;MaxParalelThreadCount<1");</p>
<p>         using(Semaphore = new Semaphore(MaxParalelThreadCount, MaxParalelThreadCount)){<br />
            var threads = new List<Thread>();<br />
            foreach (var key in Delegates.Keys) {<br />
               Semaphore.WaitOne();<br />
               var localKey = key;<br />
               var @delegate = Delegates[localKey];<br />
               var param = new ThreadParam { Delegate = @delegate, Id = localKey };<br />
               var thread = new Thread(ThreadFunc);<br />
               threads.Add(thread);<br />
               thread.Start(param);<br />
            }<br />
            foreach (var thread in threads)<br />
                thread.Join();<br />
         }<br />
      }</p>
<p>   }<br />
}</p>
<p>[/CODE]</p>
<p style="text-align:justify;">
<p style="text-align:justify;">
<p style="text-align:center;">
<h3>Web service for running and controlling application (TestComplete for example)</h3>
<p>For Service creation I choose WCF. Here simple interface of service:</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
[ServiceContract]<br />
   public interface ISpreadRunnerService {<br />
      [OperationContract]<br />
      TaskResult TryRunProgramm(string @executable, string @params, int timeout);<br />
   }</p>
<p>[/CODE]</p>
<p style="text-align:justify;">For using this server need simple send &#8220;exe&#8221; name, params for &#8220;exe&#8221;, and timeout. Also we need to know busy server or not.</p>
<p style="text-align:justify;">Service implementation:</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]<br />
    public class SpreadRunnerService : ISpreadRunnerService<br />
    {<br />
        private readonly object Locker = new object();<br />
//strategy how to run app and how to get app results<br />
        protected IRunProgramStrategy Strategy;<br />
        public virtual TaskResult TryRunProgramm(string executable, string @params, int timeout)<br />
        {<br />
//Lock service!!!<br />
            if (!Monitor.TryEnter(Locker))<br />
            {<br />
                return Strategy.NotRunResult;<br />
            }</p>
<p>            var result= Strategy.Run(executable, @params, timeout);<br />
           Monitor.Exit(Locker);<br />
           return result;<br />
        }<br />
        /// <summary><br />
        /// only for studio hoster<br />
        /// </summary><br />
        internal SpreadRunnerService() : this(null) { }<br />
        public SpreadRunnerService(IRunProgramStrategy strategy)<br />
        {<br />
            Strategy = strategy;<br />
        }<br />
    }</p>
<p>[/CODE]</p>
<p style="text-align:justify;">
<p style="text-align:justify;">SimpleRunStrategy code part. Only run application and return application exit code.</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
[DataContract]<br />
   public class TaskResult : ITaskResult {<br />
      [DataMember]<br />
      public bool Runned { get; set; }<br />
      [DataMember]<br />
      public bool Hang { get; set; }<br />
      [DataMember]<br />
      public int ProgramResult { get; set; }<br />
      [DataMember]<br />
      public string ExtraData;<br />
   }<br />
public interface IRunProgramStrategy {<br />
      TaskResult Run(string executable, string @params, int timeout);<br />
      TaskResult HangResult { get; }<br />
      TaskResult NotRunResult { get; }<br />
   }<br />
public class RunProgramStrategySimple : IRunProgramStrategy{<br />
/*…*/<br />
public virtual TaskResult Run(string executable, string @params, int timeout) {<br />
         TaskResult result=null;<br />
         try {<br />
            BeforeProcessRun();<br />
            Process p = new Process();<br />
            p.StartInfo.FileName = executable;<br />
            p.StartInfo.Arguments = @params;<br />
            p.Start();<br />
            p.WaitForExit(timeout);<br />
            if (!p.HasExited) {<br />
               p.Kill();<br />
               result= HangResult;<br />
            }<br />
            else<br />
            result= new TaskResult { Hang = false, ProgramResult = p.ExitCode, Runned = true };<br />
         }<br />
         catch (Exception e){<br />
            result= NotRunResult;<br />
            Console.WriteLine(e.Message + &#8221; &#8220;+executable+<br />
               &#8221; &#8220;+ @params);<br />
         }<br />
         finally{<br />
            AfterProcessRun(result);<br />
         }<br />
         return result;<br />
      }<br />
/*…*/</p>
<p>[/CODE]</p>
<p style="text-align:justify;">
<p style="text-align:justify;">Client is also very simple. Here it&#8217;s  implementation:</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
public class Task<br />
    {<br />
        public string Id { get; set; }<br />
        public string Executable{get;set;}<br />
        public string Params{get;set;}<br />
        public int Timeout { get; set; }<br />
    }<br />
public class SpreadRunnerClient<br />
    {<br />
//our thread controller<br />
        private ThreadControler<TaskResult> ThreadController = new  ThreadControler<TaskResult>();<br />
//list of service host. May be better use UDDI but…<br />
        internal readonly List<string> Hosts = new List<string>();<br />
//task –that stored in external file<br />
        private List<Task> Tasks = new List<Task>();<br />
public IEnumerable<string> getHosts()<br />
        {<br />
            while(true)<br />
                foreach (string host in Hosts)<br />
                    yield return host;<br />
        }</p>
<p>// create runner delegates for all task and run them in parallel mode<br />
public void RunAllTasks()<br />
        {<br />
            ThreadController.MaxParalelThreadCount = Hosts.Count;<br />
            foreach (var task in Tasks)<br />
            {<br />
                var lockref = task;<br />
                FuncDelegate<TaskResult> func = delegate()<br />
                {<br />
                    while (true)<br />
                    {<br />
                        foreach (string host in getHosts())<br />
                            try<br />
                            {<br />
                               var binding = new WSHttpBinding(&#8220;WSHttpBinding_ISpreadRunnerService&#8221;);<br />
                               binding.ReceiveTimeout = TimeSpan.FromMilliseconds(lockref.Timeout*2000);<br />
                               binding.OpenTimeout= TimeSpan.FromMilliseconds(20000);<br />
                               binding.SendTimeout = TimeSpan.FromMilliseconds(lockref.Timeout * 2000);<br />
                               using (var client = new SpreadRunnerServiceClient(binding, new EndpointAddress(host)))<br />
                                {<br />
                                    client.Open();<br />
//try to run application in server<br />
                                    TaskResult result = client.TryRunProgramm(lockref.Executable, lockref.Params, lockref.Timeout);<br />
                                    if (result.Runned)<br />
                                        return result;<br />
                                }<br />
                            }<br />
                            catch { }<br />
                    }<br />
                    throw new ApplicationException();<br />
                };<br />
                ThreadController.AddDelegate(lockref.Id,func);<br />
            }<br />
            ThreadController.Run();<br />
        }</p>
<p>[/CODE]</p>
<p style="text-align:justify;">
<p style="text-align:justify;">And finally we need to make TestFixture that contain <span style="font-family:Times New Roman;font-size:12pt;">SpreadRunnerClient</span>. In TestFixtureSetUp we must Load All Task from file and give them into <span style="font-family:Times New Roman;font-size:12pt;">SpreadRunnerClient</span>. And call <span style="font-family:Times New Roman;font-size:12pt;">SpreadRunnerClient</span>::RunAllTasks. For handling results we need to write some Test methods, for example:</p>
<p style="text-align:justify;">
<p>[CODE language="CSharp"]<br />
private static void AssertTests(TaskResult res) {<br />
         bool isnormalresult = res.ProgramResult == 0 &#124;&#124; res.ProgramResult == 1;<br />
         Assert.IsTrue(isnormalresult, &#8220;result is a &#8221; + res.ProgramResult + &#8221; &#124;&#8221; + res.ExtraData);<br />
         Assert.IsFalse((res.ExtraData.ToLowerInvariant().Contains(&#8220;exception&#8221;)), res.ExtraData);<br />
      }<br />
      // ReSharper disable InconsistentNaming<br />
      [Test]<br />
      public void XXXX001() { var res = client.GetResultsById(&#8220;XXXX001&#8243;); AssertTests(res); }</p>
<p>[/CODE]</p>
<p style="text-align:justify;">And finally we can run this test in TeamCity:</p>
<p style="text-align:justify;"><img src="http://kain64b.files.wordpress.com/2009/04/042309-0831-testcomplet3.png" alt="" /></p>
<p style="text-align:justify;">
<p style="text-align:justify;">
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[HowTo: Continuous Integration for Rails applications in GIT with TeamCity.]]></title>
<link>http://chukovskij.wordpress.com/2009/03/23/howto-continuous-integration-for-rails-applications-in-git-with-teamcity/</link>
<pubDate>Mon, 23 Mar 2009 12:01:59 +0000</pubDate>
<dc:creator>chukovskij</dc:creator>
<guid>http://chukovskij.wordpress.com/2009/03/23/howto-continuous-integration-for-rails-applications-in-git-with-teamcity/</guid>
<description><![CDATA[I&#8217;ve just setup RSpec tests on TeamCity 4.0.2 buildserver for my rails project that is located]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve just setup RSpec tests on TeamCity 4.0.2 buildserver for my rails project that is located under GIT version control!</p>
<p><img class="alignnone size-full wp-image-30" title="teamcity_rspec_demo" src="http://chukovskij.wordpress.com/files/2009/03/picture-17.png" alt="teamcity_rspec_demo" width="460" height="218" /><br />
<!--more--></p>
<p>To install git plugin see <a title="Visit site" href="http://www.knowledgetree.com/blog/continuous-integration-with-teamcity-git">instructions</a>. If you don&#8217;t want to build git plugin manually your can take my build (22 march, 2009). Also I zipped it with correct folder structure (download <a title="Download and remove .png extension" href="http://chukovskij.wordpress.com/files/2009/03/gitagentzip.png">gitagentzip.png</a> and rename to &#8220;gitAgent.zip&#8221; )</p>
<p>Also don&#8217;t forget to:</p>
<p>1. Setup <strong>Project Directory (Server): </strong>path in VCS settings. This is destination path to folder where Git plugin will clone git repository.</p>
<p>E.g. your <strong>VCS Git</strong> settings will be like this:</p>
<p><img class="alignnone size-full wp-image-17" title="teamcity_git_settings" src="http://chukovskij.wordpress.com/files/2009/03/picture-15.png" alt="teamcity_git_settings" width="460" height="296" /></p>
<p>If you leave Project Directory(Server) empty you will see NullPointer Exception:</p>
<blockquote><p>jetbrains.buildServer.serverSide.ExecutionException: Unable to collect changes jetbrains.buildServer.serverSide.ExecutionException: Unable to collect changes 	at jetbrains.buildServer.serverSide.impl.BuildChangesCollector.collectChanges(BuildChangesCollector.java:1) 	at jetbrains.buildServer.serverSide.impl.BuildStarter$1.run(BuildStarter.java:21) 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 	at java.util.concurrent.FutureTask.run(FutureTask.java:138) 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) 	at java.lang.Thread.run(Thread.java:637) Caused by: java.util.concurrent.ExecutionException: jetbrains.buildServer.vcs.VcsException: &#8216;/usr/bin/git clone -n ssh://git@unit-249/~/browser.git /Users/romeo/app/TeamCity/work/git&#8217; command failed. stderr: fatal: destination directory &#8216;/Users/romeo/app/TeamCity/work/git&#8217; already exists.   	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 	at java.util.concurrent.FutureTask.get(FutureTask.java:83) 	at jetbrains.buildServer.serverSide.impl.CancelableTaskHolder.waitForTaskToComplete(CancelableTaskHolder.java:9) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl.doCollectChanges(TopBuildDependencyGraphImpl.java:3) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl.access$000(TopBuildDependencyGraphImpl.java:49) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl$3.run(TopBuildDependencyGraphImpl.java:2) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl$3.run(TopBuildDependencyGraphImpl.java:1) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl$4.run(TopBuildDependencyGraphImpl.java:1) 	at jetbrains.buildServer.serverSide.impl.auth.SecurityContextImpl.runAs(SecurityContextImpl.java:24) 	at jetbrains.buildServer.serverSide.impl.auth.SecurityContextImpl.runAsSystem(SecurityContextImpl.java:31) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl.runAsSystem(TopBuildDependencyGraphImpl.java:60) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl.collectChanges(TopBuildDependencyGraphImpl.java:54) 	at jetbrains.buildServer.serverSide.impl.dependency.TopBuildDependencyGraphImpl.collectChanges(TopBuildDependencyGraphImpl.java:75) 	at jetbrains.buildServer.serverSide.impl.BuildChangesCollector.collectChanges(BuildChangesCollector.java:0) 	&#8230; 7 more Caused by: jetbrains.buildServer.vcs.VcsException: &#8216;/usr/bin/git clone -n ssh://git@unit-249/~/browser.git /Users/romeo/app/TeamCity/work/git&#8217; command failed. stderr: fatal: destination directory &#8216;/Users/romeo/app/TeamCity/work/git&#8217; already exists.   	at org.hivedb.teamcity.plugin.commands.CommandUtil.commandFailed(CommandUtil.java:32) 	at org.hivedb.teamcity.plugin.commands.CommandUtil.checkCommandFailed(CommandUtil.java:15) 	at org.hivedb.teamcity.plugin.commands.CommandUtil.runCommand(CommandUtil.java:39) 	at org.hivedb.teamcity.plugin.commands.GitCommand.exec(GitCommand.java:37) 	at org.hivedb.teamcity.plugin.commands.CloneCommand.run(CloneCommand.java:31) 	at org.hivedb.teamcity.plugin.GitVcs.getCurrentVersion(GitVcs.java:35) 	at jetbrains.buildServer.buildTriggers.vcs.VcsChangesLoader.getCurrentVersion(VcsChangesLoader.java:43) 	at jetbrains.buildServer.vcs.impl.VcsManagerImpl.getVersionsForAllRoots(VcsManagerImpl.java:415) 	at jetbrains.buildServer.vcs.impl.VcsManagerImpl.loadChanges(VcsManagerImpl.java:513) 	at jetbrains.buildServer.serverSide.impl.auth.SecuredVcsManager.loadChanges(SecuredVcsManager.java:72) 	at jetbrains.buildServer.vcs.impl.VcsChangesCollectorImpl$3.call(VcsChangesCollectorImpl.java:2) 	at jetbrains.buildServer.vcs.impl.VcsChangesCollectorImpl$3.call(VcsChangesCollectorImpl.java:1) 	&#8230; 5 more</p></blockquote>
<p>2. Set <strong>VCS checkout mode</strong> to &#8220;Automatically on agent (if supported by VCS)&#8221;</p>
<p>3. git should be in system PATH</p>
<p>And my <strong>Rake build runner</strong> settings are:</p>
<p><img class="alignnone size-full wp-image-18" title="teamcity_rake_settings" src="http://chukovskij.wordpress.com/files/2009/03/picture-16.png" alt="teamcity_rake_settings" width="460" height="348" /></p>
<p>Enjoy!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Good-bye broken builds]]></title>
<link>http://rasmusson.wordpress.com/2009/03/15/good-bye-broken-builds/</link>
<pubDate>Sun, 15 Mar 2009 22:47:46 +0000</pubDate>
<dc:creator>JR</dc:creator>
<guid>http://rasmusson.wordpress.com/2009/03/15/good-bye-broken-builds/</guid>
<description><![CDATA[The smart folks at JetBrains just made our lives a lot easier. TeamCity 4.0 has an extra verificatio]]></description>
<content:encoded><![CDATA[The smart folks at JetBrains just made our lives a lot easier. TeamCity 4.0 has an extra verificatio]]></content:encoded>
</item>

</channel>
</rss>
