SVN: How to release software properly

Tuesday 21 November 2006

Many projects use SubVersion nowadays to store their project code. I do this also at work, and for my personal projects like CSE-Tool.

The question, however, is how to release your current code properly to the public. You probably don't want your users to check out your current development code. Either you want them to check out a certain version (release) or you want to present them with a download archive containing the code.

I'm going to show you how to release a simple PHP application from SubVersion as an archive file to my users. ~ The base layout of my svn repository is like this. I have directory named 'trunk' that always contains the most recent version of the software. This is the development branch, so to say. I also have a 'branches' and a 'tags' directory. If you don't have these, you'll need to create them now:

$ svn mkdir -m "Creating branches directory" svn://yourrepository/branches
Commited revision 123.
$ svn mkdir -m "Creating tags directory" svn://yourrepository/tags
Commited revision 124.

In this case my current development code, in the trunk of the svn repository is at revision 10. All files in the trunk are marked to be develoment quality. This means that I don't display version numbers, but simply show 'HEAD' to indicate you're working with a development quality product. Before I release this code to the public, I want to tweak a few things. Since this is not general development, I create a Release Branch. This release branch is basically a copy of the current code in the trunk. Changes to that branch are stored seperately from the development code, so I can easily tweak it to release quality.

Creating the release branch is really easy. Let's say I want to release version 1.1.0 of CSE-Tool. I just copy the code in subversion. Note that I don't download and store the code on my local machine. SubVersion is smart and duplicates the code on the server. This can save you valueable bandwidth, especially when you're working on a large project.

Well, create the Release Branch which is named, by convention, RB-1.1.0.

$ svn copy -m "Creating release branch 1.1.0" https://svn.sourceforge.net/svnroot/cse-tool/trunk https://svn.sourceforge.net/svnroot/cse-tool/branches/RB-1.1.0
Committed revision 11.

You can see at http://cse-tool.svn.sourceforge.net/viewvc/cse-tool/branches/ that the new release branch (RB-1.1.0) was created as a directory containing a copy of the current develoment code.

I can now do two things. Either I checkout a seperate working copy of the release branch or I change my current working copy (which is using the trunk) to use the release branch. Checking out is easy, but I'll show it first to you anyway. Next I'll show you how to switch your repository.

Just check out your code as you'd normally do, but make sure you specify the release branch. I've also specified to store this code in a directory named cse-tool-1.1.0 so I don't confuse it with the trunk code, which is stored in a directory named 'cse-tool'.

$ svn co https://svn.sourceforge.net/svnroot/cse-tool/branches/RB-1.0.0 cse-tool-1.1.0

I could also swich my current working copy to the release branch. This may be useful if your project is very huge and you don't want to download the whole thing again. Switching between a release branch and the trunk is usually more efficient because you only need to download the differences between the two.

$ svn switch https://svn.sourceforge.net/svnroot/cse-tool/branches/RB-1.0.0

Okay, now I can work on the release branch. Branding it with the right version number among other things. In your case it might be a good place to two SQL files to install or update a database you are using. You might want to update the changelog and other documentation.

When you commit changes, they will be applied to the release branch only, not not to the current development code.

When you're done you may switch back to the current development code:

$ svn switch https://svn.sourceforge.net/svnroot/cse-tool/trunk

The code in the release branch is now ready to be shipped out. We want to mark this code as being Relese 1.1.0. This is called tagging. A tag is nothing more than a copy of the repository on a give moment. Technically, a branch and tag are the same. However, the conventions I use dictate that you don't change the code in a tag because it represents a certain state of your code, in this case the state the code was in at the time of Release 1.1.0.

Now, to actually create a release tag, named REL-1.1.0, we use the same procedure as with the creation of the release branch. Just note the differences in the source and destination repositories.

$ svn copy -m "Tag release 1.1.0" https://svn.sourceforge.net/svnroot/cse-tool/branches/RB-1.1.0 https://svn.sourceforge.net/svnroot/cse-tool/tags/REL-1.1.0
Committed revision 13.

With the REL-1.1.0 tag we can create an archive that we can distribute to our users. Because we don't want to include svn metadata in our release we can't use checkout for this. SubVersion allows us to export our code, which is basically a check out, but without all the svn metadata. This is ideal to ship to our customers.

$ svn export https://svn.sourceforge.net/svnroot/cse-tool/tags/REL-1.1.0 cse-tool-1.1.0

Next I can tar up the cse-tool-1.1.0 directory and put the files on SourceForge. (Download them here :))

Did you enjoy this post? Your generosity is much appreciated.