{"id":982,"date":"2011-02-24T23:26:51","date_gmt":"2011-02-24T22:26:51","guid":{"rendered":"http:\/\/blog.eweibel.net\/?p=982"},"modified":"2011-07-14T18:15:44","modified_gmt":"2011-07-14T16:15:44","slug":"jenkins-and-net","status":"publish","type":"post","link":"https:\/\/blog.eweibel.net\/?p=982","title":{"rendered":"Jenkins and .Net"},"content":{"rendered":"<p><a href=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/butler.gif\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px\" title=\"butler\" border=\"0\" alt=\"butler\" align=\"right\" src=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/butler_thumb.gif\" width=\"102\" height=\"102\" \/><\/a> This week I visited the first <a href=\"http:\/\/www.jugs.ch\/\" target=\"_blank\">JUG\u2019s<\/a> event in Bern. The topic was <a href=\"http:\/\/jenkins-ci.org\/\" target=\"_blank\">Jenkins<\/a> (<a href=\"http:\/\/www.infoq.com\/news\/2011\/01\/jenkins\" target=\"_blank\">fork of Hudson<\/a>). The presentation of <a href=\"http:\/\/www.simonwiest.de\/\" target=\"_blank\">Dr. Simon Wiest<\/a> was very entertaining. He explained continuous integration and showed how easy it is to install, configure and run Jenkins.<\/p>\n<p><strong>.Net integration in Jenkins<\/strong><\/p>\n<p>Jenkins is from the <a href=\"http:\/\/www.readwriteweb.com\/enterprise\/2011\/01\/the-java-ecosystem-infographic.php\" target=\"_blank\">Java ecosystem<\/a>, so it isn\u2019t obvious to use it in a .Net environment. But one of best thing of Jenkins is that there exists a lot of plugins. So, there are also plugins for .Net:<\/p>\n<ul>\n<li>MSBuild support<\/li>\n<li>NAnt support <\/li>\n<li>MSTest support <\/li>\n<li>NUnit support<\/li>\n<li>NCover support <\/li>\n<li>TFS support <\/li>\n<\/ul>\n<p><strong>Installation<\/strong><\/p>\n<p>First you have to download Jenkins from <a href=\"http:\/\/jenkins-ci.org\" target=\"_blank\">http:\/\/jenkins-ci.org<\/a>. Then you type on the console:<\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f7a70227-efe9-4515-ab07-4dfcba72a2b8\" class=\"wlWriterEditableSmartContent\">\n<pre class=\"brush: bash;\">java -jar jenkins.war<\/pre>\n<\/div>\n<p>And that was the whole installation. Well, you could now install Jenkins as a windows service, but that isn\u2019t hard too. There exists a command to do that in the \u201cManage Jenkins\u201d menu.<\/p>\n<p>To use Jenkins in a .Net environment you have to install the needed plugins first. I installed the following plugins through the UI:<\/p>\n<ul>\n<li>MSBuild <\/li>\n<li>NUnit <\/li>\n<\/ul>\n<p>After you installed the plugins you have to restart Jenkins and don\u2019t forget to check if you have to configure the installed plugins.<\/p>\n<p><strong>Simple project setup<\/strong><\/p>\n<p>To show the configuration, I show you the same project \u201cDokuDB\u201d on Jenkins and&#160; on CruiseControl.NET.<\/p>\n<p><a href=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/image12.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/image_thumb12.png\" width=\"600\" height=\"205\" \/><\/a><\/p>\n<p><a href=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/image13.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/blog.eweibel.net\/wp-content\/uploads\/image_thumb13.png\" width=\"598\" height=\"197\" \/><\/a> <\/p>\n<p>The project \u201cDokuDB\u201d is&#160; a .Net 4.0 project with a NUnit Test project. So, the steps of the build servers has to be the following:<\/p>\n<ol>\n<li>Get sources out of the SVN repository<\/li>\n<li>Build the application<\/li>\n<li>Run the unit tests<\/li>\n<li>Examine the results of the unit tests <\/li>\n<\/ol>\n<p><strong>Sample with Jenkins<\/strong><\/p>\n<p>You can configure your build of your project through XML or UI. If you haven\u2019t much experiences with Jenkins I recommend the UI way. The resulting XML is the following: <\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:f2bc3cee-3869-43a8-ab1f-d4b54a66153e\" class=\"wlWriterEditableSmartContent\">\n<pre class=\"brush: xml;\">&lt;?xml version='1.0' encoding='UTF-8'?&gt;\r\n&lt;project&gt;\r\n  &lt;actions\/&gt;\r\n  &lt;description&gt;&lt;\/description&gt;\r\n  &lt;keepDependencies&gt;false&lt;\/keepDependencies&gt;\r\n  &lt;properties\/&gt;\r\n  &lt;scm class=\"hudson.scm.SubversionSCM\"&gt;\r\n    &lt;locations&gt;\r\n      &lt;hudson.scm.SubversionSCM_-ModuleLocation&gt;\r\n        &lt;remote&gt;svn:\/\/&lt;svn-server&gt;\/&lt;svn-repo&gt;\/trunk&lt;\/remote&gt;\r\n        &lt;local&gt;.&lt;\/local&gt;\r\n      &lt;\/hudson.scm.SubversionSCM_-ModuleLocation&gt;\r\n    &lt;\/locations&gt;\r\n    &lt;browser class=\"hudson.scm.browsers.WebSVN\"&gt;\r\n      &lt;url&gt;http:\/\/&lt;WebSVN-server&gt;\/listing.php\/?repname=&lt;svn-repo&gt;&lt;\/url&gt;\r\n    &lt;\/browser&gt;\r\n    &lt;excludedRegions&gt;&lt;\/excludedRegions&gt;\r\n    &lt;includedRegions&gt;&lt;\/includedRegions&gt;\r\n    &lt;excludedUsers&gt;&lt;\/excludedUsers&gt;\r\n    &lt;excludedRevprop&gt;&lt;\/excludedRevprop&gt;\r\n    &lt;excludedCommitMessages&gt;&lt;\/excludedCommitMessages&gt;\r\n    &lt;workspaceUpdater class=\"hudson.scm.subversion.UpdateUpdater\"\/&gt;\r\n  &lt;\/scm&gt;\r\n  &lt;canRoam&gt;true&lt;\/canRoam&gt;\r\n  &lt;disabled&gt;false&lt;\/disabled&gt;\r\n  &lt;blockBuildWhenDownstreamBuilding&gt;false&lt;\/blockBuildWhenDownstreamBuilding&gt;\r\n  &lt;blockBuildWhenUpstreamBuilding&gt;false&lt;\/blockBuildWhenUpstreamBuilding&gt;\r\n  &lt;triggers class=\"vector\"&gt;\r\n    &lt;hudson.triggers.SCMTrigger&gt;\r\n      &lt;spec&gt;* * * * *&lt;\/spec&gt;\r\n    &lt;\/hudson.triggers.SCMTrigger&gt;\r\n  &lt;\/triggers&gt;\r\n  &lt;concurrentBuild&gt;false&lt;\/concurrentBuild&gt;\r\n  &lt;builders&gt;\r\n    &lt;hudson.plugins.msbuild.MsBuildBuilder&gt;\r\n      &lt;msBuildName&gt;MSBuild 4.0&lt;\/msBuildName&gt;\r\n      &lt;msBuildFile&gt;src\/Doad\/Doad.sln&lt;\/msBuildFile&gt;\r\n      &lt;cmdLineArgs&gt;\/t:Clean;Rebuild&lt;\/cmdLineArgs&gt;\r\n    &lt;\/hudson.plugins.msbuild.MsBuildBuilder&gt;\r\n    &lt;hudson.tasks.BatchFile&gt;\r\n      &lt;command&gt;\"c:\\Program Files (x86)\\NUnit 2.5.8\\bin\\net-2.0\\nunit-console.exe\" src\/Doad\/Doad.Test\/bin\/debug\/Doad.Test.dll&lt;\/command&gt;\r\n    &lt;\/hudson.tasks.BatchFile&gt;\r\n  &lt;\/builders&gt;\r\n  &lt;publishers&gt;\r\n    &lt;hudson.plugins.nunit.NUnitPublisher&gt;\r\n      &lt;testResultsPattern&gt;*.xml&lt;\/testResultsPattern&gt;\r\n      &lt;debug&gt;false&lt;\/debug&gt;\r\n      &lt;keepJUnitReports&gt;false&lt;\/keepJUnitReports&gt;\r\n      &lt;skipJUnitArchiver&gt;false&lt;\/skipJUnitArchiver&gt;\r\n    &lt;\/hudson.plugins.nunit.NUnitPublisher&gt;\r\n  &lt;\/publishers&gt;\r\n  &lt;buildWrappers\/&gt;\r\n&lt;\/project&gt;<\/pre>\n<\/div>\n<p>Jenkins doesn\u2019t have by default an application for the system tray on the developer machines, so that the developer can observe the build state. But there are two available tray-apps:<\/p>\n<ul>\n<li><a href=\"http:\/\/wiki.hudson-ci.org\/display\/HUDSON\/Hudson+Tray+Application\" target=\"_blank\">Hudson Tray Application<\/a><\/li>\n<li><a href=\"http:\/\/code.google.com\/p\/hudson-tray-tracker\/\" target=\"_blank\">Hudson-Tray-Tracker<\/a>&#160;<\/li>\n<\/ul>\n<p><strong>Sample with CruiseControl.NET<\/strong><\/p>\n<p>To configure your build in CruiseControl.NET you have to edit the ccnet.config file. CruiseControl.Net hasn\u2019t an UI to edit the configuration, but there is an application to validate the config file: CCValidator. The resulting config file for the sample project looks like that:<\/p>\n<div style=\"padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px\" id=\"scid:f32c3428-b7e9-4f15-a8ea-c502c7ff2e88:50af2d32-c123-4a6c-9bc5-2232113eb876\" class=\"wlWriterEditableSmartContent\">\n<pre class=\"brush: xml;\">&lt;cruisecontrol xmlns:cb=\"urn:ccnet.config.builder\"&gt;\r\n\t&lt;project&gt;\r\n\t\t&lt;name&gt;DokuDB&lt;\/name&gt;\r\n\t\t&lt;sourcecontrol type=\"svn\"&gt;\r\n\t\t\t&lt;executable&gt;C:\\Program Files (x86)\\Subversion\\bin\\svn.exe&lt;\/executable&gt;\r\n\t\t\t&lt;trunkUrl&gt;svn:\/\/&lt;svn-server&gt;\/&lt;svn-repo&gt;\/trunk&lt;\/trunkUrl&gt;\r\n\t\t\t&lt;workingDirectory&gt;c:\\Integration\\DokuDB&lt;\/workingDirectory&gt;\r\n\t\t\t&lt;webUrlBuilder type=\"websvn\"&gt;\r\n\t\t\t\t&lt;url&gt;http:\/\/&lt;WebSVN-server&gt;\/diff.php?repname=&lt;svn-repo&gt;&amp;amp;path={0}&amp;amp;rev={1}&amp;amp;ignorews=1&lt;\/url&gt;\r\n\t\t\t&lt;\/webUrlBuilder&gt;\r\n\t\t&lt;\/sourcecontrol&gt;\r\n\t\t&lt;tasks&gt;\r\n\t\t\t&lt;msbuild&gt;\r\n\t\t\t\t&lt;executable&gt;C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe&lt;\/executable&gt;\r\n\t\t\t\t&lt;workingDirectory&gt;C:\\Integration\\Doad\\src\\Doad&lt;\/workingDirectory&gt;\r\n\t\t\t\t&lt;projectFile&gt;Doad.sln&lt;\/projectFile&gt;\r\n\t\t\t\t&lt;targets&gt;Clean;Rebuild&lt;\/targets&gt;\r\n\t\t\t\t&lt;logger&gt;C:\\Program Files (x86)\\CruiseControl.NET\\server\\ThoughtWorks.CruiseControl.MsBuild.dll&lt;\/logger&gt;\r\n\t\t\t&lt;\/msbuild&gt;\r\n\t\t\t&lt;exec executable=\"C:\\Integration\\Doad\\src\\Doad\\packages\\NUnit.2.5.7.10213\\Tools\\nunit-console.exe\" buildArgs=\"C:\\Integration\\Doad\\src\\Doad\\Doad.Test\\bin\\Debug\\Doad.Test.dll \/xml:doad-results.xml \/nologo\"\/&gt;\r\n\t\t&lt;\/tasks&gt;\r\n\t\t&lt;publishers&gt;\r\n\t\t\t&lt;merge&gt;\r\n\t\t\t\t&lt;files&gt;\r\n\t\t\t\t\t&lt;file&gt;doad-results.xml&lt;\/file&gt;\r\n\t\t\t\t&lt;\/files&gt;\r\n\t\t\t&lt;\/merge&gt;\r\n\t\t\t&lt;xmllogger \/&gt;\r\n\t\t&lt;\/publishers&gt;\r\n\t\t&lt;triggers&gt;\r\n\t\t\t&lt;intervalTrigger name=\"Continuous integration\" seconds=\"30\" initialSeconds=\"30\" \/&gt;\r\n\t\t&lt;\/triggers&gt;\r\n\t&lt;\/project&gt;\r\n&lt;\/cruisecontrol&gt;<\/pre>\n<\/div>\n<p>CruiseControl.Net has an own System Tray application, the CCTray. <\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>Jenkins is really easy and fast to install and configure. In comparison to CruiseControl.NET the Look&amp;Feel is much nicer.&#160; <br \/>All downloaded plugins for .Net worked well except the TFS-plugin, but there was maybe a problem with the Team Foundation server. <\/p>\n<p>For the next (ALT.NET)-project I consider to use Jenkins instead of CruiseControl.NET.<\/p>\n<p>Dr. Simon Wiest wrote also a book about Hudson:<\/p>\n<p><SCRIPT charset=\"utf-8\" type=\"text\/javascript\" src=\"http:\/\/ws.amazon.de\/widgets\/q?ServiceVersion=20070822&amp;MarketPlace=DE&amp;ID=V20070822\/DE\/assumptiofadv-21\/8001\/f64b8651-e15c-4bf5-ad94-94546f1ef05f\"> <\/SCRIPT><noscript><\/noscript><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week I visited the first JUG\u2019s event in Bern. The topic was Jenkins (fork of Hudson). The presentation of Dr. Simon Wiest was very entertaining. He explained continuous integration and showed how easy it is to install, configure and run Jenkins. .Net integration in Jenkins Jenkins is from the Java ecosystem, so it isn\u2019t obvious to use it in a .Net environment. But one of best thing of Jenkins is that there exists a lot of plugins. So, there&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/blog.eweibel.net\/?p=982\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[13,7,6],"tags":[],"class_list":["post-982","post","type-post","status-publish","format-standard","hentry","category-net","category-first-experiencies","category-new-technology"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/plOV9-fQ","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1014,"url":"https:\/\/blog.eweibel.net\/?p=1014","url_meta":{"origin":982,"position":0},"title":"Master of Advanced Studies in Information Technology","author":"Patrick","date":"9. May 2011","format":false,"excerpt":"During the last three years I was a part-time student again because I did at the university of applied science in Berne a post-grade study. Last week I received my certificate and the new title on the CV is now \u201cMaster of Advanced Studies in Information Technology\u201d. I chose the\u2026","rel":"","context":"In &quot;Private&quot;","block_context":{"text":"Private","link":"https:\/\/blog.eweibel.net\/?cat=9"},"img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/image_thumb16.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":160,"url":"https:\/\/blog.eweibel.net\/?p=160","url_meta":{"origin":982,"position":1},"title":"When to use stored procedures","author":"Patrick","date":"13. May 2009","format":false,"excerpt":"Recently I discussed with a colleague when to use stored procedures. As exptected it was quite a religious conversation. A few days later I found the following screencast: The Pros and Cons of Stored Procedures Based on the discussion and the screencast I tried to summarize my Pros and Cons:\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":622,"url":"https:\/\/blog.eweibel.net\/?p=622","url_meta":{"origin":982,"position":2},"title":"Branching practices","author":"Patrick","date":"6. Apr 2010","format":false,"excerpt":"In an environment where several developers work at the same code base or several features have to be implemented, then branching will be a topic. I was asked to create a branching guide for my current employer which use TFS as source code repository. Motivation In our projects I found\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/image_thumb3.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/image_thumb3.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/image_thumb3.png?resize=525%2C300 1.5x"},"classes":[]},{"id":954,"url":"https:\/\/blog.eweibel.net\/?p=954","url_meta":{"origin":982,"position":3},"title":"Visualize changes in your repository","author":"Patrick","date":"17. Feb 2011","format":false,"excerpt":"As you perhaps know, there exists a very interesting project on Google code, with which you can visualize the activities on your repository: Gource. Getting started It supports Git, Mercurial, Bazaar and SVN. There is also a way to visualize the changes in a repository of a Microsoft Team Foundation\u2026","rel":"","context":"In &quot;New technology&quot;","block_context":{"text":"New technology","link":"https:\/\/blog.eweibel.net\/?cat=6"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":499,"url":"https:\/\/blog.eweibel.net\/?p=499","url_meta":{"origin":982,"position":4},"title":"Favoured podcasts","author":"Patrick","date":"1. Nov 2009","format":false,"excerpt":"I migrated my desktop PC to Windows 7 Professional. I didn\u2019t choose the upgrade path, I install Windows 7 from scratch. So, after installing iTunes I had to register my favoured podcasts again: .Net .Net Rocks! Hanselminutes herding {code} Stackoverflow Polymorphic Podcast Alt.NET podcast Java The Java Posse Software engineering\u2026","rel":"","context":"In &quot;.NET&quot;","block_context":{"text":".NET","link":"https:\/\/blog.eweibel.net\/?cat=13"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1117,"url":"https:\/\/blog.eweibel.net\/?p=1117","url_meta":{"origin":982,"position":5},"title":"Speaking at the .NET Usergroup Zentralschweiz","author":"Patrick","date":"18. Nov 2011","format":false,"excerpt":"I'm holding at the .NET Usergroup Zentralschweiz a short talk about \"Know your warm-up\", see my last blog post. I'll explain what I developed exactly and how I train new employees with this warm-up. I will also demonstrate the sample application which a new employee develops from scratch. Come to\u2026","rel":"","context":"In &quot;Good practices&quot;","block_context":{"text":"Good practices","link":"https:\/\/blog.eweibel.net\/?cat=5"},"img":{"alt_text":"dotnetzentral","src":"https:\/\/i0.wp.com\/blog.eweibel.net\/wp-content\/uploads\/dotnetzentral_thumb.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=982"}],"version-history":[{"count":15,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/982\/revisions"}],"predecessor-version":[{"id":1071,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=\/wp\/v2\/posts\/982\/revisions\/1071"}],"wp:attachment":[{"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.eweibel.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}