How to setup CI to run Phoenix projects

Writing tests is an important step in software development and everyone knows the benefits. In our last post, we took a look on how to write acceptance tests in Phoenix and today we will see how to configure CI to run the tests.

Install Erlang and Elixir

We use Jenkins to run ours builds and Ansible to setup the agents. The following code are snippets from the tasks used for machine provisioning. Our agents are using Ubuntu, but you can check the Elixir Install section to follow the steps for another OS.

Step 1: Add the Erlang Solutions repository:

First, we need to add the Erlang Solution repo and its GPG key before updating the repo. With this step we can find the Erlang and Elixir packages.

- name: Add Erlang Solutions repository
  apt_repository: >
    repo='deb {{ansible_distribution_release}} contrib'

- name: Add the GPG key for Erlang Solutions
    url: "{{ ansible_distribution | lower }}/erlang_solutions.asc"
    state: present

Step 2: Install Erlang and Elixir packages.

We are using the latest version of Elixir but if you need to manage it you can take a look at a manager like kiex or asdf.

- name: Install Erlang
  apt: pkg=esl-erlang state=latest

- name: Install Elixir
  apt: pkg=elixir state=latest

Step 3: Install Hex and Rebar.

If you are new to Elixir/Erlang, you probably don’t know about these tools. Hex is the package manager for the Erlang ecosystem and you can learn more at

Rebar is an Erlang build tool, and it’s necessary to build the dependency poolboy. The task mix local.rebar will install both rebar and rebar3. You can check the Mix.Tasks.Local.Rebar documentation to install one of them if you need.

- name: Install Elixir Hex
  command: mix local.hex --force

- name: Install Rebar
  command: mix local.rebar

Running your tests

We use Janky, along with Jenkins, which can execute a custom build configuration into script/cibuild that is stored at the root of the repository. Our Phoenix projects use the following script:

#!/bin/bash -ex

source /etc/profile

export POSTGRESQL_USER="test"

mix ecto.reset
mix deps.get
mix test

Exporting ENV variables

Our project is using Postgres and it isn’t a good practice to store the credentials in the version control. So, we export the credential to environment variables and get it in config/test.exs:

config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: System.get_env("POSTGRESQL_USER") || "postgres",
  password: System.get_env("POSTGRESQL_PASSWORD") || "postgres",
  database: "my_app_test",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox,
  port: System.get_env("POSTGRESQL_PORT") || 5432

You can read more about this practice at Twelve-Factor App.

Reset your database

Usually, each builder is responsible for provision in a new machine. Instead of this, we setup a machine that will run several builds from different projects while there is activity. Therefore, we need to reset the database to avoid side-effects with different schemas.

The task mix test will run the tasks ecto.create and ecto.migrate (you can check it in test/test_helper.exs). We could use mix ecto.destroy instead of mix ecto.reset, but we prefer to use the latter to be more explicit.

Install dependencies and run the tests

Now, mix deps.get and mix test will install the project dependencies and run your tests.

Which tips do you have to install or use in CI to run Phoenix tests?

Subscribe to Elixir Radar

Comments are closed.