SVN: A Deployment Strategy

February 06, 2011
Tags: SVN

Recently I was required to take over the hosting of our SVN server and had the opportunity to take the existing system, which was a good base, and rebuild some parts of the it to meet some of our evolving business needs. I spent a lot of time reading about all the features of SVN and other version control systems as well as testing and redesigning it until I found the right balance of structure and security. I hope that what I learned as a result will help you as a web developer know what you can do with your repository and hopefully take some of the strain out of managing your environment. I do know there are a lot of other versioning systems out there and I'm not going to go into which you should use over another here. If that's what you're looking for you can read up here in an article written by Smashing Magazine. It's also worth noting that different programming languages have far different paradigms for code structure and this article may completely miss the point for you. I'm working in a .NET Web Application environment so bear that in mind.

The Settings Window

If you have SVN installed, right-click anywhere and go to TortoiseSVN->Settings.

Settings

This will pop open a dialog window that will be your main point of contact for customizing your SVN environment. There are a few sections that you really should know about.

Context Menu

The context menu controls the svn tools available to you when you right-click. You can add additional actions alongside TortoiseSVN for quicker access so that you don't have to go into the submenu for them. This is especially convenient since the actions on a server environment will differ from the actions needed on a development environment. To customize this, inside the settings dialog window, in the left column you'll see the "General" section. If you click on "Context Menu" you'll see checkboxes next to a list of actions. For a development environment I commonly use "Checkout", "Update", "Commit" and "Repo-browser", but on a server I usually need "Repo-browser" and "Switch".

Context Menu

Saved Data

Another useful section is "Saved Data". When you're developing you may have login credentials to several online open source repositories or even work on a shared development server and you may end up needing to wipe the stored login credentials and this is where you'd do it. If you select "Saved Data" you'll see several types of stored information that you can wipe from the machine, but in this case "Authentication data" is what you're looking for.

 Saved Data

Hook Scripts

The last section I'll highlight is the "Hook Scripts" section. Hooks are a powerful feature of SVN that allows you to automatically run code on specific events. Specifically you can tie actions to pre and post commits and pre and post updates. I don't plan on getting into the specifics of how to write hooks because that topic is far to broad to cover in this article but you can get started with the SVN Redbean or how to send a build email. Some other examples of tasks you might want to run are building the code, creating releases, sending emails, updating a search index or calling to activate a continuous integration server which subsequently contains many of the previous tasks.

Hooks

Add Hook

The Properties Window

If you're in a folder that has a checked out copy an SVN folder you can view the properties specific on that folder by right-clicking and going to TortoiseSVN->Properties.

Properties

Properties Window

There are a lot of different properties you can add but I'm only going to focus on one which is commonly used: Externals. Occasionally you'll have a repository structure that stores information logically but isn't useful to checkout in it's entirety. In my case I needed to create a view of the tree that limited users from seeing several source libraries and only allowed them to develop within the existing platform. The solution is to create a folder that combines only what folders are needed by adding "External" references to those other folders. What you'll end up with is a folder that when checked-out will save time downloading, allow you to restrict their permissions and ultimately allow you to customize how users interact with your repository. In the settings window if you click on the "New" button you'll be able to select the type "svn:external" from the drop down field and then add the property values.

Add Property

Each line will be a separate entry and the basic format is "location" space "Display Name". In my case I used "^/trunk/Platform Platform". I was pulling a platform folder from trunk and when checked out it would be named "Platform". There is a syntax associated with external paths so that you can reference locations based on absolute, relative or even third party locations. You can read more in depth on it at SVN Redbean.

SVN Tree Structure

When I first started releasing code to the server we had a wwwroot folder in SVN with each project folder below it. We were just committing all the files to a single project folder and then updating that folder on the server. That's essentially the source control low road. We also never needed the system to be overly complex since I would often be the sole developer on a project and I wasn't worried about code collisions. Most clients also didn't have any complex requirements about the process of releasing code. Not all environments though, are that simple and if you've ever pushed code that you needed to roll back you'd suddenly be wishing you had a more complex system.

Let's start by discussing the root level. By default SVN will tell you to setup your repository with a base set of folders: Branches, Tags and Trunk. It's really up to you to figure out what you need or don't need, but you'll want to consider adding Releases to the list. I also am not entirely comfortable with the name "Tags". It doesn't evoke the same the understanding that the creators must have envisioned. For me I call this folder "Views" since it's really where I build unique views of the tree for others to checkout, but naming is arbitrary so call it whatever makes sense for you.

 SVN Tree

Trunk

This is where you're root application will live and it should be considered the last place you should be committing code. This is your stable product. One thing you'll want to consider is that when it comes time to release the code to your server, you're only going to want to release the minimum amount of code. There's no reason the spend a lifetime checking out all of your library code when it's really only relevant on a development box that can compile it. That said, I prefer to separate the relevant code and settings for my web application into a folder called "Platform" and all class library projects into a folder called "Libraries". If you work with a multi-site installation of Sitecore you'll also want to consider adding a "Sites" folder to separate your site code from your platform so that you can update the platform independent from each sites and vice-versa. Under Platform I create a folder called "Environment-Settings". I do this because each server environment has a different set of connection strings, url redirects, web.config files and application project files. Again if you're working with a Sitecore installation you'll want to have a separate folder for "Data" and "Website", otherwise just a "Website" folder. In the Website folder you will have all of your web application. This kind of structure will require you to piece together the project on your server but once you've set that up it won't take up any more of your attention. One important thing to note is that the web.config file is not commited inside the Website folder and this is entirely intentional. I have seen a server brought down more times becuase a developer has commited his web.config with his local settings in and updated the server with them. There may be better approaches to this problem but I have found that forcing you to update the web.config by hand requieres you to pay much closer attention to what you're doing and be careful where simply updating a site does not.

Branches

Branching in SVN is a paradigm. Copying is the action that creates branches, but branches are what is understood to mean a copy of a folder that is intended to be merged back with the original folder when changes are completed. In the branches folder consider creating a folder called Development. Use this folder to branch/copy the "Libraries", "Platform" and "Sites" folder so that you can check this out and do your development work on it here. If you work with other teams consider creating a folder for each team or a View(Tag) where you can branch/copy from. This will give everyone a personal sandbox and will allow them to work along independent timelines of each other. This kind of setup will also require you to be familiar with merging. Using SVN's merge tool will allow you to bring changes back from other branches and test it on your platform before you commit it, giving you a line of defense against a platform failure.

Views (Tags)

Although I already mentioned Views in the previous sections I will expand more about setting this up. If you are going to be creating branches for developers that limit their access to certain libraries you'll not want to do this manually each time. You'll want to create a View that represents the mixed parts using branch copies and externals and then branch the view. This will save you time and get back some of your already busy day.

Releases

When it comes time to send code to the server you really don't want to just check out the Platform or Sites folders in trunk. The reason for creating releases along with being able to track the history of a product is to easily roll back code. You might have code that, despite your attempt to keep a solid build, broke. You may end up having a client that has a business requirement that would need you to take a new feature down shortly after release. Whatever the reason this is a fairly easy way to manage those situations. So in your trunk you've been committing several new features that you've thoroughly vetted and you're now thinking that the platform is ready to be updated. In your releases folder you'll want to create a folder for your Platform and if you're working like me a Sites folder. Under the Sites folder you'll have a separate folder for each of your sites. In this example you're going to want to copy your /trunk/Platform folder to /releases/Platform and name it with some sort of convention. A date or version number would be recommended. Now when you go to checkout the code you'll be checking out the Platform release and once it is checked out, when you want to update to a newer release you'll simply use the "Switch" action and specify the newer release. The "Switch" action will not checkout the new copy but only update the changes between the two releases. This really only works since each release is based off a common ancestor and can quickly run through the history of changes from one revision to another.

To recap, if you're using SVN to deploy your websites and need to develop a more complex strategy to solve your business needs, there is quite a bit more SVN can do. It's important to know what's at your disposal for tools. If you understand the basics of how to work with SVN, then you'll be able to develop a good strategy by customizing your environment with the proper settings, properties and repository structure. Hopefully this will help you when you're at that point and you're trying to figure out what kind of strategy will best fit your needs by seeing how other systems have been developed to meet theirs.