SVN: How to release software properly

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 :))

  • Twitter
  • Digg
  • del.icio.us
  • DZone
  • Reddit
  • email

18 Responses to “SVN: How to release software properly”

  1. [...] To see how I manage a the creation of a release through SubVersion, check this post over here. Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]

  2. ariejan says:

    There’ll be more Subversion tutorials soon. Feel free to contact me to place a request :)

  3. [...] iG:Syntax Hiliter This plugin allows me to easily post different kinds of code like Ruby, PHP and C#. It will show the code properly formatted, syntax highlighting is included and it will allow you to copy it all as plain text! Want a demonstration? [...]

  4. [...] I’ve already told you about releasing your project with help from Subversion. Now I want to talk to you about using Subversion to fix bugs in your application. [...]

  5. [...] Ruby On Rails for PHP: CakePHPSVN: How to release software properlyUbuntu 6.10 Live DVD on the Apple MacBookGoogle Project Hosting: SourceForge Competitor [...]

  6. Hi I also took down a few notes and thoughts on svn patching

  7. Kingsley says:

    The version above works for applications where you extract a bunch of source files and create them from scratch such as a Java App or a C++ app.

    What about for database development where the changes are iterative. I have 4000 procedures but only want to update say 2 or 3.

    Im stuggling to mkake subversion extract just the files i have changed. I still want to retain the history of those files as i cant be sure when i will be releasing cases(Containing objects).

    Does anyone have experience in this area?

    Am i looking at this the wrong way?

    Or is this just the wrong tool for the job? (Its been forced on me by company policy)

  8. @Kingsley: if you look at Ruby on Rails, there is also database development involved. The Rails way is to store your changes in separate, numbered files. This way you can define what “version” of your database model you’re currently running.

    Read http://api.rubyonrails.org/classes/ActiveRecord/Migration.html for more details about Rails migrations. It may give you some great ideas to solve your own issue.

  9. Kingsley says:

    The ruby on rails framework looks great and may solve another issue we are looking at but doesnt help me with version control.

    The upgrade scripts would be massive and it would take many hours to run in just a couple of new objects. When all i want from my config management tool is for it to understand which files are in a release and to only extract those files.

    I run a 8 terrabyte database with 50000+ objects. To use this method and go through each table and look at the versions would be crazy. We dont run several different versions of the DB only 1 so the ruby approach would not be much help.

    I would have thought it would be a simple SVN issue to only package the files that are needed for the release rather than the entire branch???

    I thank you for your help…

    9-5 Frustrated :-)

  10. Gaurav Mantri says:

    Thanks. As I am new to SVN, this article really helped me understand branching & tagging. We are developing a solution using Visual Studio.Net. Here is what I want to accomplish:

    We want developers to work off of “trunk”. When they are ready to release the software for testing, they would use the “branch” and create a new branch. However we want the testers to only get binaries & not the source code. How do you recommend we do this? Should we create a branch and the developers do a SVN update of the code in the branch and then make a new build and release that build to the testers?

    Please let me know.

    Thanks

  11. @Gaurav: As a ruby developer I’m not really used to compiling stuff ;-) But I see your point.

    The best way to handle this, in my opinion, is to create a script that can compile binaries from a given branch. The developer should invoke the script when he signs over the branch to the testing department.

    You could probably do something nifty with post-commit hooks, which could build the binary automatically after a commit.

  12. Gaurav Mantri says:

    Thanks. I think this is the best way out. I will also try to find something more and update my comments here.

  13. userbarna says:

    Hello from Spain.

    Thank you for this post, it is very useful.
    I once read about that the difference between a stable branch and non-stable branches was in numbers, let’s try to apply this to your example. Please correct me if I’m wrong, I’m here to learn. :)

    In your example 1.1.0 would be a non-stable version. If we consider that it’s allright after adding some code and we want to make a stable branch (and a tag as well?) we would change it to: 1.2.0 (changing from an odd number to an even number).

    Thank you for your post.
    Regards from Spain.

  14. @userbarna The odd/even numbering is a possibility. The Linux kernel users such a numbering. E.g. Kernel 2.6.x is stable, while 2.7.x is unstable and will later turn in 2.8.x.The reason for this is to make it clear to users what version are considered stable and which are not. Labeling a release ‘alpha’ or ‘beta’ will also indicate its quality.

  15. Martin says:

    Hello,
    I found this post while I was looking for a simple solution for the following problem:

    Assume many designers are working on one project and everyone checks in his latest changes to the trunk. So the trunk will not be stable. To build a stable release some some parts have to be taken from earlier revisions.

    So I could write a mail to all developers an ask them to copy their last stable version to the release branch.
    Then I have t wait till everyone answers that he is finished, and pray that everyone has copied all files needed.

    Is there a script available which can automate this.

    The idea is to have a PHP generated view where each user sees all his files with the latest version. It should be possible to select earlier file revisions and the php script then should copy the marked revisions onto the revision branch.
    A logfile should hold the info who has committed which file revisions to the branch.

    I come from ASIC design and we have a CVS based standalone tool for that, but I would like to move to SVN and get rid of the standalone solution.

    I plan to code this in php but first I want to check if something similar is available.

    Perhaps someone who reads this has a solution.

    regards
    Martin

  16. @Martin: Well, you cannot commit new changes, unless you have the most current code yourself.

    This means that if developer A commit new things, developer B needs to update his work with the changes from developer A before he can commit his own changes.

    I’m not sure you’re working with developers, but you should have automated test. As soon as developer B merges his code with that of A, all tests should still be working. If not, don’t commit it!

  17. Martin says:

    hi Ariejan,

    In our case designers are responsible for their module tests and the release is what goes to the toplevel tests.

    It could happen that a designer has already implemented and tested a feature where he knows that it will cause problems in toplevel so he wants to put an earlier version of his module in the release.

    Whole toplevel regression might run for a week.

Leave a Reply