Skip to content

Instantly share code, notes, and snippets.

@doot0
Created August 8, 2025 11:46
Show Gist options
  • Save doot0/68d801190148f2248f36269a23a35a29 to your computer and use it in GitHub Desktop.
Save doot0/68d801190148f2248f36269a23a35a29 to your computer and use it in GitHub Desktop.
LineageOS - OnePlus 8T root (on MacOS host)
#!/bin/bash
set -e
DEVICE="kebab"
WORKDIR="$HOME/lineage_root"
DEVICE_STORAGE_NAME="Download"
FAIL_LATER=()
FORCE_REFRESH=false
# Optional flag: --fresh
if [[ "$1" == "--fresh" ]]; then
echo "πŸ” Force-redownloading and re-extracting files..."
FORCE_REFRESH=true
fi
fail() { echo "❌ ERROR: $1"; exit 1; }
echo "=== Step 0: Gather Info ==="
adb start-server
sleep 2
if ! adb devices | grep -w "device"; then
echo " β€’ Your device isn’t connected or USB debugging isn't authorized."
echo " β†’ Please enable USB debugging and authorize your Mac, then press Enter."
read -r
adb devices | grep -w "device" || fail "Device still not detected."
fi
echo " β€’ Device connected OK."
adb shell pm list packages | grep -q com.topjohnwu.magisk && MAGISK_INSTALLED=true || MAGISK_INSTALLED=false
echo " β€’ Magisk installed: $MAGISK_INSTALLED"
echo "=== Step 0b: Bootloader Check ==="
adb reboot bootloader
sleep 4
BOOT_STATUS=$(fastboot getvar unlocked 2>&1 | grep 'unlocked' | awk '{print $2}')
fastboot reboot
sleep 6
echo " β€’ Bootloader unlocked: $BOOT_STATUS"
if [[ "$BOOT_STATUS" != "yes" ]]; then
echo "πŸ”’ Bootloader is locked. Please unlock it manually first."
exit 1
fi
if [[ "$MAGISK_INSTALLED" = false ]]; then
echo "πŸ“± Please install Magisk APK on your phone and try again."
exit 1
fi
echo "=== Step 1: Check macOS Tools ==="
[[ ! $(command -v brew) ]] && echo " β€’ Installing Homebrew..." && /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
[[ ! $(command -v adb) || ! $(command -v fastboot) ]] && echo " β€’ Installing platform-tools..." && brew install --cask android-platform-tools
# Ensure xz is installed for lzma.h
if [[ ! -f /opt/homebrew/include/lzma.h ]]; then
echo "πŸ“¦ Installing liblzma (xz)..."
brew install xz || fail "Failed to install XZ / liblzma"
fi
# Install Go and payload-dumper-go
if ! command -v payload-dumper-go &>/dev/null; then
echo "πŸ›  Installing payload-dumper-go..."
brew install go || fail "Failed to install Go"
export PATH="$PATH:$HOME/go/bin"
export CGO_CFLAGS="-I/opt/homebrew/include"
export CGO_LDFLAGS="-L/opt/homebrew/lib"
echo 'export PATH="$PATH:$HOME/go/bin"' >> ~/.zprofile
go install github.com/ssut/payload-dumper-go@latest || fail "❌ Failed to compile payload-dumper-go (even with headers)"
fi
echo "=== Step 2: Determine LineageOS build ==="
LATEST_JSON=$(curl -s https://download.lineageos.org/api/v1/devices/${DEVICE}/builds || true)
if [[ -n "$LATEST_JSON" ]]; then
BUILD_FILE=$(echo "$LATEST_JSON" | grep '"filename"' | grep "nightly-${DEVICE}-signed.zip" | sed -E 's/.*"filename":"([^"]+)".*/\1/' | head -n1)
else
BUILD_FILE=""
fi
if [[ -z "$BUILD_FILE" ]]; then
echo "⚠️ No official nightly build found via API for $DEVICE."
read -rp "Enter filename manually (e.g. lineage-22.2-20250801-nightly-kebab-signed.zip): " BUILD_FILE
[[ -z "$BUILD_FILE" ]] && fail "No filename provided."
fi
if [[ "$BUILD_FILE" =~ lineage-([0-9]+\.[0-9]+)-([0-9]{8})-nightly-([a-z0-9]+)-signed\.zip ]]; then
LINEAGE_VER="${BASH_REMATCH[1]}"
BUILD_DATE="${BASH_REMATCH[2]}"
DEVICE_PARSED="${BASH_REMATCH[3]}"
else
fail "Filename doesn't match expected format."
fi
ROM_URL="https://mirrorbits.lineageos.org/full/${DEVICE}/${BUILD_DATE}/${BUILD_FILE}"
mkdir -p "$WORKDIR"
cd "$WORKDIR"
echo "=== Step 3: Download ROM ==="
if [[ "$FORCE_REFRESH" = true && -f "$BUILD_FILE" ]]; then
echo "πŸ” Removing old ROM due to --fresh flag..."
rm -f "$BUILD_FILE"
fi
if [[ -f "$BUILD_FILE" ]]; then
echo "πŸ“¦ Using cached ROM: $BUILD_FILE"
else
echo "⬇️ Downloading $BUILD_FILE..."
curl -L -O "$ROM_URL" || fail "Download failed."
fi
SZ=$(stat -f%z "$BUILD_FILE" 2>/dev/null || stat -c%s "$BUILD_FILE")
(( SZ < 500000000 )) && fail "Downloaded file too small (<500MB)."
echo "πŸ“¦ Checking for boot.img or payload.bin..."
if [[ "$FORCE_REFRESH" = true ]]; then
rm -f boot.img payload.bin
rm -rf extracted_payload/
fi
if [[ -f boot.img ]]; then
echo "βœ… Using cached boot.img"
else
unzip -o "$BUILD_FILE" 'boot.img' && echo "βœ… Extracted boot.img from ZIP." || {
if [[ -f extracted_payload/boot.img ]]; then
echo "βœ… Using cached boot.img from payload dump"
cp extracted_payload/boot.img .
else
echo "⚠️ boot.img not found. Extracting from payload.bin..."
unzip -o "$BUILD_FILE" 'payload.bin' || fail "Could not extract payload.bin."
mkdir -p extracted_payload
payload-dumper-go -o extracted_payload payload.bin || fail "payload-dumper-go failed."
[[ ! -f extracted_payload/boot.img ]] && fail "boot.img not found in payload dump."
cp extracted_payload/boot.img .
echo "βœ… boot.img extracted from payload.bin."
fi
}
fi
echo "=== Step 4: Patch with Magisk ==="
echo "πŸ“‚ Please manually copy the file '$WORKDIR/boot.img' to your phone’s Downloads folder."
echo " You can drag it in Finder, or use Android File Transfer / OpenMTP."
open "$WORKDIR" || true
read -rp "πŸ“± Once it's copied and patched with Magisk, press Enter to continue..."
PATCHED=$(adb shell ls "/sdcard/${DEVICE_STORAGE_NAME}/magisk_patched-*.img" 2>/dev/null | tail -n1 | tr -d '\r')
[[ -z "$PATCHED" ]] && fail "No patched image found. Did you patch it with Magisk?"
adb pull "$PATCHED" "$WORKDIR/" || fail "Failed to pull patched image."
NEW_BOOT=$(basename "$PATCHED")
echo "=== Step 5: Flash patched image ==="
adb reboot bootloader
sleep 3
fastboot flash boot "$NEW_BOOT" || fail "Flashing failed."
fastboot reboot
echo "βœ… Rooting complete!"
echo "πŸ’Ύ Stock boot saved: $WORKDIR/boot.img"
echo "πŸ’Ύ Patched boot saved: $WORKDIR/$NEW_BOOT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment