My first novel is avalable for pre-order!

Read Singular
 ~2 minutes

Setting up CircleCI for an Elixir/Phoenix Project

In case this might be useful to someone else, here is how I setup a Phoenix project to work with Circle CI.

This gives you continuous integration with proper parsing of test results.

Step 1: Phoenix Default Git Ignores

Change the .gitignore to have this for the App artifacts section:

# App artifacts

Then add a .gitkeep file into the following directories:

  • _build
  • _build/test
  • priv/repo/migrations

Step 2: Parseable Test Output

Since Elixir isn’t properly supported, we have to generate XML into a standardized format so CircleCI can parse it and give us our red/green.

Add the following dependency to mix.exs:

defp deps do
   {:junit_formatter, ">= 0.0.0"},

Since I still like the default formatter, we tell it to use both in test/test_helper.exs:

ExUnit.configure formatters: [JUnitFormatter, ExUnit.CLIFormatter]

And specify some config options in config/test.exs:

config :junit_formatter,
  report_file: "results.xml",
  print_report_file: true

Step 3: Circle.yml

Copy all of this into your circle.yml file:

    version: 6.2.0
    PATH: "$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
    MIX_ENV: "test"

    - ~/.asdf
    - _build
    - deps
    - if ! asdf | grep version; then git clone ~/.asdf; fi
    - if ! asdf plugin-list | grep erlang; then asdf plugin-add erlang; fi
    - if ! asdf plugin-list | grep elixir; then asdf plugin-add elixir; fi
    - echo "erlang ref:OTP-19.0.2" >> .tool-versions
    - echo "elixir 1.3.2" >> .tool-versions
    - erlang_version=$(awk '/erlang/ { print $2 }' .tool-versions) && asdf install erlang ${erlang_version}
    - elixir_version=$(awk '/elixir/ { print $2 }' .tool-versions) && asdf install elixir ${elixir_version}
    - yes | mix deps.get
    - yes | mix local.rebar

    - mix test
    - mkdir -p $CIRCLE_TEST_REPORTS/exunit
    - cp _build/test/lib/APPNAME/results.xml $CIRCLE_TEST_REPORTS/exunit

Note: you have to change APPNAME above to match your actual app’s name.


This works for now (takes almost four minutes to run on Circle, takes a couple seconds locally), but I’m going to guess that it’ll break before long. The first time you run this, it will take fifteen minutes or more to build Erlang and all the rest.

If you want to update this for a newer Elixir/Erlang, make sure you check what the Erlang version is actually called in asdf-erlang as non-released but tagged versions have a particular naming scheme.

I’m indebted to the folks on this thread who had earlier versions of Elixir/Erlang working.

Tagged with: programming