diff --git a/release.sh b/release.sh
new file mode 100644
index 00000000..39cfefec
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,102 @@
+#!/usr/bin/env bash
+
+# Stop at first error
+set -e
+
+if ! command -v gh > /dev/null; then
+ echo "Could not find the GitHub CLI, please install it from https://github.com/cli/cli"
+ exit 1
+fi
+
+# Use version from changelog
+# version=$(head -n1 CHANGELOG.md|cut -d"v" -f2);
+version=$1
+# The target branch, defaults to the current branch
+target=${2:-$(git branch --show-current)}
+# The tag
+tag=v$version
+
+if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ echo "Invalid version, please enter a valid semantic version"
+ exit 1
+fi
+
+if [[ $(git branch --show-current) != $target ]]; then
+ if ! git switch $target > /dev/null; then
+ echo "Target branch does not exist, please enter a valid branch name"
+ exit 1
+ fi
+fi
+
+echo "Releasing version $version on branch $target";
+
+# Ask for confirmation
+read -r -p "Are you sure? [y/N] " input
+
+case $input in
+ [yY][eE][sS]|[yY])
+ echo "You say Yes"
+ ;;
+ [nN][oO]|[nN])
+ echo "You say No"
+ exit 1
+ ;;
+ *)
+ echo "Invalid input..."
+ exit 1
+ ;;
+esac
+
+# Ask for confirmation
+read -r -p "Create commit and tag? [y/N] " input
+
+case $input in
+ [yY][eE][sS]|[yY])
+ echo "You say Yes"
+
+ # Bump version in info.xml
+ sed -i -E "s|^\t.+|\t$version|" appinfo/info.xml
+
+ # Add changed files to git
+ git add CHANGELOG.md
+ git add appinfo/info.xml
+
+ # Create commit
+ git commit --signoff --message $tag
+
+ # Create tag
+ git tag $tag
+
+ # Show the result
+ git log -1 -p
+ ;;
+ *)
+ echo "You say No"
+ ;;
+esac
+
+# Ask for confirmation
+read -r -p "Push and draft releases? [y/N] " input
+
+case $input in
+ [yY][eE][sS]|[yY])
+ echo "You say Yes"
+
+ # Push commit
+ git push git@github.com:nextcloud/user_migration.git
+
+ # Push tag
+ git push git@github.com:nextcloud/user_migration.git $tag
+ git push git@github.com:nextcloud-releases/user_migration.git $tag
+
+ # Draft GitHub releases
+ gh release create --repo nextcloud/user_migration --draft --generate-notes --target $target --title $tag --verify-tag $tag
+ gh release create --repo nextcloud-releases/user_migration --draft --generate-notes --target $target --title $tag --verify-tag $tag
+ ;;
+ *)
+ echo "You say No"
+ ;;
+esac
+
+echo "Check and publish the drafted release on https://github.com/nextcloud/user_migration/releases"
+echo "Check and publish the drafted release on https://github.com/nextcloud-releases/user_migration/releases"