Wolfmans Howlings

A programmers Blog about Ruby, Rails and a few other issues

a Capistrano scm module for local SVN access

Posted by Jim Morris Thu, 07 Dec 2006 05:42:00 GMT

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 ,  | Tags ,  | 26 comments | no trackbacks

Comments

  1. Sebastian said about 1 hour later:

    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 about 2 hours later:

    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 about 11 hours later:

    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 about 15 hours later:

    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 12 days later:

    Many thanks for putting this together - it finally makes Capistrano a viable deployment option for us. Works like a charm :)

  6. Jon Evans said about 1 month later:

    Thanks for this, most useful! It works perfectly. You directed me here from a message 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 about 1 month later:

    Great work, was just about to write something like this and then stumbled on yours.. Thanks..

  8. Jacob Atzen said about 1 month later:

    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 2 months later:

    Thanks for this great Capistrano module. Works great on my config.

  10. Chuck said 2 months later:

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

    Thanks!

  11. Chuck said 2 months later:

    p.s. Windows, eat me. MacBook's in the mail and I'm ready to move on in life.

  12. wolfmanjm said 2 months later:

    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 2 months later:

    Jim, this was exactly what I was looking for. They should make this a standard recipe for Capistrano

  14. wolfmanjm said 2 months later:

    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 2 months later:

    I uploaded a fixed version and tested the rsync version better

  16. James said 2 months later:

    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?

    J.

  17. wolfmanjm said 2 months later:

    Ok found the problem, and fixed it. Thanks

  18. James said 2 months later:

    Cheers wolfman!

    Link is generating an Application Error at present though:

    http://blog.wolfman.com/files/localsubversionwithrsync3

  19. wolfmanjm said 2 months later:

    OK the link is fixed - thanks, you should also read the updated blog entry.

  20. James said 2 months later:

    Nice one. Thanks wolfman.

  21. Hasham said 6 months later:
    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 6 months later:

    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 6 months later:

    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 6 months later:

    Now all we need is someone to port that solution to cap2.0 :)

  25. saurabh purnaye said about 1 year later:

    i m using a windows machine .. so can you pls guide me for the path to access a local repository

  26. wolfmanjm said about 1 year later:

    You should be using capistrano 2 which has this functionality built in. This article has been deprecated.

    See http://capify.org/

Trackbacks

Use the following link to trackback from your own site:
http://blog.wolfman.com/articles/trackback/91

(leave url/email »)

   Comment Markup Help Preview comment