Tuesday, March 18, 2014

Extract the Version of Bundler, Chef, Ruby, etc. for CI

RVM and rbenv can use the .ruby-version file to define the Ruby version to use for your application. What about extracting the versions for Bundler and Chef?

If your application doesn't need to know anything about Chef, but you want your CI build/tests for that application to use your Chef bootstrapping process to set up your VM, maybe in your Chef repo where you keep your recipes, etc., your Chef Gemfile might look like:

chef_version = File.read(
  File.join(
    File.dirname(__FILE__),
      '.chef-version')).strip

gem 'chef', chef_version

And, let's say that you have a Chef bootstrap script that needs to install Bundler prior to doing bundle install:

gem install bundler --version=`cat .bundler-version`
bundle install

Now put the Chef version in .chef-version and the Bundler version in .bundler-version, e.g. if a version is 1.2.3, then the file would only contain:

1.2.3

Your application's repo just has .ruby-version and the rest of the application, but after you clone it and change to that directory in CI, you could do the following to grab and use those new version files from the Chef git repo. More about git archive here:

rbenv install `cat .ruby-version` || true
rbenv local
git archive --format=tar \
  --remote=your_chef_git_repo_uri \
  HEAD: .chef-version .bundler-version \
  | tar -x
gem install bundler --version=`cat .bundler-version`
gem install chef --version=`cat .chef-version`

That installs ruby if it isn't there (need || true so won't fail if already installed), uses it, just gets .chef-version and .bundler-version from another git repo, and then installs bundler, then chef, and you are ready to start bootstrapping. If you are using RVM like I do in development (this is the long version- you might not need all of this):

if test -f ~/.rvm/scripts/rvm; then
    [ "$(type -t rvm)" = "function" ] \
       || source ~/.rvm/scripts/rvm
fi
rvm get stable
rvm install `cat .ruby-version` || true
# if using gemset, specify that too, and --create
rvm use `cat .ruby-version`
git archive --format=tar \
  --remote=your_chef_git_repo_uri \
  HEAD: .chef-version .bundler-version \
  | tar -x
gem install bundler --version=`cat .bundler-version`
gem install chef --version=`cat .chef-version`

It is a bit dirty. Docker may be a better choice now for getting setup quickly, but if you use chef and other shell scripts, etc., then extracting version numbers might help.

No comments: