diff --git a/.gitignore b/.gitignore
index b8c66e9e4b833ce08fa4034f61fd12f1eb8c301f..affa0e2113eec71529a70e8b66f0758362871c3d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
-.eunit
-.rebar
-ebin
-deps
-*.o
-*.beam
-*.plt
+_build
+rebar3
+rebar.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7c0bb9c2169466eb146655f91e23bac100c4e787
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,26 @@
+before_script:
+  - banner "Environment"
+  - env | sort
+  - docker info
+  - git config --global url.https://.insteadOf git://
+  - mkdir -p ~/.hex ~/.config/rebar3
+  - printf "{key,<<\"$HEX_KEY\">>}.\n{username,<<\"$HEX_USERNAME\">>}.\n" > ~/.hex/hex.config
+  - printf "{plugins, [rebar3_hex]}.\n" > ~/.config/rebar3/rebar.config
+  - if [ "$HTTP_PROXY" != "" ]; then printf "{http_proxy,\"$HTTP_PROXY\"}.\n" >> ~/.config/rebar3/rebar.config; fi
+  - if [ "$HTTPS_PROXY" != "" ]; then printf "{https_proxy,\"$HTTPS_PROXY\"}.\n" >> ~/.config/rebar3/rebar.config; fi
+
+stages:
+  - build
+  - test
+
+build:
+  stage: build
+  script:
+    - banner "Build"
+    - make compile
+
+test:
+  stage: test
+  script:
+    - banner "Test"
+    - make test
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e0d657129d947ce9710bc78c6e508fc9bad438bd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,34 @@
+REBAR ?= $(CURDIR)/rebar3
+REBAR_URL ?= https://s3.amazonaws.com/rebar3/rebar3
+define get_rebar
+	curl -s -L -o $(REBAR) $(REBAR_URL) || rm $(REBAR)
+	chmod +x $(REBAR)
+endef
+export REBAR
+
+all: test
+
+$(REBAR):
+	@$(call get_rebar)
+	@$(REBAR) update
+
+compile: $(REBAR)
+	@$(REBAR) compile
+
+test: compile
+	@$(REBAR) as test do eunit --cover --dir=test, cover --verbose
+
+release: $(REBAR)
+	@$(REBAR) release
+
+docs: $(REBAR)
+	@$(REBAR) edoc
+
+clean: $(REBAR)
+	@$(REBAR) clean
+
+distclean:
+	@rm -rf _build rebar.lock $(REBAR)
+
+dialyzer: $(REBAR)
+	@$(REBAR) as dialyze do dialyzer
diff --git a/circle.yml b/circle.yml
deleted file mode 100644
index d799502b6d9298a66ca13f16a4df5438e7187638..0000000000000000000000000000000000000000
--- a/circle.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-machine:
-  environment:
-    PATH: ${HOME}/extras/bin:${HOME}/extras/otp/17.5/bin:${PATH}
-    TZ: Europe/Stockholm
-
-general:
-  branches:
-    ignore:
-      - gh-pages
-  artifacts:
-    - .eunit/*.html
-
-dependencies:
-  cache_directories:
-    - ~/extras
-  pre:
-    - curl -L https://raw.githubusercontent.com/ehedenst/circleci/master/kerl.sh | sh
-    - if [ ! -d ~/extras/otp/17.5 ]; then kerl build 17.5 17.5; kerl install 17.5 ~/extras/otp/17.5; fi
-  override:
-    - ./rebar get-deps
-
-test:
-  override:
-    - ./rebar compile eunit
-  post:
-    - mv .eunit/*.xml $CIRCLE_TEST_REPORTS
diff --git a/rebar b/rebar
deleted file mode 100755
index 8978e55ff2a2853d7aabb298d411e63ccd7e9835..0000000000000000000000000000000000000000
Binary files a/rebar and /dev/null differ
diff --git a/rebar.config b/rebar.config
index 727a0b01239d86d951513a8451835e4d8729ef7e..95012f93a1139db65b401a031628f08f7378d8a7 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,3 +1,25 @@
-{erl_opts, [debug_info, {d, debug}]}.
-{eunit_opts, [{report, {eunit_surefire, [{dir, ".eunit"}]}}]}.
-{cover_enabled, true}.
\ No newline at end of file
+{relx, [
+    {release, {gurka, semver}, [gurka]},
+    {dev_mode, true},
+    {include_erts, false},
+    {extended_start_script, true}
+]}.
+
+{profiles, [
+    {test, [
+        {eunit_opts, [{report, {eunit_surefire, [{dir, "_build/test"}]}}]},
+        {erl_opts, [debug_info, nowarn_unused_vars]}
+    ]},
+    {dialyze, [
+        {dialyzer, [{warnings, [unknown]}]},
+        {erl_opts, [debug_info]}
+    ]},
+    {prod, [
+        {relx, [
+            {dev_mode, false},
+            {include_erts, true}
+        ]},
+        {erl_opts, [no_debug_info, warnings_as_errors]}
+    ]}
+]}.
+
diff --git a/src/gurka.app.src b/src/gurka.app.src
index 28577a8fb70cedec559c72807e5aff0ce18c1d93..d6d2fb78635cf734e3e0ff0167bdf4cf00c54aeb 100644
--- a/src/gurka.app.src
+++ b/src/gurka.app.src
@@ -1,7 +1,7 @@
 {application, gurka,
     [
         {description, "Erlang implementation of Cucumber"},
-        {vsn, "0.3.0"},
+        {vsn, semver},
         {applications, [
             kernel,
             stdlib
diff --git a/test/features.erl b/test/features.erl
index 96ee999d58976f0bea296bd3a455832e388d8ae0..a435509ca28ea116f34766084b4a7e947f80973c 100644
--- a/test/features.erl
+++ b/test/features.erl
@@ -4,7 +4,6 @@
 
 gurka_test_() ->
     Features = fun() ->
-        file:set_cwd(".."),
         filelib:fold_files("features", ".*[.]feature", true, fun(File, Files) -> [File | Files] end, [])
     end,
     gurka_eunit:setup(Features).