diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5c4983a637f4f1a3980393cc25299b2b91e16920..f71b4a5670b30ee3cd077d3479403635a795f6f7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,4 +18,6 @@ build:
     - cat gitlab-known-hosts >> ~/.ssh/known_hosts
   script:
     - ./update-gluon.sh
+    - rm -rf gluon
+    - ./update-gluon-experimental.sh
   cache: {}
diff --git a/update-gluon-experimental.sh b/update-gluon-experimental.sh
new file mode 100755
index 0000000000000000000000000000000000000000..15a01d5ec71aa1a53d484dfb977c98f6241bfdd1
--- /dev/null
+++ b/update-gluon-experimental.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+set -x
+set -eu
+set -o pipefail
+
+gluon_fork_git_url="ssh://git@gitlab.freifunk-stuttgart.de:22220/firmware/gluon.git"
+gluon_upstream_git_url="https://github.com/freifunk-gluon/gluon.git"
+site_git_url="ssh://git@gitlab.freifunk-stuttgart.de:22220/firmware/site-ffs.git"
+
+git clone "$gluon_fork_git_url" gluon
+cd gluon
+git remote add upstream "$gluon_upstream_git_url"
+
+git checkout experimental
+
+# search in the fork for the newest tag of our fork with custom patches
+fork_tag=$(git tag | grep -E '^experimental-[0-9]{4}-[0-9]{2}-[0-9]{2}$' | sort | tail -n1)
+echo Fork is at "$fork_tag"
+
+# check that we have a base tag
+base_tag="$fork_tag-base"
+if ! git rev-parse "$base_tag"; then
+	echo Base tag "$base_tag" does not exist
+	exit 1
+fi
+echo Base is at "$base_tag"
+
+git fetch upstream master
+rebase_output=$(git rebase "$base_tag" --onto FETCH_HEAD)
+if [ "$rebase_output" = "Current branch experimental is up to date." ]; then
+	echo No changes in branch. not doing anything.
+	exit 0
+fi
+
+
+fork_commit=$(git rev-parse --verify "$fork_tag")
+current_commit=$(git rev-parse --verify HEAD)
+# we didn't change anything - no new upstream release, no need to do anything
+if [ "$current_commit" = "$fork_commit" ]; then
+	echo fork commit "$upstream_commit" matches current commit - not doing anything
+	exit 0
+fi
+
+new_tag_name="experimental-$(date +%Y-%m-%d)"
+new_base_tag_name="$new_tag_name-base"
+
+git tag -a "$new_tag_name" -m "Release $new_tag_name"
+git tag -a "$new_base_tag_name" -m "Release $new_base_tag_name" FETCH_HEAD
+git push origin "$new_tag_name"
+git push origin "$new_base_tag_name"
+
+git push --force-with-lease origin
+
+cd ..
+
+git clone --recurse "$site_git_url"
+
+cd site-ffs
+git checkout experimental
+
+git submodule sync
+git submodule update
+
+git -C gluon fetch
+git -C gluon checkout "$new_tag_name"
+
+git add gluon
+git commit -m "automatic update to gluon $new_tag_name"
+git push