{"id":129,"date":"2010-06-13T21:08:11","date_gmt":"2010-06-14T03:08:11","guid":{"rendered":"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2010\/06\/13\/extreme-continuous-integration-a-personal-ci-build-for-visual-studio-part-1\/"},"modified":"2011-09-17T21:26:47","modified_gmt":"2011-09-18T03:26:47","slug":"extreme-continuous-integration-a-personal-ci-build-for-visual-studio-part-1","status":"publish","type":"post","link":"http:\/\/architester.com\/blog\/2010\/06\/13\/extreme-continuous-integration-a-personal-ci-build-for-visual-studio-part-1\/","title":{"rendered":"Extreme Continuous Integration: A Personal CI Build For Visual Studio &ndash; Part 1"},"content":{"rendered":"<p><em>How I run a personal CI build every time I build my code in Visual Studio.<\/em><\/p>\n<h2>Summary<\/h2>\n<p>In this series I show you how to take continuous integration to the extreme by building a personal CI server that runs all your tests and adds a commit to source control every time you build in Visual Studio.<\/p>\n<p>This week, we look at the overview of the problem and the proposed solution.<\/p>\n<ul>\n<li><strong>Extreme CI Part 1 \u00e2\u20ac\u201c Overview <em>(you are here)<\/em><\/strong><\/li>\n<li><a title=\"Extreme CI Part 2\" href=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2010\/06\/20\/extreme-ci-part-2-setting-up-git-for-a-personal-ci\/\" target=\"_self\">Extreme CI Part 2 \u00e2\u20ac\u201c Setting Up Git<\/a><\/li>\n<li><a title=\"Extreme CI Part 3\" href=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2010\/06\/21\/extreme-ci-part-3-the-visual-studio-macro\/\" target=\"_self\">Extreme CI Part 3 \u00e2\u20ac\u201c The Visual Studio Macro<\/a><\/li>\n<\/ul>\n<h2>The Problem<\/h2>\n<p>As more and more tests are written for a project, they take longer and longer to run. Even after optimizing tests I find that I spend far too much time waiting for them to run. So what do I do? I stop running all the tests, and only run part of them. But then how do I know when I have broken a test if I am not running it? And there lies the rub. It\u00e2\u20ac\u2122s a catch-22. I try to save time by running fewer tests, only to lose time fixing errors those tests were written to protect me from. What to do?<\/p>\n<h2>The Idea<\/h2>\n<p>I thought, \u00e2\u20ac\u0153If only I could keep working while the tests were running\u00e2\u20ac\u00a6But that would mean they would need to run on another machine\u00e2\u20ac\u00a6How would I kick that off\u00e2\u20ac\u00a6\u00e2\u20ac\u009d Then it hit me, \u00e2\u20ac\u0153I do this all the time, I just need a CI server.\u00e2\u20ac\u009d Then the ideas just started flowing\u00e2\u20ac\u00a6<\/p>\n<blockquote><p><span style=\"background-color: #ffffff;\"><em>Sidebar<\/em><\/span><\/p>\n<p><span style=\"background-color: #ffffff;\"><strong>Continuous Integration:<\/strong><\/span><\/p>\n<p><span style=\"background-color: #ffffff;\">Continuous Integration is an Agile\/XP practice where developers check their code into a source code repository very often (at least once a day) and an automated process builds the code and runs all the tests against it to ensure quality. <\/span><\/p>\n<p><span style=\"background-color: #ffffff;\"> <\/span><\/p>\n<p><span style=\"background-color: #ffffff;\">To run this automated process, we a Continuous Integration Server application. This software can be configured to check the source control repository for changes, and kick off your build scripts (that you write) to compile your code, and run your tests. You can run unit, integration, and ever UI-tests. Its common to build installers and gather code metrics, etc., all automatically.<\/span><\/p>\n<p><span style=\"background-color: #ffffff;\"> <\/span><\/p>\n<p><span style=\"background-color: #ffffff;\">The top three CI Servers for .NET projects are <\/span><span style=\"background-color: #ffffff;\"><a href=\"http:\/\/ccnet.thoughtworks.com\/\" target=\"_blank\">CruiseControl.NET<\/a>, <\/span><span style=\"background-color: #ffffff;\"><a href=\"http:\/\/www.jetbrains.com\/teamcity\/index.html\" target=\"_blank\">TeamCity<\/a>, and <\/span><span style=\"background-color: #ffffff;\"><a href=\"http:\/\/hudson-ci.org\/\" target=\"_blank\">Hudson<\/a><\/span><\/p><\/blockquote>\n<p>If I could get a CI Server just for me, a \u00e2\u20ac\u0153Personal CI\u00e2\u20ac\u009d, and have it kick off every time I run my tests (even if I don\u00e2\u20ac\u2122t run them all), then I could get out of that catch-22 and save time running tests because they will run automatically on another server while I continue working.<\/p>\n<p>As an added bonus, I could have the CI Server tag the versions of the code that passed all the tests so I could roll back to the most recent good state if I ever needed to.<\/p>\n<h2>How It Works<\/h2>\n<p>So I schemed an planned, and tried, failed, and tried again, and here is what I came up with.<\/p>\n<p><a href=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/wp-content\/uploads\/2010\/06\/image.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;\" title=\"image\" src=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/wp-content\/uploads\/2010\/06\/image_thumb.png\" border=\"0\" alt=\"image\" width=\"463\" height=\"544\" \/><\/a><\/p>\n<ul>\n<li>I build my code in Visual Studio.<\/li>\n<li>A custom Visual Studio macro commits all my changes to a local Git repository.<\/li>\n<li>The macro then pushes the changes to the Git repository that the CI Server is watching.<\/li>\n<li>The CI Server sees the changes, pulls them down, builds the code, and runs all the tests.<\/li>\n<li>When all the tests pass, the CI server can tag that version of the code so we can roll back to it if necessary.<\/li>\n<li>On failure, the CI notifies me.<\/li>\n<\/ul>\n<p>Lets walk through the major parts of this process.<\/p>\n<h3>The Visual Studio Macro<\/h3>\n<p>I chose to trigger the process when building rather than running the tests.\u00c2\u00a0 I did this for two reasons: (1) I wanted to run the tests as often as possible, (I build my code more often than I run the tests.) and (2) it was much easier than triggering off the test runner.<\/p>\n<p>When code is built in Visual Studio, it fires of several events that can be captured by custom macros. When the macro fires off, it will execute a batch file that calls git on the command line to commit our code to the git repository and push it to the CI\u00e2\u20ac\u2122s repository. The batch file is executed as an \u00e2\u20ac\u0153External Tool\u00e2\u20ac\u009d since we cant just shell out to the command prompt from the macro.<\/p>\n<h3>The Git Repositories<\/h3>\n<p>This process involves two repositories. The first is on the developer\u00e2\u20ac\u2122s machine. It\u00e2\u20ac\u2122s the developer\u00e2\u20ac\u2122s local working repository. The second is the CI Server\u00e2\u20ac\u2122s repository. This is set up as a remote on the developer\u00e2\u20ac\u2122s repository so the changes can be pushed to the CI server.<\/p>\n<p>I chose to use Git because it can work side by side with other source control packages.. If you are using SubVersion, you can just tell subversion to ignore the .Git folder and use them both.. If you are using Git, you can push to the CI Server\u00e2\u20ac\u2122s repository without pushing to other developer repositories or your main repository. Its just another remote.<\/p>\n<h3>The CI Server<\/h3>\n<p>The CI server will detect that the new code has been committed to the repository, check it out, and run your build script against it to build the code and run the tests. What CI you choose to use is up to you. Hopefully, if you are setting up a personal CI Server, you already have a team CI Server that you are using. If not, you need to set up one of those first. So you would likely use the same CI Server software. I have done this with Hudson and TeamCity, though CCNet would work as well.<\/p>\n<p>I set my CI Server up on my personal laptop and had it running next to my dev box. That way I could watch it run the tests and know immediately if it fails (using email or a CI monitor for notification works just as well).\u00c2\u00a0 Alternatively, you could also set up another box or VM somewhere on the network. I wouldn\u00e2\u20ac\u2122t recommend running it on your dev machine (either in a VM, or directly on the machine) because that would really slow your machine down and defeat the purpose. Whatever machine you use, it doesn\u00e2\u20ac\u2122t have to be a really fast one. After all, its running on its own so you don\u00e2\u20ac\u2122t have to wait for it, so speed isn\u00e2\u20ac\u2122t that big of a deal.<\/p>\n<h3>The Build Script<\/h3>\n<p>This is the script that builds your code and runs your tests. Use MSBuild, NAnt, PowerShell, Rake, or whatever floats our boat. If you have a team CI Server running, you can usually just use its script.<\/p>\n<p>You can set this script up to tag the code when the tests pass if you like. Then you can roll back to the last known state where the tests passed.<\/p>\n<p><a href=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2010\/06\/20\/extreme-ci-part-2-setting-up-git-for-a-personal-ci\/\" target=\"_blank\">Next week<\/a> we\u00e2\u20ac\u2122ll look at how to set up the Git repositories and automate pushing files from the developer\u00e2\u20ac\u2122s working repository up to the CI Server.<\/p>\n<p><a href=\"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2010\/06\/20\/extreme-ci-part-2-setting-up-git-for-a-personal-ci\/\" target=\"_blank\">Extreme CI Part 2: Setting Up Git<\/a><\/p>\n<p>-Chris<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How I run a personal CI build every time I build my code in Visual Studio. Summary In this series I show you how to take continuous integration to the extreme by building a personal CI server that runs all your tests and adds a commit to source control every time you build in Visual [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,4,32,8,33],"tags":[79,76,82,71,83],"class_list":["post-129","post","type-post","status-publish","format-standard","hentry","category-net","category-agile","category-continuous-integration","category-testing","category-visual-studio","tag-net","tag-agile","tag-continuous-integration","tag-testing","tag-visual-studio"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/comments?post=129"}],"version-history":[{"count":7,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":410,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/129\/revisions\/410"}],"wp:attachment":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/media?parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/categories?post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/tags?post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}