diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 73f33383b8e722b7e7e7b4bbd1cf2b7a7f4ef044..2f98937466ff3358fb0d30d78026b08537d09d70 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -21,9 +21,5 @@ cmake:
     script:
         - source /cvmfs/cms.cern.ch/cmsset_default.sh
         - yum install -y cmake3 python3 zsh
-        - scram project CMSSW_12_4_0
-        - cd CMSSW_12_4_0; eval $(scram runtime -sh); cd -
-        - (cd CMSSW_12_4_0; scram setup $OLDPWD/libgit2.xml)
-        - cmake3 -B build
-        - cmake3 --build build -v -j$(nproc)
+        - ./install.sh
 
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ae9227fc4f84b2043e0babedb51beaca57e306de
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+set -e
+
+BASE_DIR=$PWD
+
+# Get a CMSSW if we don't have one
+if [ -z $CMSSW_BASE ]; then
+    cmsrel CMSSW_12_4_0
+    cd CMSSW_12_4_0
+    cmsenv
+fi
+
+# Set up libgit2
+cd $CMSSW_BASE
+scram setup ../libgit2.xml
+
+# Download and build supporting tools
+cd $BASE_DIR
+cmake3 -B .build
+cmake3 --build .build -j$(nproc)
+cmake3 --build .build --target install -j8
+
+# Set up scram tools in CMSSW
+cd $CMSSW_BASE
+for xml in $BASE_DIR/tools/etc/*.xml; do
+    scram setup $xml
+done
+
+# Get Core
+cd $CMSSW_BASE/src
+[ ! -d Core ] && git clone https://gitlab.cern.ch/DasAnalysisSystem/Core.git
+