Using cruisecontrol.rb with repositories without anonymous access
by Doug on Feb.02, 2008, under Agile, Ruby
I decided to use cruisecontrol.rb for continuous integration of an application that I’m working on at Bezurk. So I downloaded the 1.2.1 release from RubyForge and proceeded to add the project repository to the local installation of cruisecontrol.rb.
douglas@macbookpro:~$ ./cruise add MyProject --url http://path.to/repository --username 'douglas' --password 'guessable' douglas@macbookpro:~$ ./cruise build MyProject Builder for project 'MyProject' started Logging to: /Users/douglas/Development/Ruby/cruisecontrolrb-1.2.1/log/MyProject_builder.log Build loop failed BuilderError: svn: PROPFIND request failed on '/svn/my_project/trunk' ./script/../config/../app/models/subversion.rb:98:in `execute_in_local_copy' ./script/../config/../lib/command_line.rb:86:in `call' ./script/../config/../lib/command_line.rb:86:in `e' ./script/../config/../lib/command_line.rb:84:in `popen' ./script/../config/../lib/command_line.rb:84:in `e' ./script/../config/../lib/command_line.rb:71:in `execute' ./script/../config/../lib/command_line.rb:70:in `chdir' ./script/../config/../lib/command_line.rb:70:in `execute' ./script/../config/../app/models/subversion.rb:89:in `execute_in_local_copy' ./script/../config/../app/models/subversion.rb:85:in `chdir' ./script/../config/../app/models/subversion.rb:85:in `execute_in_local_copy' ./script/../config/../app/models/subversion.rb:44:in `latest_revision' ./script/../config/../app/models/project.rb:228:in `new_revisions' ./script/../config/../app/models/change_in_source_control_trigger.rb:8:in `revisions_to_build' ./script/../config/../vendor/rails/actionpack/lib/../../activesupport/lib/active_support/core_ext/symbol.rb:10:in `__send__' ./script/../config/../vendor/rails/actionpack/lib/../../activesupport/lib/active_support/core_ext/symbol.rb:10:in `to_proc' ./script/../config/../app/models/project.rb:223:in `collect' ./script/../config/../app/models/project.rb:223:in `revisions_to_build' ./script/../config/../app/models/project.rb:202:in `build_if_necessary' ./script/../config/../app/models/polling_scheduler.rb:13:in `run' ./script/builder:79 ./script/builder:78:in `catch' ./script/builder:78 ./cruise:14:in `load' ./cruise:14:in `builder' ./cruise:68:in `send' ./cruise:68 /opt/local/lib/ruby/1.8/fileutils.rb:121:in `chdir' /opt/local/lib/ruby/1.8/fileutils.rb:121:in `cd' ./cruise:67
Hmm, what’s with the svn: PROPFIND error? Looking at the stracktrace doesn’t tell me alot about what’s going wrong here, let’s try logging errors to the console.
--SNIP-- douglas$ svn --non-interactive info --xml douglas$ svn --non-interactive log --revision HEAD:20 --verbose --xml svn: PROPFIND request failed on '/repository/trunk' svn: PROPFIND of '/repository/trunk': authorization failed (http://svnhost.com) --SNIP--
It happens that my repository does not have anonymous access and requires a subversion user account to do anything useful. So it should be obvious that cruisecontrol.rb is trying to get log info from the repository but subversion is quitting with authentication errors because no user credentials are being supplied.
I need to have cruisecontrol.rb make use of the –username and –password options when making queries to the repository when I give it the credentials for access.
My first stop is the app/models/subversion.rb. Only the checkout method uses the username and password instance variables. Subversion should only include the –username and –password options when executing svn commands when both the username and password instance variables are present.
[ruby]
test/unit/subversion_test.rb
def test_svn_command_uses_user_password_when_provided
svn = Subversion.new(:username => 'jer', :password => "crap")
svn.expects(:info).with(dummy_project).returns(Subversion::Info.new(10, 10))
svn.expects(:execute).with(["svn", "--non-interactive", "log", "--revision", "HEAD:10", "--verbose", "--xml",
"--username", "jer", "--password", "crap"],
{:stderr => './svn.err'}).yields(StringIO.new(LOG_ENTRY))
svn.latest_revision(dummy_project)
end
app/models/subversion.rb
def checkout(target_directory, revision = nil, stdout = $stdout)
@url or raise 'URL not specified'
options = [@url, target_directory]
options < < "--revision" << revision_number(revision) if revision
# need to read from command output, because otherwise tests break
execute(svn('co', options)) do |io|
begin
while line = io.gets
stdout.puts line
end
rescue EOFError
end
end
end
def svn(operation, *options)
command = ["svn"]
command << "--non-interactive" unless @interactive
command << operation
command += options.compact.flatten
command += ['--username', @username, '--password', @password] if @username and @password
command
end
[/ruby]
The username and password would then be injected into the project's Subversion instance in the cruise_config.rb file for each project.
[ruby]
Project.configure do |project|
project.source_control.username = 'douglas'
project.source_control.password = 'guessable'
end
[/ruby]
I’ve submitted a ticket along with a patch for this on cruisecontrol.rb’s tracker. Keep a lookout for it if you happen to encounter the same problem.
February 12th, 2008 on 8:59 am
A quick question – are you developing on Leopard? If so, I believe you’re running into a subversion bug. You can read more about it here:
http://www.opensubscriber.com/message/users@subversion.tigris.org/8197745.html
http://subversion.tigris.org/issues/show_bug.cgi?id=3059
February 24th, 2008 on 11:11 am
Yes Grant, as a matter of fact I am developing on Leopard. So going by the bug report, it doesn’t seem like Apple is going to change the way the keychain works on Leopard.
September 24th, 2009 on 1:05 am
I just tried installing cruisecontrol.rb (cruisecontrol-1.4.0) on a Mac Mini and discovered the same issue described by Doug. Doug solution works fine, however, the subversion.rb file is now located in /lib/source_control/subversion.rb