Using postgression on Travis CI
May 12, 2013
At Heroku we use Travis CI to run project tests on push to GitHub. While Travis CI offers PostgreSQL in their environment, it’s version 9.1. A project I’m working on recently started using PostgreSQL 9.2’s JSON data type, which 9.1 does not have.
Needing 9.2, I searched for ways to make it available in the Travis CI environment. I found guides that suggested upgrading PostgreSQL in a before_script
but I didn’t have much luck with that approach. Plus, it would add time to each build which I was hoping to avoid. I knew Heroku Postgres offered 9.2 by default, what I really wanted was a fresh Heroku Postgres database for every test run.
Then I remembered postgression.
postgression is a service from rdegges and zaidos, built atop Heroku Postgres. It has a very simple API:
$ curl http://api.postgression.com
postgres://user:password@host/db
The returned URL points to a Heroku Postgres database (running 9.2) which is automatically destroyed in 30 minutes, making it perfect for a Travis CI run.
My project connects to the database specified by $DATABASE_URL
, so I needed to get that set to the URL returned by postgression. Before I started using the JSON data type, I used the env
section of .travis.yml
to set $DATABASE_URL
to postgres://localhost/ci
and created the ci
database in the before_script
section. This worked well as settings in the env
section are made available to all parts of the build: before_script
, script
, etc. To use a postgression database for $DATABASE_URL
, I wanted the equivalent of:
export DATABASE_URL=$(curl http://api.postgression.com)
The env
section documentation has a note about needing to quote settings with asterisks (*
) which got me wondering if specified settings were being evaluated by a shell. As an experiment, I changed my env
section to:
env:
- DATABASE_URL=$(curl http://api.postgression.com)
and it worked! The build output also confirmed this happened just once for the build instead of, say, once for before_script
and again for script
. This meant I had access to the same database in all parts of the build.
For a complete example in the wild, check out the .travis.yml
for dikdik, an erlang hstore interface. Since dikdik also requires PostgreSQL 9.2, tsloughter adopted the approach described here to test it with Travis CI.
Thanks to a union of these two great services, testing projects requiring PostgreSQL 9.2 is easy. Please support them if you find them valuable!