diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7c0bb9c2169466eb146655f91e23bac100c4e787..d14adc393f61339cdb69fa07f1667f7d0087abae 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,19 +8,29 @@ before_script:
   - 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
+  - curl -jksSL -o rebar3 https://s3.amazonaws.com/rebar3/rebar3 && chmod +x rebar3
 
-stages:
-  - build
-  - test
+job:
 
-build:
-  stage: build
-  script:
-    - banner "Build"
-    - make compile
+  stages:
+    - compile
+    - test
+    - publish
 
-test:
-  stage: test
-  script:
-    - banner "Test"
-    - make test
+  compile:
+    stage: compile
+    script:
+      - rebar3 as production do compile
+
+  test:
+    stage: test
+    script:
+      - rebar3 do eunit --cover --dir=test, cover --verbose
+
+  publish:
+    stage: publish
+    only:
+      - /^\d+[.]\d+[.]\d+$/ # Only publish HEAD tagged with semantic version
+    script:
+      - rebar3 update
+      - echo Y | rebar3 hex publish
diff --git a/Makefile b/Makefile
index e0d657129d947ce9710bc78c6e508fc9bad438bd..c1c4f229e3e9071c153268bc00a9b94cb205c06a 100644
--- a/Makefile
+++ b/Makefile
@@ -15,8 +15,11 @@ $(REBAR):
 compile: $(REBAR)
 	@$(REBAR) compile
 
-test: compile
-	@$(REBAR) as test do eunit --cover --dir=test, cover --verbose
+test: $(REBAR)
+	@$(REBAR) do eunit --cover --dir=test, cover --verbose
+
+analyze: $(REBAR)
+	@$(REBAR) dialyzer
 
 release: $(REBAR)
 	@$(REBAR) release
@@ -29,6 +32,3 @@ clean: $(REBAR)
 
 distclean:
 	@rm -rf _build rebar.lock $(REBAR)
-
-dialyzer: $(REBAR)
-	@$(REBAR) as dialyze do dialyzer
diff --git a/rebar.config b/rebar.config
index 95012f93a1139db65b401a031628f08f7378d8a7..8d42c8a06c75e0f08fb86ab6a8306f6bccae391c 100644
--- a/rebar.config
+++ b/rebar.config
@@ -10,11 +10,7 @@
         {eunit_opts, [{report, {eunit_surefire, [{dir, "_build/test"}]}}]},
         {erl_opts, [debug_info, nowarn_unused_vars]}
     ]},
-    {dialyze, [
-        {dialyzer, [{warnings, [unknown]}]},
-        {erl_opts, [debug_info]}
-    ]},
-    {prod, [
+    {production, [
         {relx, [
             {dev_mode, false},
             {include_erts, true}
diff --git a/src/gurka.app.src b/src/gurka.app.src
index 2278f57b83208d5c1f736f5aaa79a0c8d70aaeb4..e16cc37fd3460d113cbf9cea73c340d71bc35bb4 100644
--- a/src/gurka.app.src
+++ b/src/gurka.app.src
@@ -1,10 +1,9 @@
-{application,gurka,
-             [{description,"Erlang implementation of Cucumber"},
-              {vsn,"0.1.1"},
-              {applications,[kernel,stdlib]},
-              {registered,[]},
-              {env,[]},
-              {maintainers,["Erik Hedenstrom"]},
-              {licenses,["MIT"]},
-              {links,[{"GitLab",
-                       "https://gitlab.hedenstroem.com/erlang-ninja/gurka"}]}]}.
+{application, gurka, [{description, "Erlang implementation of Cucumber"},
+    {vsn, semver},
+    {applications, [kernel, stdlib]},
+    {registered, []},
+    {env, []},
+    {maintainers, ["Erik Hedenstrom"]},
+    {licenses, ["MIT"]},
+    {links, [{"GitLab", "https://gitlab.hedenstroem.com/erlang-ninja/gurka"}]}
+]}.