Robot Has No Heart

Xavier Shay blogs here

A robot that does not have a heart

Maintaining a stable branch

Part one of my VCS ninja skills program.

A common scenario for a production application is to have a trunk for development, and a stable branch that is deployed to production. This is what we do at RedBubble, and here I share how to complete some common tasks with subversion.

Push out a new release

It might seem like a good idea to merge trunk into stable. Not so! Trunk is the code that you’ve been working with and testing with, merging it into another branch introduces the risk of either hard conflicts (not so bad – you can fix them) or the scarier Bodgy Merge (technical term) where subversion thinks it has merged everything correctly but hasn’t. We blow away our stable branch and just copy over trunk. Takes less time, and we’re more confident in the result. Here’s an example from our release notes:

1
2
svn delete -m "Removed previous stable branch" svn+ssh://example.com/home/svn/branches/stable
svn copy -m "Ice T Release - Iteration 2 : trunk to stable (r1234)" svn+ssh://example.com/home/svn/trunk svn+ssh://example.com/home/svn/branches/stable

We also tag the release in tags/ (just another copy), but to this day we have never checked out one of the tags, so maybe that isn’t worthwhile. You can always checkout a specific revision anyway.

Patch a bug fix into stable

Oh noes! Production is broken! Code Red! Hopefully you release often enough that trunk and stable are similar enough that you can apply the same patch to both of them. This is the case 99% of the time for us, so when something is broken we fix it in trunk, then merge the patch across to stable to release.

1
2
3
4
5
6
# trunk fix was r100
cd branches/stable
svn merge -r99:100 svn+ssh://example.com/home/svn/trunk .
svn st   # Always check!
svn diff # Always check!
svn ci -m "Merge r100 from trunk (my awesome bug fix)"

That’ll get it done, but we don’t want to be just competent. Ninjas aren’t just ‘competent’.

1
2
3
4
5
#!/usr/bin/env ruby
ARGV.collect {|x| x.to_i }.each do |revision|
  cmd = "svn merge -r#{revision-1}:#{revision} svn+ssh://example.com/home/svn/trunk ."
  puts `#{cmd}`
end

Put that in your bin folder – mine’s called rbm (RedBubble Merge – yay for obscure shortcuts) – and you can now patch with rbm 100 105. It’s so quick, there have been reports of patches getting merged before they’re even committed to trunk.

UPDATE: Multi-param version of rbm

SVN, Trac and NFS

Migrated my Subversion repository to my dev server, and am getting it served up through https with LDAP authentication. Going to set up pretty formatting this afternoon – not that I ever use the web interface.

Trac also relies on the webserver for authentication, so it too is running through https/LDAP. All very pretty. One thing that’s not immediately obvious about Trac (you know, if you don’t read the welcome screen) is that managing things like components and milestones is done using the trac-admin program, and not anything on the web interface (although there is a plugin available for this). Initial inspection looks like I’m going to be using it as a glorified TODO list, but hopefully it will improve my work ethic. The value of this program would increase exponentially with the number of developers, I feel.

1
2
3
4
5
6
7
8
9
<Location /svn>
        DAV svn
        SVNPath /var/svn/repos
        AuthType Basic
        AuthName "Subversion repository"
        AuthLDAPURL ldap://rhino:389/OU=People,DC=noreality,DC=net?uid?sub?(objectClass=account)
        Require valid-user
        SSLRequireSSL
</Location>

Improvements would be using require group insert-ldap-group rather than require valid-user, and to not allow anonymous binds to my LDAP tree. I don’t have groups setup yet though…

Also set up NFS on my server – I had been using SMB (still am for windows) even on my linux clients, but recent dapper updates have really thrown a spanner in those works. I need to comment out my SMB shares in fstab before I reboot or I’ll be waiting a loooong time for the system to come up again. Noted a neat trick on the gentoo wiki for specifying a fallback kernel when recompiling the kernel on a remote box. Thankfully I didn’t have to rely on it, but hooking up a keyboard/monitor to my server-behind-the-TV is not a task I want to have to do on a weekend.

A pretty flower Another pretty flower