Monday, June 18, 2007

Cruising with Subversion, Part 1

With a Subversion server functioning and a project loaded, it is time to install CruiseControl.Net and configure it to access the Subversion project in source control (Part 1), automate build tasks using MSBuild (Part 2) and finally look at the optional CruiseControl.NET configuration options that are of interest (Part 3).

From here on I'll be using a real project I have published on my public Subversion server. The project is a small Visual Studio 2005 library to liven up console applications. While the project library is perhaps tad archaic, I still have a soft spot for command-line and console-based applications.

First step is to download and install CruiseControl.NET. A word to the wise - if you are using Subversion as your source control repository, avoid using CrusieControl.NET 1.2; it has a few bugs that prevent it from operating correctly with Subversion. Thankfully, these bugs have been eradicated in the 1.2.1 release. I have installed CruiseControl.NET 1.2.1 using all of the default options.
  • The configuration file for CruiseControl is usually located at C:\CruiseControl.NET\server\ccnet.config
  • The subversion repository I will be using is located at svn://cognitivefusion.com/GPL
  • The project I am using is under the above repository at trunk\src\CognitiveFusion.Console
Open the ccnet.config file in a text or xml editor. The initial document looks like this:

<cruisecontrol>
<!-- This is your CruiseControl.NET Server Configuration file. Add your projects below! -->
<!-- <project name="MyFirstProject"> -->
</cruisecontrol>

For each project to be managed by CruiseControl, you need to add a <project> configuration block, like so:

<cruisecontrol>
<project name="CognitiveFusion.Console" />
</cruisecontrol>


Next add the <sourcecontrol> configuration block to tell CruiseControl.NET where the Subversion source control repository is located:

<cruisecontrol>
<project name="CognitiveFusion.Console">
<sourcecontrol type="svn">
<trunkUrl>svn://svn.cognitivefusion.com/GPL/trunk/src</trunkUrl>
<workingDirectory>c:\Program Files\CruiseControl.NET\Builds\GPL\trunk\src</workingDirectory>
<executable>[full path to svn.exe]</executable>
</sourcecontrol>
</project>
</cruisecontrol>


Assuming you are running a default Subversion install, this is all the configuration you need to have CruiseControl automatically pull the source. If you have a private subversion repository you will also need to define the <username> and <password> configuration blocks under <sourcecontrol>. To test the configuration start the CruiseControl.NET service and check the ccnet.log. If you installed the web dashboard, access it at http://localhost/ccnet.

With this minimal configuration, CruiseControl.NET will check the Subversion repository every 60 seconds for changes; tasks and publishers will execute (more on this in Part 2) when changes are detected.

In Cruising with Subversion, Part 2 we will configure MSBuild to trigger an automatic compile when CruiseControl.NET detects file changes.

Wednesday, April 18, 2007

Setup a working directory for Visual Studio

Picking up from yesterday, the trunk is now loaded with the source for a preexisting project. However, the structure we have now locally under Subversion Repositories is not ideal to work with in Visual Studio. The main problem is that the arrangement can make switching between the trunk, branches, and tags a hassle. Pulling a branch or tag under trunk then accidentally committing can be annoying. I also try not to fight the tools without good reason and Visual Studio 2005 likes to keep its projects in My Documents under Visual Studio 2005\Projects. For now I want to work out of that directory.

Create an empty project directory under My Documents\Visual Studio 2005\Projects. Right-click on the new directory and select the TortoiseSVN command SVN Checkout.... Within the Checkout dialog select the URL of the repository then click the browse button on the right to open the Repository Browser. Navigate to the directory that contains the source code (in my case it is under trunk\src), select the directory and click OK. Click OK on the Commit dialog, and TortoiseSVN will pull down the code.

Its that simple. After a little practice this process will become second nature.

Tuesday, April 17, 2007

Existing Codebase Meets New Repository

In two days I have installed Subversion and TortoiseSVN, set up a Subversion windows service to host multiple repositories, planned a repository structure and created the initial structure in a new repository. Not really a lot of work to speak of, but I'm taking my time. Now I am going to load an existing Visual Studio 2005 project into the waiting repository.

Before loading the existing code into the repository, take the time to clean up the project. Make sure your solution (*.sln) and project (*.csproj, *.vbproj, etc.) files are using relative paths to reference files and dependencies. If you were using Visual SourceSafe or another version control system, clear out the binding information and delete any files those systems may have created. After you have cleaned up references and stripped out any cruft, copy the project into a temp folder on the desktop and open it from there; this is to ensure the project files are clean. If you get any error messages on loading, there is likely a broken reference or a missed binding that needs to be removed.

Save the following cleanup until it is time to commit the project to Subversion.Visual Studio creates a number of artifacts that are not necessary for the integrity of a project. These files will be recreated by Visual Studio if they are missing when the project is opened in the IDE, so there is no reason to load them into the Subversion repository. The extensions of files that can be safely ignored are *.suo and *.user. Ignore the obj folder, the bin\Debug and bin\Release folders and their contents. Keep the bin directory into the repository to hold any locally referenced 3rd-party components: sticking them in and referencing them from the bin directory is a simple trick. Remove the cruft, then copy the project root into under trunk. The directory structure should now look similar to this:

My Documents\Subversion Repositories
\MyRepository
\branches
\tags
\trunk
\Project 1
\Project1.sln
[other project files...]


Note that the solution (*.sln) file is directly under trunk; I do this because I am using a repository for each solution. When placing more than one solution into a single repository, create folders for each solution under trunk, then put the project files under the appropriate solution folder. Just shift the whole branch down to accommodate the solution folder.

Once everything is in place (and the structure and files have been double-checked), right-click on trunk and select the TortoiseSVN command "SVN Commit..." Provide a descriptive check-in comment (not required, but a good habit), make sure all of the files and folders needed by the project are check in the Commit dialog then click OK. The files should be committed to the repository, and will now have the TortoiseSVN icon overlay appear on the file icon.

Monday, April 16, 2007

Initialize a New Repository

I have a newly created, configured and empty subversion repository tritely named {MyRepository}. I have put some time into planning the initial structure to meet my needs and am ready to initialize {MyRepository} using TortoiseSVN on a workstation running Windows XP Pro. The following instructions assume you are using Windows Explorer to setup the folder structures.

Housekeeping
First, create a new folder under My Documents named Subversion Repositories - this will serve as a root folder for managing multiple project repositories, but for now focus on getting the first one set up. Under Subversion Repositories create a new folder named MyRepository. The MyRepository folder will hold the working copy of the full contents of the subversion repository {MyRepository}.

Note on the naming/formatting conventions: from here on {MyRepository} refers to the Subversion repository and MyRepository refers to the folder under My Documents.

Sync with the Repository

  1. Right-click on MyRepository and select the TortoiseSVN command "SVN Checkout..." to open the Checkout dialog.
  2. Provide the path to {MyRepository} under URL of Repository.
  3. Click OK. Depending on the configuration of the repository, credentials may be requested.
TortoiseSVN will create a hidden folder named .svn under MyRepository. Do not mess with the contents of the .svn folder. Since {MyRepository} is empty, no other contents will be pulled down from the Subversion server. If you have rebooted since installing TortoiseSVN, you will see a green circle with a white check overlay the folder icon for MyRepository. (If you don't know what this means, I suggest you review the TortoiseSVN Icon Overlays.

Create the Initial Structure
I am creating my "ideal" initial structure as hashed out in the previous post. Substitute whatever structure you prefer here. Under MyRepository create three new folders named branches, tags and trunk. Under trunk create three new folders named doc, lib, and src.

Commit the Initial Structure
Now commit the changes to add the newly created folders to {MyRepository}:
  1. Right-click on MyRepository and select the TortoiseSVN command "SVN Commit..." to open the Commit dialog
  2. Type in a message describing the commit; "create initial structure" is what I use.
  3. If you have followed these instructions to the letter, you should only see the folders created under MyRepository. Check all of the folders you created for the initial structure, then click OK. You will probably be prompted for credentials.
You should now have a subversion repositoy with one revison checked in. All of the folders you committed should have the TortoiseSVN "Normal" icon overlay.

Planning a new Subversion Repository

The first thing to do before populating a repository is to plan out the structure. While Subversion has a decent set of functions for restructuring the contents of a repository, don't be forced to try them out due to poor planning. Avoid an unnecessary headache by thinking about the structure before committing the first file.

The documentation for Subversion and TortoiseSVN recommend using the traditional branches/tags/trunk structure at the repository root:

<Repository Root>
\branches
\tags
\trunk
\Project 1
\Project 2


The documentation also suggests an alternate structure using the project as the root:

<Repository Root>
\Project 1
\branches
\tags
\trunk
\Project 2
\branches
\tags
\trunk


I am opting to use the traditional layout using branches/tags/trunk. I am already separating top-level projects into independent repositories. I also like to keep non-code resources and reference materials with the project, so I am going to use an additional folder level below the trunk to split out source code, 3rd-party libraries, documents, etc:

<Brandon's Repository>
\branches
\tags
\trunk
\doc
\lib
\src
\Project 1
\Project 2


Now I will be able to store any additional files along with the trunk and avoid tangling them with the source code. The catch is that when branching/tagging from the trunk, it will include the other miscellaneous files. I am neutral on this... I'll have to see how it works in practice. In theory, I could branch from the trunk\src folder if I wanted to avoid the additional documents, but I think I want to keep the extra files in the branch for now.

Sunday, April 15, 2007

Hosting Multiple Subversion Repositories on Windows

I have decided I need to run multiple Subversion repositories under the same windows service. My original train of though was that I would just use a single repository and create a folder for each project off of the root. After reading a bit more, I found two facts that would make this kind of implementation distasteful:
  • I want to be able to expose and share certain projects with my friends, but I want to keep other projects private
  • Since version numbers are assigned globally in Subversion, changes in one project will create a gap in other projects if they are under the same repository
Hosting multiple Subversion repositories in windows can be accomplished using a single instance of svnserve running as a service if you set the root to a location that contains multiple repositories as subfolders.

C:\Repos
\Repository1
\Repository2
\Repositoryn

Given the above folder structure, if I run a test using svnserve as a daemon (command "svnserve -d -r C:\Repos") and all of the Repository# folders contain valid repository structures, each one will be served up as a unique repository on svn://localhost/Repository1, svn://localhost/Repository2, etc.

Installing Subversion 1.4.3 and TortoiseSVN

Getting Subversion running seems to be the best place to start; a good version control system is a cornerstone of any solid development and build environments. In addition to the server, I need to install and configure the client software and start moving my source code into the new repository.

I have used Subversion clients to access a few Open Source projects in the past, and played around with an early version of the subversion server. The clients were fairly easy to use, but the server was a pain to install and setup back then. I am hoping that this process has been smoothed out by now.

Here is what I want to tackle today:
  1. Install and configure Subversion to run as a windows service on my Win2000 server
  2. Install and configure TortoiseSVN on my workstation
I spent a few minutes feeding Google to find documentation for installing and running Subversion as a windows service and settled on the blog post Setting up a Subversion Server under Windows; its clean, concise and as a bonus it includes a section on setting up TortoiseSVN.

I downloaded the Subversion 1.4.3 binaries zip package, and spent a few minutes trying to find the SVNService component (the link in the instructions I am using is dead). Stupid me, I should have read the comments on that post and saved myself five minutes. The SVNService is now hosted at http://svnservice.tigris.org/; I'll be using the SVNServiceSetup 0.5.2 msi package (edit: change of plans... using svnserve instead of SVNService; read ahead.)

Following the instructions, it took me less time to install Subversion that it did to read the documents and download the files. Ten minutes, tops. Unfortunately, I seem to have put my foot in it with the SVNService. I can install and start the service, but cannot connect to it from a remote computer. I keep getting an error stating that the "connection was actively rejected." Additional research turned up that Subversion now includes an internal server, svnserve, that can run as a service. I pulled the rest of the information I needed from How to run Subversion 1.4.0 in Windows.

Interesting side note... apparently you can copy the sc.exe utility from a Windows XP installation and run it on Windows 2000 server. Take this with a BIG grain of salt. It worked for me, but I do not know if there are any side effects. If you need sc.exe, you should install the Windows 2000 Resource Kit.

TortoiseSVN installed without a problem, I am using version 1.4.3; the versions appear to be synced with the Subversion releases. The installation prompts you to reboot at the end, but it is not required to function. However, you will not see the icons on folders/files indicating they are a part of a subversion repository and their status until you reboot.

I am going to take a break to review the Subversion book and the TortioseSVN documentation before moving on.