Chad WoolleyChad Woolley
Automating Bundler In Your Deploy
edit Posted by Chad Woolley on Thursday March 25, 2010 at 05:09PM

If you are using Bundler to lock and package your gem dependencies in your app (which you should), here's some tips on making everything automatic in your Capistrano deploy.

Refer to the Bundler Documentation for instructions on how to use Bundler to properly package your gems and check everything in.

Once this is done, however, you still must ensure that two things are done on every machine to which you will deploy:

  1. Bundler is installed
  2. You run 'bundle install' on every deploy to install the packaged gems on the local machine (and compile any gems with native dependencies)

Here's the Capistrano magic to accomplish these two tasks automatically on every deploy:

before "deploy:bundle_install", "deploy:install_bundler"
after "deploy:update_code", "deploy:bundle_install"

namespace :deploy do
  desc "installs Bundler if it is not already installed"
  task :install_bundler, :roles => :app do
    sudo "sh -c 'if [ -z `which bundle` ]; then echo Installing Bundler; sudo gem install bundler; fi'"
  end

  desc "run 'bundle install' to install Bundler's packaged gems for the current deploy"
  task :bundle_install, :roles => :app do
    run "cd #{release_path} && bundle install"
  end
end

Oh, and for you GemInstaller users out there - here's an easy way to generate a Bundler Gemfile from your geminstaller.yml config:

geminstaller --bundler-export > Gemfile

You'll probably still need some tweaks, but this will get you started. Just make sure you upgrade to GemInstaller 0.5.5 first (0.5.4 forgot to put the 'source' line in the Gemfile).

Happy Bundling! -- Chad

P.S. There is a similar article here, which includes tasks to symlink your .bundle dir into the Capistrano shared directory, but my deploy was pretty fast anyway, so I didn't worry about it. YMMV.

Corey InnisCorey Innis
Bundle(r) Yourself... and Get Ready to Cruise!
edit Posted by Corey Innis on Tuesday November 17, 2009 at 07:00PM

On a current project, we've just switched from GemInstaller to Bundler for managing our application's gems.

All in all, the transition was painless... in our development environments. Of course, in order to keep things on running smoothly on the continuous integration box, we amended our rake cruise:spec task to start by running sh "gem bundle".

So, wonderful! Any changes to our gem dependency list will picked up when cruise starts and made available for that "build"; there's no need to log in and make any manual updates. Right?

Not quite. We're using the disable_system_gems option and, in that case, Bundler (very intentionally) modifies your GEM_PATH such that only "vendor'd" gems are available to the application. Which of course means that Bundler itself, being "a gem to bundle gems", is unavailable when that sh "gem bundle" command is run.

Our solution: bundle Bundler, obviously! That's right, in our Bundler Gemfile we've included gem "bundler". Now, after a single manual execution of gem bundle to pick up the bundled Gem Bundler gem bundle (heh), any subsequent Gemfile changes (to gems other than Bundler) get picked up at the start of the build... and we're cruisin'

Have another solution? Please let us know in the comments.

Chad WoolleyChad Woolley
[ANN] GemInstaller 0.5.3 Released
edit Posted by Chad Woolley on Tuesday August 25, 2009 at 11:25PM

This fixes several bugs that people have complained about for quite a while. Please let me know if anything is broken.


GemInstaller 0.5.3 has been released!

GemInstaller

CHANGES

  • 0.5.3 / 2009-08-25
  • Many long overdue bugfixes and patches, see http://tinyurl.com/geminstaller-0-5-3-release for details.
  • Thanks to Greg Fitzgerald, Britt Crawford, John Trupiano, Gabriel Gironda, and Eric Hodel for patches and assistance.
  • Issues with case statement under Ruby 1.9
  • GemInstaller cannot distinguish between gems that have the ame name but capitalized differently.
  • add ./ci as default location for config file
  • Disable GemInstaller install in default rails preinitializer.rb, but fork if it is used
  • autogem() fails when run for newly-installed gem
  • Sometimes installing fails due to RubyGems cache not being cleared between multiple API calls

DESCRIPTION

Automated Gem installation, activation, and much more!

FEATURES

GemInstaller provides automated installation, loading and activation of RubyGems. It uses a simple YAML config file to:

  • Automatically install the correct versions of all required gems wherever your app runs.
  • Automatically ensure installed gems and versions are consistent across multiple applications, machines, platforms, and environments
  • Automatically activate correct versions of gems on the ruby load path when your app runs ('require_gem'/'gem')
  • Automatically reinstall missing dependency gems (built in to RubyGems > 1.0)
  • Automatically detect correct platform to install for multi-platform gems (built in to RubyGems > 1.0)
  • Print YAML for "rogue gems" which are not specified in the current config, to easily bootstrap your config file, or find gems that were manually installed without GemInstaller.
  • Allow for common configs to be reused across projects or environments by supporting multiple config files, including common config file snippets, and defaults with overrides.
  • Allow for dynamic selection of gems, versions, and platforms to be used based on environment vars or any other logic.
  • Avoid the "works on demo, breaks on production" syndrome
  • Find lost socks.

Quick Start

See http://geminstaller.rubyforge.org/documentation/index.html

INSTALL

  • [sudo] gem install geminstaller