Wolfmans Howlings

A programmers Blog about Programming solutions and a few other issues

a Capistrano scm module for local SVN access

Posted by Jim Morris on Wed Dec 06 21:42:05 -0800 2006

UPDATE 2007-06-09 This method has been deprecated in Cap 2.0.

UPDATE 2007-02-21 I have updated the files to correctly update revisions.log

UPDATE I added rsync as suggested see end of article for more info.

I previously published a custom deploy recipe that allowed subversion to checkout from a local repository and send to the remote server.

This was a suboptimal solution, as it wouldn't work with things like deprec.

So here is the way I should have done it in the first place. It is a modified version of the standard subversion scm module, it should be backward compatible with the built in version, but adds a couple of features.

  • Handles the subversion repository only being accessible from the local machine
  • If the subversion repository is accessible from the remote server allows for different URLs for access from the local and remote machines.

If you use a standard deploy.rb and your subversion is accessible from the server, then it should work exactly as the built-in version (no need to use it then, but it should work)

However if you have your subversion server behind your local firewall, you just add these three lines to your deploy.rb

require 'lib/tasks/local_subversion_rsync.rb'
set :scm, Capistrano::SCM::LocalSubversionRsync
set :repository_is_not_reachable_from_remote, true

And everything will work as before, even though the server has no idea what subversion is.

Of course for this to work you need to download this de-tar it and put it in your lib/tasks directory. (That's where the require line gets this extension from). There is also a unit test for the new_subversion module which is extended from the one shipped with Capistrano, which passes.

Everything else in deploy.rb should be the same as before, except that you set the repository to the URL your local machine uses to access your locally accessible subversion server or repository. (Should even work with the URL file://...), for instance...

set :repository, "svn://your.svnserver.host/#{application}/trunk"

The assumption is that both the local and remote machines can create files and directories in /tmp, if this is not true then one or both of these should be set...

set :tmpdir_local, "/usr/tmp"
set :tmpdir_remote, "/home/user/tmp"

The way this module works is to export the relevant version of the project from Subversion into a temporary directory on the local machine (default is /tmp/unique_name). Then I create a gzip'd tar archive into the temp directory. The tar file is then transferred to the target servers, using the Capistrano put command into a temporary directory (/tmp by default) on the server. I then create the target directory on the server and un-tar the file into that directory. Then clean up the various temporary files. From the perspective of the server the end result should be identical to doing an svn export into the target directory on the server.

The other facility this SCM Module provides is when your subversion server is accessible from the server as is the "normal" use case (per the Capistrano developers, but bad practice IMHO), but you need a different URL to access the SVN repository from the local machine vs the remote server, eg

server accesses with this URL svn://localhost/myapp/trunk local machine accesses with this URL svn+ssh://myserver.com/myapp/trunk

in this case you add these lines...

require 'lib/tasks/local_subversion_rsync.rb'
set :scm, Capistrano::SCM::LocalSubversionRsync

set :local_repository_path, "svn+ssh://myserver.com/myapp/trunk"
set :repository, "svn://localhost/myapp/trunk"

In addition if the actual SVN binary is different on server and local you can add these for instance...

set :remote_svn, "/usr/local/bin/svn"
set :local_svn, "/usr/bin/svn"

If the relevant configuration variable is not set then the standard svn configuration variable is used, and then just "svn" if that is not set.

Please beware I have not fully tested the use cases other than the first one, where I use my local subversion server to deploy to my remote servers that know nothing about subversion, however the unit tests do pass for the other use cases.

UPDATE 2007-02-15 check this article for using the rsync option.

Posted in Rails,Ruby  |  Tags capistrano,subversion  |  26 comments


  1. Sebastian said on Wed Dec 06 23:08:37 -0800 2006
    Cool. I was looking for something like this... I'll give it a try.

    One Question: How are the files transfered to the server in your solution?
  2. wolfmanjm said on Wed Dec 06 23:52:09 -0800 2006
    I tar and gzip the directory then copy that tar file over using capistrano's put (which uses scp basically), then on the server I untar into the target directory. I'll add some explanation to the post, thanks for asking.
  3. Arjen said on Thu Dec 07 09:09:40 -0800 2006
    Too bad this won't work for windows users, since they can't use tar. Any clever ideas to work around this?
  4. wolfmanjm said on Thu Dec 07 12:12:35 -0800 2006
    Arjen- Yes just replace the tar calls with zip and unzip, and it should work fine on Windows. You also have to make sure the tmp directories are set up properly as /tmp probably doesn't exist on windows either. Alternatively just install a win32 tar binary, there are a few around.
  5. Christophe said on Tue Dec 19 03:53:01 -0800 2006
    Many thanks for putting this together - it finally makes Capistrano a viable deployment option for us. Works like a charm :)
  6. Jon Evans said on Mon Jan 08 09:30:58 -0800 2007
    Thanks for this, most useful! It works perfectly. You directed me here from [a message](http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/c817c4dba7d84521) on the RoR mailing list but although I replied to that using Google Groups a good 6 hours ago it still hasn't shown up on the list.
  7. Si said on Tue Jan 09 07:39:03 -0800 2007
    Great work, was just about to write something like this and then stumbled on yours.. Thanks..
  8. Jacob Atzen said on Tue Jan 09 13:36:29 -0800 2007
    Looks nice. A small improvement would be to have a "checkout" on the server which would be updated with rsync on each deployment. This checkout would then be copied into the releases directory. Just like the svn_cache from caboose. This would minimize deployment time and bandwidth usage.
  9. Maxime Curioni said on Thu Feb 08 12:41:24 -0800 2007
    Thanks for this great Capistrano module. Works great on my config.
  10. Chuck said on Thu Feb 15 00:52:54 -0800 2007
    Works like a charm so far! Exactely what I needed. I should check if the local/remote repo options have been rolled into the new Capistrano release (since this is a few days old now).

  11. Chuck said on Thu Feb 15 00:53:32 -0800 2007
    p.s. Windows, eat me. MacBook's in the mail and I'm ready to move on in life.
  12. wolfmanjm said on Thu Feb 15 12:19:02 -0800 2007
    none of these changes have been added to the cap release, as Jamis is working on a new architecture that will deprecate the need for this module.
  13. Steve said on Thu Feb 15 12:47:48 -0800 2007
    Jim, this was exactly what I was looking for. They should make this a standard recipe for Capistrano
  14. wolfmanjm said on Thu Feb 15 14:40:51 -0800 2007
    As suggested I have uploaded a new version that can use rsync instead of put to get the new version to the servers, I have updated the end of this article with the instructions. However I still use the put version so someone needs to test out this new rsync version. Thanks
  15. wolfmanjm said on Thu Feb 15 22:23:00 -0800 2007
    I uploaded a fixed version and tested the rsync version better
  16. James said on Wed Feb 21 07:01:01 -0800 2007
    Very nice - works fine for me... apart from one thing :)

    revisions.log is no longer populated with the release details. Any chance you could add support for this?

  17. wolfmanjm said on Wed Feb 21 13:12:00 -0800 2007
    Ok found the problem, and fixed it. Thanks
  18. James said on Thu Feb 22 04:34:52 -0800 2007
    Cheers wolfman!

    Link is generating an Application Error at present though:

  19. wolfmanjm said on Thu Feb 22 11:31:34 -0800 2007
    OK the link is fixed - thanks, you should also read the updated blog entry.
  20. James said on Fri Feb 23 05:52:15 -0800 2007
    Nice one. Thanks wolfman.
  21. Hasham said on Fri Jun 08 03:53:55 -0700 2007
    Does this works with Capistrano 2. I am getting this error:

      /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- capistrano/scm/base (LoadError)
              from ....
  22. wolfmanjm said on Fri Jun 08 09:40:03 -0700 2007
    No this method is deprecated in cap 2 as cap 2 includes a way to do this. see the cap 2 docs.
  23. Jacob Atzen said on Sat Jun 09 14:12:36 -0700 2007
    I guess I never did get to say thank you for the rsync stuff. So here it is: Thanks a lot! The rsync deployment is really great :-)
  24. wolfmanjm said on Sat Jun 09 15:31:21 -0700 2007
    Now all we need is someone to port that solution to cap2.0 :)
  25. saurabh purnaye said on Mon Jan 07 23:42:29 -0800 2008
    i m using a windows machine .. so can you pls guide me for the path to access a local repository
  26. wolfmanjm said on Tue Jan 08 13:03:35 -0800 2008
    You should be using capistrano 2 which has this functionality built in. This article has been deprecated.

    See http://capify.org/

(leave email »)