Skip to content

Instantly share code, notes, and snippets.

@JayCuthrell
Last active June 19, 2026 23:50
Show Gist options
  • Select an option

  • Save JayCuthrell/c0bea7785cef24a832d1ce0a13d54d27 to your computer and use it in GitHub Desktop.

Select an option

Save JayCuthrell/c0bea7785cef24a832d1ce0a13d54d27 to your computer and use it in GitHub Desktop.
Upgrade GoToSocial to the latest version
#!/usr/bin/env bash
# --- Configuration ---
GTS_TARGET="linux_amd64"
INSTALL_DIR="/gotosocial"
BACKUP_DIR="$INSTALL_DIR/backups"
GTS_DB_PATH="/var/lib/gotosocial/gts.db"
# Ensure script is run as root
if [[ "$EUID" -ne 0 ]]; then
echo -e "\e[31m[ERROR]\e[0m Please run this script as root or using sudo."
exit 1
fi
# Move into the installation directory
cd "$INSTALL_DIR" || exit 1
# Dependency check
for cmd in curl jq wget sqlite3 awk tar sha256sum; do
if ! command -v "$cmd" &> /dev/null; then
echo -e "\e[31m[ERROR]\e[0m Required command '$cmd' is not installed. Please install it and try again."
exit 1
fi
done
# --- Argument Parsing ---
APPROVED=false
FORCE=false
SPECIFIC_VERSION=""
while [[ "$#" -gt 0 ]]; do
case $1 in
--approved) APPROVED=true; shift ;;
--force) FORCE=true; shift ;;
--version)
if [[ -n "$2" && "$2" != --* ]]; then
SPECIFIC_VERSION="${2#v}"
shift 2
else
echo -e "\e[31m[ERROR]\e[0m --version requires a version string (e.g., 0.22.0-rc3)."
exit 1
fi
;;
*)
echo -e "\e[33m[WARNING]\e[0m Unknown parameter: $1"
shift
;;
esac
done
# Function to handle execution logic
run() {
local desc=$1
local cmd=$2
if [ "$APPROVED" = true ]; then
echo -e "\e[32m[EXECUTING]\e[0m $desc"
if ! eval "$cmd"; then
echo -e "\e[31m[ERROR]\e[0m Command failed: $desc. Aborting."
exit 1
fi
else
echo -e "\e[33m[DRY RUN]\e[0m $desc"
echo -e " Command: \e[2m$cmd\e[0m"
fi
}
echo "--- Checking Version Requirements ---"
# 1. Determine Target Version
if [[ -n "$SPECIFIC_VERSION" ]]; then
GTS_VERSION="$SPECIFIC_VERSION"
echo -e "Targeting specified version: \e[1mv$GTS_VERSION\e[0m"
else
echo "Fetching Latest Stable Version from Codeberg..."
RAW_VERSION=$(curl -s https://codeberg.org/api/v1/repos/superseriousbusiness/gotosocial/releases/latest | jq -r .tag_name)
GTS_VERSION="${RAW_VERSION#v}"
if [[ -z "$GTS_VERSION" || "$GTS_VERSION" == "null" ]]; then
echo -e "\e[31m[ERROR]\e[0m Could not retrieve version from Codeberg API."
exit 1
fi
echo -e "Targeting latest stable: \e[1mv$GTS_VERSION\e[0m"
fi
# 2. Check Local Version
if [[ -f "./gotosocial" ]]; then
LOCAL_VERSION=$(./gotosocial --version | awk '{print $3}')
echo "Local Version: $LOCAL_VERSION"
echo "Target Version: $GTS_VERSION"
if [[ "$LOCAL_VERSION" == *"$GTS_VERSION"* ]]; then
if [ "$FORCE" = true ]; then
echo -e "\e[35m[FORCE]\e[0m Version match detected, but --force is active. Proceeding..."
else
echo -e "\e[32m✔ You are already running version $GTS_VERSION.\e[0m"
exit 0
fi
fi
else
echo "Local binary not found. Proceeding with fresh install."
fi
# Filenames
ARCHIVE_NAME="gotosocial_${GTS_VERSION}_${GTS_TARGET}.tar.gz"
CHECKSUM_FILE="checksums.txt"
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="$BACKUP_DIR/gts.db_$TIMESTAMP.db"
APP_BACKUP_FILE="$BACKUP_DIR/gts_assets_$TIMESTAMP.tar.gz"
if [ "$APPROVED" = false ]; then
echo -e "\n\e[1m*** UPGRADE PLAN: DRY RUN MODE ***\e[0m"
echo -e "Review commands below, then run with \e[32m--approved\e[0m to execute.\n"
fi
# 3. Upgrade Steps
run "Downloading archive" "wget -q --show-progress -O $ARCHIVE_NAME https://codeberg.org/superseriousbusiness/gotosocial/releases/download/v${GTS_VERSION}/${ARCHIVE_NAME}"
run "Downloading checksums" "wget -q -O $CHECKSUM_FILE https://codeberg.org/superseriousbusiness/gotosocial/releases/download/v${GTS_VERSION}/checksums.txt"
run "Verifying SHA256" "grep '$ARCHIVE_NAME' '$CHECKSUM_FILE' | sha256sum -c -"
run "Creating backup directory" "mkdir -p '$BACKUP_DIR'"
run "Stopping service" "systemctl stop gotosocial"
# --- BACKUP STEPS ---
run "Backing up database" "sqlite3 '$GTS_DB_PATH' \".backup '$BACKUP_FILE'\""
run "Backing up current app assets" "[[ -f gotosocial ]] && tar -czf '$APP_BACKUP_FILE' gotosocial web || true"
# --- EXTRACTION STEPS ---
run "Extracting new binary and web assets" "tar -xzf '$ARCHIVE_NAME' gotosocial web"
run "Setting permissions" "chown root:root gotosocial && chmod +x gotosocial && chown -R gotosocial:gotosocial web"
run "Cleaning up files" "rm '$ARCHIVE_NAME' '$CHECKSUM_FILE'"
run "Restarting service" "systemctl start gotosocial"
run "Verifying status" "systemctl status gotosocial --no-pager"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment