Skip to content

Instantly share code, notes, and snippets.

@shvchk
Created February 28, 2025 06:26
Show Gist options
  • Save shvchk/ab8246540ad44385dcf447d9c266c134 to your computer and use it in GitHub Desktop.
Save shvchk/ab8246540ad44385dcf447d9c266c134 to your computer and use it in GitHub Desktop.
Update LineageOS and Magisk from PC with ADB sideload
#! /usr/bin/env bash
set -euo pipefail
[[ -v 1 ]] || {
echo "Update LineageOS and Magisk from PC with ADB sideload"
echo "Usage: $(basename -- "$0") <device>"
echo "e.g. $(basename -- "$0") beryllium"
exit 1
}
DEVICE="$1"
BASE_DIR="${HOME}/Downloads"
dependencies=( "adb" "aria2c" "curl" "jq" "sha256sum" )
# text decoration utilities
# shellcheck disable=SC2015
{
normal=$(tput sgr0 ||:)
bold=$(tput bold ||:)
info_msg="$(tput setab 33 && tput setaf 231 ||:)$bold" # blue bg, white text
warn_msg="$(tput setab 220 && tput setaf 16 ||:)$bold" # yellow bg, black text
err_msg="$(tput setab 160 && tput setaf 231 ||:)$bold" # red bg, white text
accent="$(tput setab 238 && tput setaf 231 ||:)$bold" # gray bg, white text
}
_echo() {
# unset formatting after output
echo -e "${*} $normal"
}
ask() {
while echo; do
# `< /dev/tty` is required to be able to run via pipe: cat x.sh | bash
read -rp "${warn_msg} $* ${accent} + or - ${normal} " response < /dev/tty || { echo "No tty"; exit 1; }
case "$response" in
"+") return 0 ;;
"-") return 1 ;;
esac
done
}
clean() {
popd > /dev/null || :
ask "Cleanup?" || return
rm -rf "$OTA_DIR"
}
check_dependencies() {
for i in "$@"; do
command -v "$i" &> /dev/null || {
_echo >&2 "${accent} $i ${err_msg} required"
exit 1
}
done
}
boot_sideload_mode() {
adb -d reboot sideload || :
_echo "\n${warn_msg} If your device didn't reboot into ADB sideload mode automatically"
_echo "${warn_msg} Put your device into ADB sideload mode: ${normal} ${accent} Apply update ${normal} → ${accent} Apply from ADB"
ask "Enter ${accent} + ${warn_msg} when device will be in ADB sideload mode or ${accent} - ${warn_msg} to cancel" \
|| exit
}
update_los() {
local filename filesize
_echo "\n${info_msg} Updating LineageOS"
get_build_info() {
jq -r ".$*" <<< "$build_data"
}
build_data="$(jq -r '.files[] | select(.type == "nightly")' <<< "$LOS_BUILD_JSON")"
filename="$(get_build_info filename)"
filesize="$(get_build_info 'size / pow(1024; 2) | floor | tostring')"
_echo "\n${info_msg} Downloading"
_echo " $filename ($filesize MB)"
aria2c --allow-overwrite -c -x 4 -V --checksum=sha-256="$(get_build_info sha256)" "$(get_build_info url)"
_echo "\n${info_msg} Flashing"
_echo " * Connect your device to PC"
_echo " * Make sure USB debugging is enabled"
_echo " * Prepare to reboot into ADB sideload mode"
ask "Proceed?" || exit
boot_sideload_mode
adb -d sideload "$filename"
}
update_magisk() {
local release_api_url release_dl_url_base ver
_echo "\n${info_msg} Updating Magisk"
_echo "\n${info_msg} Downloading"
release_api_url="https://api.github.com/repos/topjohnwu/Magisk/releases"
release_dl_url_base="https://github.com/topjohnwu/Magisk/releases"
ver="$(curl -fsSL "$release_api_url" | jq -r '.[].tag_name' | rg -m 1 '^v')"
aria2c --allow-overwrite -c -x 4 -o magisk.zip "${release_dl_url_base}/download/${ver}/Magisk-${ver}.apk"
_echo "\n${info_msg} Flashing"
boot_sideload_mode
_echo "\n${warn_msg} Tap ${accent} Yes ${warn_msg} on ${err_msg} Signature verification failed ${warn_msg} error"
adb -d sideload magisk.zip
}
main() {
local LOS_BUILD_JSON
check_dependencies "${dependencies[@]}"
LOS_BUILD_JSON="$(curl -fsSL "https://download.lineageos.org/api/v2/devices/$DEVICE/builds" | jq -r '.[0]')"
LOS_VER="$(jq -r ".version" <<< "$LOS_BUILD_JSON")"
LOS_DATE="$(jq -r ".date" <<< "$LOS_BUILD_JSON")"
OTA_DIR="${BASE_DIR}/LOS-${DEVICE}/OTA-${LOS_VER}-${LOS_DATE}"
_echo "${info_msg} Device ${normal} $DEVICE"
_echo "${info_msg} Version ${normal} $LOS_VER / $LOS_DATE"
ask "Proceed?" || exit
mkdir -p "$OTA_DIR"
pushd "$OTA_DIR" > /dev/null
update_los
update_magisk
while ask "Need to install additional packages?"; do
# shellcheck disable=SC2012
pkg="$(ls -t -- *.zip | fzf +m --no-info --header-first --header "Select package")"
[[ -f $pkg ]] || { echo " No file, skipping"; continue; }
boot_sideload_mode
adb -d sideload "$pkg"
done
ask "Installation finished, reboot?" && adb -d reboot
}
trap clean EXIT
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment