diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 6022ab13f..02016b9a4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,24 +1,28 @@
-image: registry.gitlab.com/fdroid/ci-images-client:latest
-
-cache:
-  paths:
-    - .gradle/wrapper
-    - .gradle/caches
-
 stages:
   - test
   - deploy
 
-before_script:
-  - export GRADLE_USER_HOME=$PWD/.gradle
-  - export ANDROID_COMPILE_SDK=`sed -n 's,.*compileSdkVersion\s*\([0-9][0-9]*\).*,\1,p' app/build.gradle`
-  - alias sdkmanager="sdkmanager --no_https"
-  - echo y | sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" > /dev/null
-  # limit RAM usage for all gradle runs
-  - export maxmem=$(expr $(sed -n 's,^MemAvailable:[^0-9]*\([0-9][0-9]*\)[^0-9]*$,\1,p' /proc/meminfo) / 1024 / 2 / 1024 \* 1024)
-  - printf '\norg.gradle.jvmargs=-Xmx${maxmem}m -XX:MaxPermSize=${maxmem}m\norg.gradle.daemon=false\norg.gradle.parallel=false\n' >> local.properties
+.base:
+  image: registry.gitlab.com/fdroid/ci-images-client:latest
+  before_script:
+    - export GRADLE_USER_HOME=$PWD/.gradle
+    - export ANDROID_COMPILE_SDK=`sed -n 's,.*compileSdkVersion\s*\([0-9][0-9]*\).*,\1,p' app/build.gradle`
+    - alias sdkmanager="sdkmanager --no_https"
+    - echo y | sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" > /dev/null
+    # limit RAM usage for all gradle runs
+    - export maxmem=$(expr $(sed -n 's,^MemAvailable:[^0-9]*\([0-9][0-9]*\)[^0-9]*$,\1,p' /proc/meminfo) / 1024 / 2 / 1024 \* 1024)
+    - printf '\norg.gradle.jvmargs=-Xmx${maxmem}m -XX:MaxPermSize=${maxmem}m\norg.gradle.daemon=false\norg.gradle.parallel=false\n' >> local.properties
+  after_script:
+    # this file changes every time but should not be cached
+    - rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
+    - rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/
+  cache:
+    paths:
+      - .gradle/wrapper
+      - .gradle/caches
 
 .test-template: &test-template
+  extends: .base
   stage: test
   artifacts:
     name: "${CI_PROJECT_PATH}_${CI_JOB_STAGE}_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHA}"
@@ -56,6 +60,7 @@ test_lint_pmd_checkstyle:
     - exit $EXITVALUE
 
 errorprone:
+  extends: .base
   stage: test
   script:
     - apt-get update
@@ -68,6 +73,7 @@ errorprone:
 # once these prove stable, the task should be switched to
 # connectedCheck to test all the build flavors
 .connected-template: &connected-template
+  extends: .base
   script:
     - ./gradlew assembleFullDebug
     - export AVD_SDK=`echo $CI_JOB_NAME | awk '{print $2}'`
@@ -112,6 +118,7 @@ connected 26 google_apis x86:
     - branches@eighthave/fdroidclient
 
 deploy_nightly:
+  extends: .base
   stage: deploy
   only:
     - master
@@ -131,8 +138,3 @@ deploy_nightly:
     # build the APKs!
     - ./gradlew assembleDebug
     - fdroid nightly -v
-
-after_script:
-    # this file changes every time but should not be cached
-    - rm -f $GRADLE_USER_HOME/caches/modules-2/modules-2.lock
-    - rm -fr $GRADLE_USER_HOME/caches/*/plugin-resolution/