I finally set up a continuous deployment (CD) server for Ducky Guidance. I decided to use Jenkins since we already have a Windows Jenkins server for our Sitecore projects.
Setting up the project
Since we use RVM for our development and production enviroments, I
installed RVM for the Jenkins user. Then I set Jenkins to use
/bin/bash for shell commands. I created a
.bashrc file to load RVM.
With that, I was ready to create the build step for our project.
The build task
source ~/.bashrc # Loads RVM cd . # Loads the RVM environment set in the .rvmrc file cp ~/duckyg-database.yml config/database.yml # Copies the database.yml locally bundle install # Installs gems rake db:schema:load # Loads all the database schema rake # Runs RSpec and Cucumber
I use the
source ~/.bashrc line to load RVM for the build task. After
that, I use
cd . to load the Ruby version and gemset we use for Ducky
Since I made sure to not store our
database.yml in our git repository,
I created one in the Jenkins user home folder. I copy it from the
Jenkins user's home directory with every build.
rake db:schema:load and the
bundle install commands ensure that
all the migrations are loaded and all the gems are installed. From
there, we can call
rake, which will call RSpec and Cucumber.
RSpec & Cucumber HTML Formatted output
RSpec and Cucumber both have HTML results formatters. Since Jenkins will serve up HTML output, I thought it would be useful to have both tools output their results to an HTML file in the workspace. That way, I can quickly scan the full color, formatted HTML instead of digging through the console output. To accomplish this, I have to call RSpec and Cucumber separately, so that I can redirect their outputs to separate files.
It was easy to tell Cucumber to use the HTML formatter, as Cucumber
looks at the
CUCUMBER_FORMAT environment variable. I added the
following line to my build task:
CUCUMBER_FORMAT=html rake cucumber > jenkins/cucumber.html
RSpec looks at the
SPEC_OPTS environment variable, so you can call
RSPEC in a similar way with the following line:
SPEC_OPTS="--format html" rake rspec > jenkins/rspec.html
My build task now looks slightly different than it did when I first set up the project:
source ~/.bashrc cd . cp ~/duckyg-database.yml config/database.yml [ -d jenkins ] && rm -rf jenkins mkdir jenkins bundle install > jenkins/bundler.txt rake db:schema:load > jenkins/schema_load.txt SPEC_OPTS="--format html" rake rspec > jenkins/rspec.html CUCUMBER_FORMAT=html rake cucumber > jenkins/cucumber.html
As you can see, I decided to redirect the
rake db:schema:load and
commands to files as well. I stored all the files in a
in the workspace group the output of the various commands called in my
build tasks. I also added a link to the
jenkins folder in the
workspace to my job description, so that I can easily get to the output
files when I view the job.
So far, I have Ducky Guidance set up as a Continuous Integration project. It is testing the project with every new commit, but it is not deploying it. The next step was to add another build task which would call Capistrano after all the RSpec and Cucumber tests passed. The contents of that build task are below:
source ~/.bashrc cd . cap development deploy:migrations > jenkins/deploy.txt curl https://demo.duckyg.com --insecure > /dev/null
curl to warm up the app after it is deployed, so the first person to
visit the site is no longer penalized with longer load times.
Before using Jenkins for deploys, I was invoking capistrano locally. I
was utilizing SSH Agent Forwarding for authenticating code fetches on
our staging and production servers. So when I used the above build task
initally, it was erroring out when git would fetch the code. It seems
that the way that Jenkins invokes shell commands prevents
.ssh/config settings. To solve the problem, I created
an SSH key on my deployment targets. Now capistrano uses the private key
on the staging and production servers to authenticate git commands.
It wasn't too hard to fit Jenkins into my workflow. There were a couple of hiccups (like explicitly loading RVM, and placing SSH keys on our staging and production servers), but no show stoppers.