diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 44c718e279b81a95d22915ced5843f3167dc0195..9f862dc02f5a99513964bf6fcfd0c5aa344ea41c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,6 +13,7 @@ variables:
 include:
   # extends
   - local: '/scripts/ci/extends/build.yml'
+  - local: '/scripts/ci/extends/build-win.yml'
   - local: '/scripts/ci/extends/container-maker-setup.yml'
   - local: '/scripts/ci/extends/vs2019-environment.yml'
   - local: '/scripts/ci/extends/test-artifacts.yml'
diff --git a/scripts/ci/extends/build-win.yml b/scripts/ci/extends/build-win.yml
new file mode 100644
index 0000000000000000000000000000000000000000..67abc7b8ef1eb25b3958616e4dcc5bc572c55213
--- /dev/null
+++ b/scripts/ci/extends/build-win.yml
@@ -0,0 +1,17 @@
+.build_win_definition:
+  stage: test
+  extends:
+    - .vs2019-environment
+    - .test-artifacts
+
+  variables:
+    CCACHE_DIR: "$CI_PROJECT_DIR/.ccache"
+
+  script:
+    - mkdir -p $BUILD_DIR
+    - cd $BUILD_DIR
+    - cmake .. -G Ninja $env:CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DOGS_BUILD_PROCESSES=GroundwaterFlow
+    - cmake --build . | Tee-Object -FilePath make.output
+    - cmake --build . --target tests
+    - cmake --build . --target ctest
+    - cp Testing/**/Test.xml Tests/ctest.xml
diff --git a/scripts/ci/jobs/build-win.yml b/scripts/ci/jobs/build-win.yml
index 232daf4adeb4de278f65648293cae125273c418f..a59f4efcd56b4b7018d9c2aed41273d8c4c911c7 100644
--- a/scripts/ci/jobs/build-win.yml
+++ b/scripts/ci/jobs/build-win.yml
@@ -1,23 +1,14 @@
 build win:
   stage: test
+
   tags:
     - windows
+
   variables:
-    BUILD_DIR: "build-win"
-  extends:
-    - .vs2019-environment
-    - .test-artifacts
+    BUILD_DIR: build-win
+    CMAKE_ARGS: >-
+      "-DOGS_USE_PYTHON=ON"
+      "-DOGS_CI_TESTRUNNER_REPEAT=1"
 
-  script:
-    - mkdir -p $BUILD_DIR
-    - cd $BUILD_DIR
-    - |
-      cmake .. -G Ninja `
-        -DCMAKE_BUILD_TYPE=Release `
-        -DOGS_BUILD_PROCESSES=GroundwaterFlow `
-        -DOGS_USE_PYTHON=ON `
-        -DOGS_CI_TESTRUNNER_REPEAT=1
-    - cmake --build . | Tee-Object -FilePath make.output
-    - cmake --build . --target tests
-    - cmake --build . --target ctest
-    - cp Testing/**/Test.xml Tests/ctest.xml
+  extends:
+    - .build_win_definition
diff --git a/scripts/ci/jobs/gui.yml b/scripts/ci/jobs/gui.yml
index a1f06895920b2f8c8d1af4bfb90fcb484309938b..a1e23fbcad8af7ae0cefbb8f286978547fc5f5d4 100644
--- a/scripts/ci/jobs/gui.yml
+++ b/scripts/ci/jobs/gui.yml
@@ -1,28 +1,19 @@
 gui win:
   stage: gui
   when: manual
+
   tags:
     - windows
+
   variables:
-    BUILD_DIR: "build-gui-win"
-  extends:
-    - .vs2019-environment
-    - .test-artifacts
+    BUILD_DIR: build-gui-win
+    CMAKE_ARGS: >-
+      "-DOGS_USE_PYTHON=ON"
+      "-DOGS_BUILD_GUI=ON"
+      "-DOGS_BUILD_UTILS=ON"
+      "-DOGS_BUILD_SWMM=ON"
+      "-DOGS_USE_NETCDF=ON"
+      "-DOGS_CI_TESTRUNNER_REPEAT=1"
 
-  script:
-    - mkdir -p $BUILD_DIR
-    - cd $BUILD_DIR
-    - |
-      cmake .. -G Ninja `
-        -DCMAKE_BUILD_TYPE=Release `
-        -DOGS_BUILD_PROCESSES=GroundwaterFlow `
-        -DOGS_USE_PYTHON=ON `
-        -DOGS_BUILD_GUI=ON `
-        -DOGS_BUILD_UTILS=ON `
-        -DOGS_BUILD_SWMM=ON `
-        -DOGS_USE_NETCDF=ON `
-        -DOGS_CI_TESTRUNNER_REPEAT=1
-    - cmake --build . --target tests
-    - cmake --build . --target ctest
-    - cp Testing/**/Test.xml Tests/ctest.xml
-    - cmake --build .
+  extends:
+    - .build_win_definition