Continuous Integration for Phoenix Apps on CircleCI
I just recently got turned on to Elixir and Phoenix. I decided to play around and write a small, silly app that would function as a sort of bot for my company’s Slack team. There are a handful of specs, and I wanted to be able use Continuous Integration to run those specs for me.
I tried using Travis CI first with their instructions for running Elixir projects. I left it with the default settings which uses Elixir 1.0.2 and Erlang/OTP 17.4. It failed because my project needed Elixir >= 1.1.0, namely because it uses Enum.random/1
. My Travis build
Then I tried to install Erlang/OTP 18 and Elixir 1.1.1 on Travis CI, but it just timed out. Timed out build.
So, I gave up on Travis CI and decided to try CircleCI instead. I based my circle.yml
file on instructions from Kevin Disneur and goneflyin. Neither of their instructions worked 100% for me, but in combining the two, I was able to get my specs to run on CircleCI!
This configuration uses asdf a multi-language version manager.
To set the Erlang/OTP and Elixir versions, just add a .tool-versions
file at the root of your project. My file looks like this:
erlang 18.0
elixir 1.1.1
Once you have that file, all you need is a circle.yml
file to tell CircleCI what to do.
My circle.yml
file
machine:
environment:
PATH: "$HOME/.asdf/bin:$HOME/.asdf/shims:$PATH"
dependencies:
cache_directories:
- ~/.asdf
pre:
- if ! asdf | grep version; then git clone https://github.com/HashNuke/asdf.git ~/.asdf; fi
- asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git
- asdf plugin-add elixir https://github.com/HashNuke/asdf-elixir.git
- 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
- mix local.rebar
test:
override:
- mix test
The first run will take significantly longer than subsequent runs as the Erlang/OTP and Elixir installations are not yet cached. My first run took around 9 minutes, whereas my second run took a little over 2 minutes.