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.
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?
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.
Too bad this won't work for windows users, since they can't use tar. Any clever ideas to work around this?
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.
Many thanks for putting this together - it finally makes Capistrano a viable deployment option for us. Works like a charm :)
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.
Great work, was just about to write something like this and then stumbled on yours.. Thanks..
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.
Thanks for this great Capistrano module. Works great on my config.
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!
p.s. Windows, eat me. MacBook's in the mail and I'm ready to move on in life.
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.
Jim, this was exactly what I was looking for. They should make this a standard recipe for Capistrano
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
I uploaded a fixed version and tested the rsync version better
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.
Ok found the problem, and fixed it. Thanks
Cheers wolfman!
Link is generating an Application Error at present though:
http://blog.wolfman.com/files/local_subversion_with_rsync_3
OK the link is fixed - thanks, you should also read the updated blog entry.
Nice one. Thanks wolfman.
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 ....
No this method is deprecated in cap 2 as cap 2 includes a way to do this. see the cap 2 docs.
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 :-)
Now all we need is someone to port that solution to cap2.0 :)
i m using a windows machine .. so can you pls guide me for the path to access a local repository
You should be using capistrano 2 which has this functionality built in. This article has been deprecated.
See http://capify.org/