#!/bin/bash set -e # -- SECURITY CHECK: Root only -- if [ "$EUID" -ne 0 ]; then echo "ERROR: This script must be run as root!" echo "Please use: sudo $0" exit 1 fi # Configuration RUNNER_USER="git" RUNNER_GROUP="git" SERVICE_NAME="gitea-runner" INSTALL_DIR="/usr/local/bin" BINARY_NAME="gitea-runner" CONFIG_DIR="/var/lib/gitea-runner" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' echo -e "${GREEN}=== Gitea Runner Update Checker ===${NC}" # Get current installed version if ! command -v ${BINARY_NAME} &> /dev/null; then echo -e "${RED}Error: ${BINARY_NAME} not found in PATH${NC}" exit 1 fi CURRENT_VERSION=$(${BINARY_NAME} --version 2>&1 | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+') if [ -z "$CURRENT_VERSION" ]; then echo -e "${RED}Error: Could not determine current version${NC}" exit 1 fi echo -e "Current version: ${YELLOW}v${CURRENT_VERSION}${NC}" # Fetch latest version from Gitea API echo "Checking for latest version..." API_URL="https://gitea.com/api/v1/repos/gitea/runner/releases/latest" LATEST_INFO=$(curl -s "${API_URL}") if [ $? -ne 0 ]; then echo -e "${RED}Error: Failed to fetch release information from Gitea API${NC}" exit 1 fi # Parse version (improved parsing from your script) LATEST_VERSION=$(echo "${LATEST_INFO}" | grep -o '"tag_name":"[^"]*"' | cut -d'"' -f4 | sed 's/^v//') if [ -z "$LATEST_VERSION" ]; then echo -e "${RED}Error: Could not parse latest version from API response${NC}" exit 1 fi echo -e "Latest version: ${YELLOW}v${LATEST_VERSION}${NC}" # Compare versions using sort -V (semantic version comparison) if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then echo -e "${GREEN}✓ You already have the latest version installed!${NC}" exit 0 fi # Check if update is needed NEWER=$(printf '%s\n%s' "$CURRENT_VERSION" "$LATEST_VERSION" | sort -V | tail -n1) if [ "$NEWER" = "$CURRENT_VERSION" ]; then echo -e "${YELLOW}Warning: Installed version appears newer than latest release${NC}" read -p "Continue anyway? [y/N]: " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 0 fi fi echo -e "\n${YELLOW}New version available: v${CURRENT_VERSION} → v${LATEST_VERSION}${NC}" # Ask for update confirmation read -p "Do you want to update? [Y/n]: " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Update cancelled." exit 0 fi # Determine architecture ARCH=$(uname -m) case ${ARCH} in x86_64) ARCH_FILE="amd64" ;; aarch64) ARCH_FILE="arm64" ;; *) echo -e "${RED}Error: Unsupported architecture: ${ARCH}${NC}" exit 1 ;; esac # Prepare download variables DL_FILE="${BINARY_NAME}-${LATEST_VERSION}-linux-${ARCH_FILE}" DL_URL="https://dl.gitea.com/gitea-runner/${LATEST_VERSION}/${DL_FILE}" echo -e "\n${GREEN}Downloading version v${LATEST_VERSION}...${NC}" cd ${INSTALL_DIR} || exit 1 # Download binary and checksum wget -N "${DL_URL}" wget -N "${DL_URL}.sha256" # Verify checksum (your method, improved output) echo "Verifying checksum..." if sha256sum --check "${DL_FILE}.sha256" &> /dev/null; then echo -e "${GREEN}✓ Checksum verification passed${NC}" else echo -e "${RED}✗ Checksum verification FAILED! Aborting update.${NC}" rm -f "${DL_FILE}" "${DL_FILE}.sha256" exit 1 fi # Stop the service before updating echo "Stopping ${SERVICE_NAME}..." systemctl stop ${SERVICE_NAME} # Backup old binary if [ -f "${BINARY_NAME}" ]; then cp "${BINARY_NAME}" "${BINARY_NAME}.backup.${CURRENT_VERSION}" echo -e "Backup created: ${YELLOW}${BINARY_NAME}.backup.${CURRENT_VERSION}${NC}" fi # Install new binary (your symlink approach preserved) echo "Installing new version..." chmod +x "${DL_FILE}" chown ${RUNNER_USER}:${RUNNER_GROUP} "${DL_FILE}" ln -sf "${DL_FILE}" "${BINARY_NAME}" # Clean up rm -f "${DL_FILE}.sha256" # Verify installation NEW_VERSION=$(${BINARY_NAME} --version 2>&1 | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+') if [ "$NEW_VERSION" != "$LATEST_VERSION" ]; then echo -e "${RED}Error: Version mismatch after installation!${NC}" echo "Expected: v${LATEST_VERSION}, Got: v${NEW_VERSION}" # Restore backup if [ -f "${BINARY_NAME}.backup.${CURRENT_VERSION}" ]; then mv "${BINARY_NAME}.backup.${CURRENT_VERSION}" "${BINARY_NAME}" echo "Restored backup." fi systemctl start ${SERVICE_NAME} exit 1 fi echo -e "${GREEN}✓ Successfully updated to v${NEW_VERSION}${NC}" # Ask for service restart confirmation read -p "Do you want to restart the ${SERVICE_NAME} service now? [Y/n]: " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Starting ${SERVICE_NAME}..." systemctl start ${SERVICE_NAME} # Check service status sleep 2 if systemctl is-active --quiet ${SERVICE_NAME}; then echo -e "${GREEN}✓ Service started successfully${NC}" echo "" systemctl status ${SERVICE_NAME} --no-pager -l else echo -e "${RED}✗ Service failed to start! Check logs with: journalctl -u ${SERVICE_NAME}${NC}" exit 1 fi else echo -e "${YELLOW}Service not restarted. Please restart manually when ready:${NC}" echo " sudo systemctl restart ${SERVICE_NAME}" fi # Clean old backups (keep last 3) ls -t ${BINARY_NAME}.backup.* 2>/dev/null | tail -n +4 | xargs -r rm echo -e "\n${GREEN}=== Update complete! ===${NC}"