From 4491ff50bac201a86bce7538cf891f887a70804a Mon Sep 17 00:00:00 2001 From: "Lockszmith (@Kateryna)" Date: Sat, 15 Mar 2025 22:35:07 -0400 Subject: [PATCH] Safe Automated Update Added detection of next available version (as opposed to just latest) Automatic incremental updates with `tpc update next`. --- _bin/checkver.sh | 108 ++++++++++++++++++++++++++++++++++------------- _bin/rtpctl.d | 30 ++++++++++--- 2 files changed, 104 insertions(+), 34 deletions(-) diff --git a/_bin/checkver.sh b/_bin/checkver.sh index ebcfe5e..c67458b 100755 --- a/_bin/checkver.sh +++ b/_bin/checkver.sh @@ -1,6 +1,8 @@ #! /usr/bin/env bash SCRIPT_DIR=${SCRIPT_DIR:-"$( cd -- "$( dirname -- "$0" )" &> /dev/null && pwd )"} +set -e + # Function to compare semantic versions compare_major_version() { local major_version1=$(echo $1 | cut -d. -f1) @@ -12,38 +14,86 @@ compare_major_version() { return 1 fi } + +if [[ "${1}" =~ ^(-h|--help$) ]]; then + printf '%s\n' \ + "Query runtipi's current version and compares with what is available online" \ + "" \ + "Usage:" \ + " ${0##*/} -h | --help | [next] [] " \ + "" \ + "Arguments:" \ + " -h | --help Display usage" \ + " version [optional] assume current version - auto-detected when ommitted" \ + " next Show the next version (to current-version, see above)" \ + "" \ + "Exit codes:" \ + " 0 (ok) if (next) and on the latest version" \ + " if (next) and next version exist and is not a major version change" \ + " or when listing versions (not 'next')" \ + "" \ + " 1 non operational (like --help)" \ + " major versions do not match" + exit 1 +fi # Get Current Version of Runtipi runtipi_path=${RUNTIPI_DIR:-"$(cd -- "${SCRIPT_DIR}/../.." &> /dev/null && pwd )"} -[ -r "$runtipi_path/VERSION" ] || runtipi_path=${RUNTIPI_DIR:-"$(cd -- "${SCRIPT_DIR}/../../_" &> /dev/null && pwd )"} -current_version=$(cat "$runtipi_path/VERSION") +current_version="$1" +if [ "$current_version" == "next" ]; then + current_version="$2" + next_version_only=1 +fi +if [ -z "$current_version" ]; then + [ -r "$runtipi_path/VERSION" ] || runtipi_path=${RUNTIPI_DIR:-"$(cd -- "${SCRIPT_DIR}/../../_" &> /dev/null && pwd )"} + current_version=$(cat "$runtipi_path/VERSION") +fi # Get the latest release information from GitHub API -latest_release=$(curl -sL \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/runtipi/runtipi/releases/latest) +latest_releases_page=1 +latest_releases="" +while [ $latest_releases_page -lt ${RELEASE_PAGE_LIMIT:-4} ]; do + tmp_releases="$(curl -sL \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/runtipi/runtipi/releases\?page=${latest_releases_page} \ + | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4 | grep -E '^v[[:digit:]\.]+$' \ + )" || break + + [ -z "$tmp_releases" ] \ + && tmp_releases="EMPTY" && break \ + || true + + latest_releases="$(printf '%s\n' ${latest_releases} ${tmp_releases})" + + grep -q "^${current_version}$" <<<"${tmp_releases}" \ + && tmp_releases="" && break \ + || (( latest_releases_page+=1 )) +done +[ -n "$tmp_releases" ] \ +&& next_version_only="" && current_version="${current_version} # !not-online!" \ +|| tmp_releases="" + +# List everything up to latest version (excluding the latest version) +latest_releases="$( <<<"${latest_releases}" sed -n ' + 0,/^'"${current_version//\./\\.}"'$/p + ' | tac +)" + +next_tag="$( head -n2 <<<"${latest_releases:-${current_version}}" | tail -n1 )" +latest_tag="$( tail -n1 <<<"${latest_releases:-${current_version}}")" -# Extract the tag name from the release information -tag_name=$(echo "$latest_release" | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4) - -printf 'current: %-10s online: %-10s\n' "$current_version" "$tag_name" >&2 -# Compare major version numbers -compare_major_version "$tag_name" "$current_version" -# major_version_match=$? -# -# # Check if major versions are the same and if the latest release is newer than the current version -# if [[ $major_version_match -eq 0 ]] && [[ "$tag_name" > "$current_version" ]]; then -# echo "A new release is available: $tag_name" -# cd $runtipi_path -# echo "Backing up current version" -# if [ ! -d "$runtipi_path/backups" ]; then -# mkdir -p $runtipi_path/backups -# fi -# tar -czvf runtipi-backup-$current_version.tar.gz --exclude=media --exclude=backups * -# mv runtipi-backup-$current_version.tar.gz $runtipi_path/backups -# echo "Starting update" -# echo $runtipi_path/runtipi-cli update latest -# else -# echo "No new release found or major version mismatch" -# fi +if [ "$next_version_only" != "1" ]; then + printf 'current:\n %-10s\nonline:\n' "$current_version" >&2 + [ ${#latest_releases} -eq 0 ] || printf ' %-10s\n' ${latest_releases} >&2 + # Compare major version numbers + compare_major_version "$latest_tag" "$current_version" +elif [ "$next_tag" == "$current_version" ]; then + printf "on the latest version\n" + #printf "%s\n" "$current_version" >&2 +elif [ "$next_tag" != "$current_version" ]; then + printf "%s\n" "$next_tag" + # Compare major version numbers + compare_major_version "$next_tag" "$current_version" +fi + diff --git a/_bin/rtpctl.d b/_bin/rtpctl.d index fd3bcd1..00f1e1b 100755 --- a/_bin/rtpctl.d +++ b/_bin/rtpctl.d @@ -292,10 +292,30 @@ case "${1}" in runtipi-cli start --env-file user-config/.env.local ${2:---no-permissions} ;; update) - if [ -z "${2}" ]; then - ${SCRIPT_DIR}/checkver.sh + if [[ "$2" =~ ^(-h|--help$|help$) ]]; then + printf '%s %-12s %s\n' \ + "Query if upgrade is available, or perform auto update" "" "" \ + "" "" "" \ + "Usage:" "" ""\ + " ${BASE_NAME} update -h | --help | [ -- [] | [next] [version] ] " "" ""\ + "" "" "" \ + "Arguments:" "" ""\ + "" "-h | --help" "Display usage" \ + "" "" "" \ + "" "-- []" "invoke checkver.sh with [optional] " \ + "" "version" "specify specific version" \ + "" "next" "detect next version (version will assume current-version instead of detecting)" + exit 1 + fi + if [ -z "${2}" ] || [ "${2}" == '--' ]; then + ${SCRIPT_DIR}/checkver.sh "${@:3}" else - runtipi-cli update --env-file user-config/.env.local --no-permissions "${2:?Must supply version}" "${@:3}" + update_to="${2:?Must supply version}" + [ "${update_to}" != "auto" ] && [ "${update_to}" != "next" ] \ + || update_to=$(${SCRIPT_DIR}/checkver.sh next "${3}") || update_to="" + [ "${update_to}" == "on the latest version" ] && exit 0 + [ -n "${update_to}" ] \ + && runtipi-cli update --env-file user-config/.env.local --no-permissions "${update_to}" "${@:4}" fi ;; dls) @@ -319,8 +339,8 @@ case "${1}" in setup) ln -s $2 "$(cd -- "${SCRIPT_DIR}" && pwd)/${BASE_NAME}" "${3:-$HOME/.local/bin/}" ;; - edit) - ${VISUAL:-${EDITOR:-vi}} $0 + editme) + ${VISUAL:-${EDITOR:-vi}} "$(readlink -f "$0")" ;; _load) echo "alias ${BASE_NAME}cd='cd \"$SCRIPT_DIR/..\"'"