Skip to content

Instantly share code, notes, and snippets.

@warmfusion
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save warmfusion/0c92d89b3a03ca1c031e to your computer and use it in GitHub Desktop.
Save warmfusion/0c92d89b3a03ca1c031e to your computer and use it in GitHub Desktop.
Creating Ruby packages through FPM - Multi-Module

This project builds GEMs into Debian packages for multiple versions of Ruby and deploys them into the appropriate repositories.

The packages created are suffixed with the rubyversion being built to assist in identifying dependencies.

For example

rubygem-fluentd_0.12.8-9~ruby1.9.3-p194_all.deb

Configuration

Each version of ruby must be configured in a config-VERSION.properties file which describes

  1. The exact ruby version to use (eg 1.9.3 can be 1.9.3-p551)
  2. The location the gem's will be installed into, eg /var/lib/gems/1.9.1
  3. The Apt Repositories that the generated debian files will be deployed to (An array)

Example

This configuration file, found here describes a ruby build environment for pre-jessie servers, where we install into the 1.9.1 directory, but actually compile for a 1.9.3 ruby version.

Configuration

RB_VER=1.9.3-p194 RB_PREFIX=/var/lib/gems/1.9.1

Array of repositories the package will be deployed

REPOS=(jenkins@example.com:wheezy
jenkins-ci@example.com:squeeze
jenkins-ci@example.com:lenny)

Jenkins Job

The Jenkins job that builds this uses a Matrix Job configuration, so we can simultaniously build mutiple gems against different dependencies automatically.

The configuration can be summarised as:

  1. A build parameter named 'PACKAGE' which is the package the user wishes to package up
  2. A VERSION axis containing a list of versions which correspond to the CONFIG files included in this repo
  3. a single shell execution of ./package.sh $VERSION
# Configuration
RB_VER=1.9.3-p194
RB_PREFIX=/var/lib/gems/1.9.1
# Array of repositories the package will be deployed
REPOS=(jenkins@target-repository.example.com:wheezy \
jenkins-ci@target-repository.example.com:squeeze \
jenkins-ci@target-repository.example.com:lenny)
#!/bin/bash -e
#
# Matrix-Friendly Gem to Deb builder
#
# Params:
#
# VERSION: Which version are we creating, and therefore
# which ${CONF} to load
#
#Use the incoming VERSION param, or the first argument if its not set
VERSION=${VERSION:-$1}
CONF=config-${VERSION}.properties
if [ -z $VERSION ]; then
echo 'No Ruby Version set, set VERSION or provide as first argument to this script'
echo ' Usage: ./package.sh 1.9.1'
exit 1
fi
if [ ! -f ${CONF} ]; then
echo "Unable to find configuration (${CONF}) - Check your arguments..."
exit 2
fi
echo "Reading configuration from ${CONF}"
source ${CONF}
if [ -z $RB_PREFIX -o -z $RB_VER -o -z $REPOS ]; then
echo "Both RB_PREFIX (${RB_PREFIX}), RB_VER(${RB_VER}), REPOS(${REPOS}) must be set in your configuration"
exit 3
fi
echo "Gems will be installed into: ${RB_PREFIX}"
echo "Setting ruby environment to ${RB_VER} using rbenv"
~/.rbenv/bin/rbenv local ${RB_VER}
ruby -v
echo '-------------------'
echo 'Initialising Bundle to create Gemfile'
/usr/local/bin/bundle init
echo "Adding dependency on $PACKAGE in Gemfile..."
echo "gem \"$PACKAGE\" " >> Gemfile
echo 'Retrieving dependencies via bundle'
/usr/local/bin/bundle install
/usr/local/bin/bundle package
# Debian_revision only allows alphanumeric,and +~. characters - so lets
# just take the numbers out of the RUBY_ENV param
RBNUM=${RB_VER//[!0-9]/}
ITERATION="${BUILD_NUMBER}~ruby${RBNUM}"
echo '-------------------'
echo 'Building debian packages from input gems'
find vendor/cache -name '*.gem' | xargs -rn1 fpm --prefix=${RB_PREFIX} -s gem -t deb \
--gem-bin-path '/usr/local/bin' -m "<admin@example.com>" --iteration "${ITERATION}"
echo 'Package build completed'
echo '-------------------'
echo 'Uploading to configured repositories'
for R in "${REPOS[@]}"
do
echo " Transferring to $R..."
/usr/bin/scp *.deb $R
done
echo 'Package deployment complete'
echo '-------------------'
echo ' It takes upto five minutes for your packages to be loaded into the repositories. '
echo ' You will then be able to install your new package using the following command: '
echo " apt-get update && apt-get install rubygem-${PACKAGE}"
echo '-------------------'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment