Sample gitlab ci pipeline for elixir projects

September 11, 2018

One of the very thing I like to do when starting a project is having a CI pipeline running. It’s really worth to invest some time at the begining of the project and that will pay off in the future when more people join the project and you want to track history of changes or ensure that builds meet restrictions. I think gitlab is offering the best CI integration at the moment.


---
image: registry.gitlab.com/yourproject/ubuntu-erlang-elixir:0.0.1

stages:
  - build
  - test
  - docs
  - deploy-qa
  - deploy-prod
  - update-dev-env

build:
  stags: build
  cache:
    key: ${CI_JOB_NAME}
    paths:
      - deps
  before_script:
    - mix local.hex --force
    - mix local.rebar --force
    - MIX_ENV=test mix deps.get
  script:
    - MIX_ENV=test mix compile --force
    - MIX_ENV=prod mix release
  artifacts:
    name: '$CI_COMMIT_SHA'
    paths:
      - _build
      - deps
      - _build/prod/rel/your_project/
    expire_in: 30 days

test:
  stags: test
  services:
    - postgres:9.6.10
  variables:
    POSTGRES_HOST: postgres
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: 'postgres'
    MIX_ENV: 'test'
  dependencies:
    - build
  artifacts:
    paths:
      - cover/excoveralls.html
  before_script:
    - apt-get update && apt-get -y install postgresql-client
    - mix local.hex --force
    - mix local.rebar --force
    - mix ecto.setup
  script:
    - mix coveralls.html -u --exclude not_implemented

credo:
  stags: test
  variables:
    MIX_ENV: test
  allow_failure: false
  dependencies:
    - build
  before_script:
    - mix local.hex --force
    - mix local.rebar --force
  script:
    - mix credo list --strict

pages:
  stags: docs
  dependencies:
    - test
  script:
    - mkdir public
    - mv cover/excoveralls.html public/coverage.html
  artifacts:
    paths:
      - public
    expire_in: 30 days
  only:
    - master

deploy:qa:
  variables:
    DEPLOY_USER: ubuntu
    DEPLOY_SERVER: 'qa.yourproject-stage.local'
    DEPLOY_PATH: '/home/ubuntu/elixirapps/yourproject-releases'
  allow_failure: false
  stags: deploy-qa
  before_script:
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$NEW_QA_SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - make deploy
  environment:
    name: QA
    url: http://qa.yourprojectapp.com/
  dependencies:
    - build
  when: manual
  tags:
    - qa

deploy:prod:
  variables:
    DEPLOY_USER: ubuntu
    DEPLOY_SERVER: 'prod.yourproject-stage.local'
    DEPLOY_PATH: '/home/ubuntu/elixirapps/yourproject-releases'
  allow_failure: false
  stags: deploy-prod
  before_script:
    - eval $(ssh-agent -s)
    - echo "$PROD_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$PROD_SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - make deploy
  environment:
    name: Production
    url: http://app.yourprojectapp.com/
  dependencies:
    - build
  when: manual
  only:
    - master
  tags:
    - docker
    - prod

trigger_dev_build:
  stags: update-dev-env
  before_script:
    - apk update && apk add curl
  script:
    - 'curl -X POST -F token=$DEV_ENV_TOKEN -F ref=master -F "variables[EXTERNAL_TRIGGER_NAME]=yourproject" -F "variables[EXTERNAL_CI_JOB]=$CI_JOB_ID" https://gitlab.com/api/v4/projects/SOMEID/trigger/pipeline'
  only:
    - master


This gitlab congiguration was built by a friend of mine for a project we worked toghether. I modified the content a litle bit to make it more generic. You should modify urls and paths, so it’s pointing to your own project but other than that this should work really well.