Skip to content

Instantly share code, notes, and snippets.

@joakimk
Last active March 18, 2026 16:24
Show Gist options
  • Select an option

  • Save joakimk/48ed80f1a7adb5f5ea27 to your computer and use it in GitHub Desktop.

Select an option

Save joakimk/48ed80f1a7adb5f5ea27 to your computer and use it in GitHub Desktop.
CircleCI elixir build example

This runs a build for a small elixir (phoenix) project in about 40 seconds by caching as much of the compiled files as possible.

We've been using this for months in multiple projects without any issues. Please ping be if there is any issues with this script and I'll update it.

It should be generic enough to work on any elixir app using mix.

If you have a elixir_buildpack.config, then enable that section in the build script to keep versions in sync!

2016-08-09: Updated to newer Erlang and Elixir and fixed curl command.

dependencies:
pre:
- script/ci/prepare.sh
cache_directories:
- ~/dependencies
- ~/.mix
- _build
- deps
test:
override:
- script/ci/tests.sh
#!/bin/bash
# NOTE: Keep in mind that this script does not verify the shasum of the downloads.
# NOTE: Don't forget to make this file executable or the build won't run
set -e
export ERLANG_VERSION="19.0"
export ELIXIR_VERSION="v1.3.2"
# If you have a elixir_buildpack.config, do this instead:
#export ERLANG_VERSION=$(cat elixir_buildpack.config | grep erlang_version | tr "=" " " | awk '{ print $2 }')
#export ELIXIR_VERSION=v$(cat elixir_buildpack.config | grep elixir_version | tr "=" " " | awk '{ print $2 }')
export INSTALL_PATH="$HOME/dependencies"
export ERLANG_PATH="$INSTALL_PATH/otp_src_$ERLANG_VERSION"
export ELIXIR_PATH="$INSTALL_PATH/elixir_$ELIXIR_VERSION"
mkdir -p $INSTALL_PATH
cd $INSTALL_PATH
# Install erlang
if [ ! -e $ERLANG_PATH/bin/erl ]; then
curl -L -O http://www.erlang.org/download/otp_src_$ERLANG_VERSION.tar.gz
tar xzf otp_src_$ERLANG_VERSION.tar.gz
cd $ERLANG_PATH
./configure --enable-smp-support \
--enable-m64-build \
--disable-native-libs \
--disable-sctp \
--enable-threads \
--enable-kernel-poll \
--disable-hipe \
--without-javac
make
# Symlink to make it easier to setup PATH to run tests
ln -sf $ERLANG_PATH $INSTALL_PATH/erlang
fi
# Install elixir
export PATH="$ERLANG_PATH/bin:$PATH"
if [ ! -e $ELIXIR_PATH/bin/elixir ]; then
git clone https://github.com/elixir-lang/elixir $ELIXIR_PATH
cd $ELIXIR_PATH
git checkout $ELIXIR_VERSION
make
# Symlink to make it easier to setup PATH to run tests
ln -sf $ELIXIR_PATH $INSTALL_PATH/elixir
fi
export PATH="$ERLANG_PATH/bin:$ELIXIR_PATH/bin:$PATH"
# Install package tools
if [ ! -e $HOME/.mix/rebar ]; then
yes Y | LC_ALL=en_GB.UTF-8 mix local.hex
yes Y | LC_ALL=en_GB.UTF-8 mix local.rebar
fi
# If you use Elm:
# 1) add the code below
# 2) run the Elm build like this " ~/dependencies/sysconfcpus/bin/sysconfcpus -n 2 node_modules/brunch/bin/brunch build"
# 3) your Elm builds will finish in seconds instead of minutes
#
# For more info see: https://github.com/elm-lang/elm-compiler/issues/1473#issuecomment-245704142
#if [ ! -d $INSTALL_PATH/sysconfcpus/bin ]; then
# git clone https://github.com/obmarg/libsysconfcpus.git
# cd libsysconfcpus
# ./configure --prefix=$INSTALL_PATH/sysconfcpus
# make && make install
# cd ..
#fi
# Fetch and compile dependencies and application code (and include testing tools)
export MIX_ENV="test"
cd $HOME/$CIRCLE_PROJECT_REPONAME
mix do deps.get, deps.compile, compile
#!/bin/bash
export MIX_ENV="test"
export PATH="$HOME/dependencies/erlang/bin:$HOME/dependencies/elixir/bin:$PATH"
mix test
@matteosister

Copy link
Copy Markdown

thanks for sharing! ❤️

@jc00ke

jc00ke commented Jan 28, 2016

Copy link
Copy Markdown

Might I suggest adding -L to the curl command? It took me a bit to figure out that it was redirecting.

Also, thank you so much for posting this!

@ubernil

ubernil commented Feb 12, 2016

Copy link
Copy Markdown

I had to change script/ci/prepare.sh to bash script/ci/prepare.sh, as I got bash: line 1: script/ci/prepare.sh: Permission denied Action failed: script/ci/prepare.sh
Also, -L to the curl command helped to solve gzip: stdin: not in gzip format

@ArturT

ArturT commented Feb 15, 2016

Copy link
Copy Markdown

@ubernil You probably forgot to set chmod executable on those sh files.

@jcortesg

jcortesg commented Feb 17, 2016

Copy link
Copy Markdown

@joakimk You need -L: curl -OL http://www.erlang.org/download/otp_src_$ERLANG_VERSION.tar.gz

@cdale77

cdale77 commented Mar 4, 2016

Copy link
Copy Markdown

Thanks! In case it helps others, this is what I did with erlang 18.2.1 and elixir 1.2.3:
-change the script names to circle-prepare.sh and circle-tests.sh and put them in the app root
-used the -L switch for curl
-my circle.yml calls the scripts thusly: - ./circle-prepare.sh

@thbar

thbar commented Apr 28, 2016

Copy link
Copy Markdown

Indeed --location seems required today. Thanks for your script!

@thbar

thbar commented Apr 30, 2016

Copy link
Copy Markdown

Changes required to get formatted test output on CircleCI can be found here.

The part below is what was a bit harder to find:

test:
  override:
    - script/ci/test.sh
    - mkdir -p $CIRCLE_TEST_REPORTS/exunit
    - cp _build/test/test-junit-report.xml $CIRCLE_TEST_REPORTS/exunit

@jc00ke

jc00ke commented May 17, 2016

Copy link
Copy Markdown

@thbar thanks!

@aerosol

aerosol commented Jul 6, 2016

Copy link
Copy Markdown

Hi @joakimk, isn't it recompiling Erlang every time you push a new branch?

@alexparker

alexparker commented Jul 8, 2016

Copy link
Copy Markdown

Seems the download is failing for me related to gzip format. I can run the curl locally just fine

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

100   184  100   184    0     0    539      0 --:--:-- --:--:-- --:--:--  1628

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

script/ci/prepare.sh returned exit code 2

Action failed: script/ci/prepare.sh

adding -L option to curl solved it. The location had a 301 redirect on it.

@joakimk

joakimk commented Aug 9, 2016

Copy link
Copy Markdown
Author

@aerosol I don't use branches very much, but that might be the case. How would you work around that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment