diff --git a/.gitlab-ci.py b/.gitlab-ci.py
deleted file mode 100755
index d35b143fdc1233c041f7a482bf593322c9b70de9..0000000000000000000000000000000000000000
--- a/.gitlab-ci.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#! /usr/bin/env python3
-
-from os import environ as env
-from platform import system
-from subprocess import check_call, check_output
-from argparse import ArgumentParser
-
-
-def define(key: str, value: str):
-    return ['-D', f'{key}={value}']
-
-
-def define_env(name: str):
-    return define(name, env[name]) if name in env else []
-
-
-if system() == 'Windows':
-
-    def setup_msvc():
-        msvc_path = 'C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/Common7/Tools'
-        lines = check_output(
-            [
-                'cmd',
-                '/c',
-                'VsDevCmd.bat',
-                '-arch=amd64',
-                f'-vcvars_ver={env["VCVARS_VER"]}',
-                '&',
-                'set'
-            ],
-            cwd=msvc_path
-        ).decode('utf-8').splitlines()
-        for line in lines:
-            split = line.split('=')
-            if len(split) != 2:
-                continue
-            key, value = split
-            if key in env and env[key] == value:
-                continue
-            env[key] = value
-
-
-def build(args):
-    if system() == 'Windows':
-        setup_msvc()
-
-    command = ['cmake']
-    command += ['-S', '.']
-    command += ['-B', 'build']
-    command += ['-G', 'Ninja']
-    command += define_env('CMAKE_BUILD_TYPE')
-    command += define('CMAKE_SUPPRESS_REGENERATION', 'ON')
-    command += define('CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY', 'ON')
-
-    if system() == 'Windows':
-        command += define(
-            'CMAKE_TOOLCHAIN_FILE',
-            env['VCPKG_DIR'] + '/scripts/buildsystems/vcpkg.cmake'
-        )
-        command += define('VCPKG_TARGET_TRIPLET', env['VCPKG_TRIPLET'])
-    check_call(command)
-
-    command = ['ninja', '-C', 'build']
-    check_call(command)
-
-
-def package(args):
-    command = ['ninja', '-C', 'build', 'package']
-    check_call(command)
-
-
-if __name__ == '__main__':
-    parser = ArgumentParser()
-    subparsers = parser.add_subparsers()
-
-    build_parser = subparsers.add_parser('build')
-    build_parser.set_defaults(task=build)
-
-    package_parser = subparsers.add_parser('package')
-    package_parser.set_defaults(task=package)
-
-    args = parser.parse_args()
-    args.task(args)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4af2858fb19989f2f6c1dfb1ab9393e97c1a5623..2f7042f0010f11d043e1b28bf8bde7cdcd66dc04 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,30 +1,22 @@
 stages:
   - build
   - package
-  - deploy
+  - trigger
 
-.centos-7:
+.centos:
   tags: [ linux, docker ]
-  image: git.imp.fu-berlin.de:5000/bioroboticslab/robofish/docker:centos-7
+  image: git.imp.fu-berlin.de:5000/bioroboticslab/robofish/docker:centos
 
-.windows-1809:
-  tags: [ windows-1809, docker ]
-  image: git.imp.fu-berlin.de:5000/bioroboticslab/robofish/docker:devel-windows-1809
+.windows:
+  tags: [ windows, docker ]
+  image: git.imp.fu-berlin.de:5000/bioroboticslab/robofish/docker:devel-windows
+  before_script:
+    - . $Profile.AllUsersAllHosts
 
 
-.gcc8: &gcc8
-  CC: gcc-8
-  CXX: g++-8
-
-.msvc15.9: &msvc15_9
-  VCVARS_VER: '14.16'
-
 .release: &release
   CMAKE_BUILD_TYPE: Release
 
-.debug: &debug
-  CMAKE_BUILD_TYPE: Debug
-
 
 .build: &build
   stage: build
@@ -32,26 +24,9 @@ stages:
     paths:
       - build
     expire_in: 1 day
-  script: ./.gitlab-ci.py build
-
-build centos-7:
-  extends: .centos-7
-  <<: *build
-  variables:
-    <<: [ *release ]
-
-build windows-1809:
-  extends: .windows-1809
-  <<: *build
-  variables:
-    <<: [ *msvc15_9, *release ]
-
-build windows-1809[debug]:
-  extends: .windows-1809
-  <<: *build
-  variables:
-    <<: [ *msvc15_9, *debug ]
-
+  script:
+    - ./ci/configure.py
+    - ./ci/compile.py
 
 .package: &package
   stage: package
@@ -59,33 +34,46 @@ build windows-1809[debug]:
     paths:
       - build/*.tar.xz
     expire_in: 1 week
-  script: ./.gitlab-ci.py package
+  script:
+    - ./ci/package.py
+
+
+build centos:
+  extends: .centos
+  <<: *build
+  variables:
+    <<: [ *release ]
+
+build windows:
+  extends: .windows
+  <<: *build
+  variables:
+    <<: [ *release ]
 
-package centos-7:
-  extends: .centos-7
-  dependencies:
-    - build centos-7
-  <<: *package
 
-package windows-1809:
-  extends: .windows-1809
+package centos:
+  extends: .centos
   dependencies:
-    - build windows-1809
+    - build centos
   <<: *package
 
-package windows-1809[debug]:
-  extends: .windows-1809
+package windows:
+  extends: .windows
   dependencies:
-    - build windows-1809[debug]
+    - build windows
   <<: *package
 
 
 trigger robofish/robotracker:
-  stage: deploy
+  stage: trigger
+  only:
+    - master
   trigger:
     project: bioroboticslab/robofish/robotracker
 
 trigger biotracker/biotracker:
-  stage: deploy
+  stage: trigger
+  only:
+    - master
   trigger:
     project: bioroboticslab/biotracker/biotracker
diff --git a/ci/compile.py b/ci/compile.py
new file mode 100755
index 0000000000000000000000000000000000000000..bf791920d530d414a659f6ea7249d4baad6aaa92
--- /dev/null
+++ b/ci/compile.py
@@ -0,0 +1,7 @@
+#! /usr/bin/env python3
+
+from subprocess import check_call
+
+if __name__ == "__main__":
+    command = ["ninja", "-C", "build"]
+    check_call(command)
diff --git a/ci/configure.py b/ci/configure.py
new file mode 100755
index 0000000000000000000000000000000000000000..bdecb85a72a85d6e5b6b7cbadd6f6682dbbb1798
--- /dev/null
+++ b/ci/configure.py
@@ -0,0 +1,28 @@
+#! /usr/bin/env python3
+
+from os import environ as env
+from subprocess import check_call
+from pathlib import Path
+
+
+def define(key: str, value: str):
+    return ["-D", f"{key}={value}"]
+
+
+def define_env(name: str):
+    return define(name, env[name]) if name in env else []
+
+
+if __name__ == "__main__":
+    command = ["cmake"]
+    command += ["-S", "."]
+    command += ["-B", "build"]
+    command += ["-G", "Ninja"]
+    command += define('CMAKE_PREFIX_PATH', Path('vendor').resolve())
+    command += define_env("CMAKE_BUILD_TYPE")
+    command += define_env("CMAKE_TOOLCHAIN_FILE")
+    command += define("CMAKE_SUPPRESS_REGENERATION", "ON")
+    command += define("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY", "ON")
+    command += define_env("VCPKG_TARGET_TRIPLET")
+
+    check_call(command)
diff --git a/ci/package.py b/ci/package.py
new file mode 100755
index 0000000000000000000000000000000000000000..fe4032f6e45cc938f14f7e4dac148a6709afea22
--- /dev/null
+++ b/ci/package.py
@@ -0,0 +1,7 @@
+#! /usr/bin/env python3
+
+from subprocess import check_call
+
+if __name__ == "__main__":
+    command = ["ninja", "-C", "build", "package"]
+    check_call(command)