Circle CI configuration with yesod (haskell) backend and javascript frontend
For “Daj się poznać” contest I’ve decided to make a tool which is close to pinboard and pinterest, but with features I was missing. When I’ve chosen frameworks which I’ll gonna use, and both of them came with some default tests, I’ve decided to setup continuous integration using CircleCI. This post describes how to setup CircleCI for repository with two apps inside (so automatic CircleCI language recognition doesn’t work) and one of them is haskell, which is not very popular and there aren’t too much resources how to do it.
Javascript frontend
That part was easy. Asuumption is that your javascript application is located in frontend
directory and the tests are run by running npm run test
command.
To run our tests, we needed only one simple command in circle.yml
:
If we want npm run test
command to work, we need firstly to install our dependencies, which is done by this part of circle.yml
config:
This should already work, however we don’t want to wait each time to install all node dependencies, but rather we’d like to cache them between builds. This can be achieved by following code:
Haskell backend
That part is more tricky.
In the beginning I’ve tried to achieve this by running cabal install
and cabal test
commands on test container, however I had some problems with installing all necessary dependencies. As on my development machine I am using stack to manage dependencies (and more), I was curious that maybe it would be easier to install this tool which is on a higher level than cabal, but probably more straightforward to run.
I’ve found that someone already tried to do this but it looks that without success. Using part of this repository I’ve managed to install stack on CircleCI without any difficulties:
As you can see, I’ve also added ~/.stack
directory to cache haskell packages.
Then, similarly like in javascript frontend, we want to install dependencies:
That is the part when things went a little bit weird. Initially, I was using only stack build
, but it looks that stack didn’t compile test dependencies. stack build --test
on the other hand, was building test dependencies, but it was instantly running all the tests. That’s why I end up using stack build --test --only-dependencies
command.
In the end, we want to run the tests:
After that change, it almost works.
Yesod ignoreEnv vs useEnv
When you firstly use yesod, it has config/settings.yml
file which keeps information about database:
You can probably guess that these _env:PGUSER
strings are there to allow developer to replace this values by using environment variables. For test environment there’s different file, config/test-settings.yml
in which you can override some values from config/settings.yml
. So, if you want to replace this values for test container, but you also want to have some reasonable default for your development machine, you can end up with following contents of config/test-settings.yml
file:
Then it should work, right? Nope. At least not in automatically generated version by stack yesod website. By default, for some reason, env variables in config/test-settings.yml
file don’t work. You have to change one argument in test/TestImport.hs
file. By default it’s
and you should change it to
You can also check relevant commmit in Symmetrical Chainsaw project.
Final config
Finally I’ve end up with following circle.yml
:
After this, my setup of continuous integration was ready to defend me from my mistakes.