Sunday, April 19, 2015

How to use Figaro with Travis CI

Although I knew that including my Facebook app_id and app_secret on the omniauth.rb file is a security risk but I went ahead because I could reset it anytime I wanted. However the correct way of handling the sensitive API keys or database credentials is by never committing them to version control. Also the 3rd commandment of a 12 factor app is to store them in environment variables!

I decided to use figaro and got up and running fast. You should follow their tutorial in the Github page. After I ran the figaro install command I added the configuration values to the application.yml. My application.yml file looked something like below (but of course with the correct credentials). Note that setting the values in "quotes" is important as otherwise you'd get errors when trying to set the keys in heroku.

app_id: "342342342343"
app_secret: "1233866op343435212389267622c123b"

production:
  app_id: "342342342343"

  app_secret: "4563866ba3434352b4569988222c466a"

Then the next task was to set the production credentials in heroku. That was easily done with 

figaro heroku:set -e production

Ran the specs (All green!), committed and pushed to Github. After that it was smooth sailing for me! Or was it ?

Travis CI sent an email immediately complaining that the build was broken. I checked and all my specs were broken and to see why, it was because I added the following line in application.rb


Figaro.require_keys("app_id", "app_secret")

So the environment variables were not set in Travis and it wouldn't run any of the specs. Figaro would throw the following error if the required keys are missing.

Missing required configuration keys: ["app_id", "app_secret"] (Figaro::MissingKeys)

So how to set the environment variables? Turns out Travis CI provides a gem that can encrypt the environment variables and add them to travis.yml, and they will be set before running specs.

After I installed the 'travis' gem it, I used the travis encrypt command to get encrypted values.

travis encrypt FOO=bar

You can use the -a option to automatically add it to the travis.yml as well.

After the values were added to the travis.yml file, it looks as shown below. Note that the the encrypted "secure" variable includes BOTH the environment variable name and value.

language: ruby
rvm:
  - "2.2.1"
# uncomment this line if your project needs to run something other than `rake`:
script:
  - RAILS_ENV=test bundle exec rake db:migrate --trace
  - bundle exec rspec spec/
env:
  global:
    - secure: "VERY LONG ENCRYPTED KEY VALUE ENV VAR"
    - secure: "ANOTHER VERY LONG ENCRYPTED ENV VAR"

I committed this file and pushed to Github and then Travis could the find environment variables and build successfully. The result was green like a cuke!