diff --git a/.gitlab-ci-unix.yml b/.gitlab-ci-unix.yml
index 5c720f8517c4403158556c75969de0f5a8df5daa..b365e29dca76a85dc4689aff52dcb01a5e7ae478 100644
--- a/.gitlab-ci-unix.yml
+++ b/.gitlab-ci-unix.yml
@@ -10,7 +10,30 @@ spec:
     no_javascript:
       default: 'no'
 ---
-.spidermonkey:
+
+".$[[ inputs.os ]]":
+  extends: .rules
+  tags: 
+    - "$[[ inputs.tagname ]]"
+  variables:
+    CROSS_PLATFORM: "$[[ inputs.cross_platform ]]"
+    OS: "$[[ inputs.os ]]"
+    PLATFORM: "$[[ inputs.platform ]]"
+    OSP: "$[[ inputs.os ]]-$[[ inputs.platform ]]"
+    BUILD_FLAGS: "$[[ inputs.build_flags ]]"
+    NO_JAVASCRIPT: "$[[ inputs.no_javascript ]]"
+
+".$[[ inputs.os ]]-build":
+  stage: build
+  extends: .$[[ inputs.os ]]
+
+".$[[ inputs.os ]]-test":
+  stage: test
+  extends: .$[[ inputs.os ]]
+
+"spidermonkey-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd 3rdp/build
     - gmake ${BUILD_FLAGS} libmozjs
@@ -22,7 +45,9 @@ spec:
     - if: $NO_JAVASCRIPT == "yes"
       when: never
 
-.cryptlib:
+"cryptlib-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd 3rdp/build
     - gmake ${BUILD_FLAGS} cryptlib
@@ -31,7 +56,9 @@ spec:
     paths:
       - "3rdp/*.*.*.release/cl"
 
-.xpdev:
+"xpdev-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/xpdev
     - gmake ${BUILD_FLAGS}
@@ -40,7 +67,9 @@ spec:
     paths:
       - "src/xpdev/*.*.*.lib.release*"
 
-.encode:
+"encode-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/encode
     - gmake ${BUILD_FLAGS}
@@ -51,7 +80,9 @@ spec:
   needs:
     - job: "xpdev-$[[ inputs.os ]]"
 
-.hash:
+"hash-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/hash
     - gmake ${BUILD_FLAGS}
@@ -60,7 +91,9 @@ spec:
     paths:
       - "src/hash/*.*.*.lib.release*"
 
-.ciolib:
+"ciolib-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/ciolib
     - gmake ${BUILD_FLAGS}
@@ -73,7 +106,9 @@ spec:
     - job: "hash-$[[ inputs.os ]]"
     - job: "encode-$[[ inputs.os ]]"
 
-.sftp:
+"sftp-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/sftp
     - gmake ${BUILD_FLAGS}
@@ -84,7 +119,9 @@ spec:
   needs:
     - job: "xpdev-$[[ inputs.os ]]"
 
-.smblib:
+"smblib-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/smblib
     - gmake ${BUILD_FLAGS}
@@ -97,7 +134,9 @@ spec:
     - job: "hash-$[[ inputs.os ]]"
     - job: "encode-$[[ inputs.os ]]"
 
-.uifc:
+"uifc-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/uifc
     - gmake ${BUILD_FLAGS}
@@ -109,7 +148,9 @@ spec:
     - job: "xpdev-$[[ inputs.os ]]"
     - job: "ciolib-$[[ inputs.os ]]"
 
-.sbbs:
+"sbbs-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/sbbs3
     - gmake ${BUILD_FLAGS} all
@@ -133,7 +174,9 @@ spec:
     - if: $CROSS_PLATFORM == "yes"
       when: never
 
-.syncterm:
+"syncterm-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/syncterm
     - gmake ${BUILD_FLAGS}
@@ -150,7 +193,9 @@ spec:
     - job: "uifc-$[[ inputs.os ]]"
     - job: "xpdev-$[[ inputs.os ]]"
 
-.syncdraw:
+"syncdraw-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/syncdraw
     - gmake ${BUILD_FLAGS}
@@ -162,7 +207,9 @@ spec:
     - job: "ciolib-$[[ inputs.os ]]"
     - job: "xpdev-$[[ inputs.os ]]"
 
-.jsdoor:
+"jsdoor-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/sbbs3
     - gmake ${BUILD_FLAGS} jsdoor
@@ -181,16 +228,9 @@ spec:
     - job: "uifc-$[[ inputs.os ]]"
     - job: "xpdev-$[[ inputs.os ]]"
 
-.js-testsuite:
-  script:
-    - "src/sbbs3/*.exe.release/jsdoor exec/tests/test.js"
-  dependencies:
-    - "jsdoor-$[[ inputs.os ]]"
-  rules:
-    - if: $CROSS_PLATFORM == "yes"
-      when: never
-
-.sexpots:
+"sexpots-$[[ inputs.os ]]":
+  extends:
+    - .$[[ inputs.os ]]-build
   script:
     - cd src/sexpots
     - gmake ${BUILD_FLAGS}
@@ -201,97 +241,13 @@ spec:
   needs:
     - job: "xpdev-$[[ inputs.os ]]"
 
-".$[[ inputs.os ]]":
-  extends: .rules
-  tags: 
-    - "$[[ inputs.tagname ]]"
-  variables:
-    CROSS_PLATFORM: "$[[ inputs.cross_platform ]]"
-    OS: "$[[ inputs.os ]]"
-    PLATFORM: "$[[ inputs.platform ]]"
-    OSP: "$[[ inputs.os ]]-$[[ inputs.platform ]]"
-    BUILD_FLAGS: "$[[ inputs.build_flags ]]"
-    NO_JAVASCRIPT: "$[[ inputs.no_javascript ]]"
-
-".$[[ inputs.os ]]-build":
-  stage: build
-  extends: .$[[ inputs.os ]]
-
-".$[[ inputs.os ]]-test":
-  stage: test
-  extends: .$[[ inputs.os ]]
-
-"spidermonkey-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .spidermonkey
-
-"cryptlib-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .cryptlib
-
-"xpdev-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .xpdev
-
-"encode-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .encode
-
-"hash-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .hash
-
-"ciolib-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .ciolib
-
-"sftp-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .sftp
-
-"smblib-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .smblib
-
-"uifc-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .uifc
-
-"sbbs-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .sbbs
-
-"syncterm-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .syncterm
-
-"syncdraw-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .syncdraw
-
-"jsdoor-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .jsdoor
-
-"sexpots-$[[ inputs.os ]]":
-  extends:
-    - .$[[ inputs.os ]]-build
-    - .sexpots
-
 "js-testsuite-$[[ inputs.os ]]":
   extends:
     - .$[[ inputs.os ]]-test
-    - .js-testsuite
+  script:
+    - "src/sbbs3/*.exe.release/jsdoor exec/tests/test.js"
+  dependencies:
+    - "jsdoor-$[[ inputs.os ]]"
+  rules:
+    - if: $CROSS_PLATFORM == "yes"
+      when: never