In our team we are very happy users of RubyMine, by JetBrains. Now JetBrains also has a continuous integration server, called TeamCity, and it is also capable to run rails rake tasks.

Installing TeamCity is close to a non-operation, as described on their website. Just download the package, extract, and run bin/runAll.sh start. Then you can browse to http://localhost:8111 and you are up and running.

Unfortunately, getting the build to actually run was a bit more complicated in our case.

Our prerequisets:

  • we do not check in any configuration file (like config.yml, database.yml, ...) so each developer can have their own settings.
  • we use bundler to manage our gem dependencies

We use the rake runner, but as you might know: rake tasks will not run unless the bundle is up to date. Luckily we are not the first to encounter that problem, and the suggested solution is actually quite simple, although a bit backward: use a custom rakefile, that will first run the bundle install, then require the actual Rakefile from which you can run the tasks.

To create the log folder, the css files (we use sass), the config-files, i had to create specific rake-tasks.

We also had a problem that our database was always somehow corrupt. Upon thorough investigation, i was able to pin-point this on the rake db:test:prepare task, that actually does not load the database from the schema.rb, but tries to clone the development database! On our continous integration server there is no development database!

So i cleared the db:test:prepare task.

Our custom rakefile then looked as follows:

directory "log"

task 'copy_rakefile' do
  cp 'Rakefile', 't_rakefile.rb', {:verbose => true}
end

task :bundle_install do
  sh 'bundle install'
end

task :sass do
  Sass::Plugin.update_stylesheets
end

task :default => [:bundle_install, 'copy_rakefile', 'log'] do
  RAILS_ENV = ENV['RAILS_ENV'] = 'test'
  
  require File.dirname(__FILE__) + '/t_rakefile'

  # launch rake tasks from the original Rakefile
  Rake::Task["log:clear"].invoke
  Rake::Task["teamcity:init_config"].invoke

  Rake::Task['db:test:prepare'].clear
  Rake::Task["db:reset"].invoke

  Rake::Task["environment"].invoke
  Rake::Task['sass'].invoke
  Rake::Task["test"].invoke
  Rake::Task["spec"].invoke
  Rake::Task["cucumber"].invoke
end

We had to copy the Rakefile, so we could later require it as a straight ruby-file.

Note that to disable the db:test:prepare i used the following code:

  Rake::Task['db:test:prepare'].clear

Simple, isn’t it :)
It’s also only cleared when running the teamcity:build, just as we want it.

Now we got this working, it is time to enjoy the goodies TeamCity offers us, like spreading over different build agents.