Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 59 additions & 28 deletions MerlinAU.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#
# Original Creation Date: 2023-Oct-01 by @ExtremeFiretop.
# Official Co-Author: @Martinski W. - Date: 2023-Nov-01
# Last Modified: 2025-Jun-17
# Last Modified: 2025-Jun-28
###################################################################
set -u

## Set version for each Production Release ##
readonly SCRIPT_VERSION=1.4.9
readonly SCRIPT_VERSION=1.5.0
readonly SCRIPT_NAME="MerlinAU"
## Set to "master" for Production Releases ##
SCRIPT_BRANCH="dev"
Expand Down Expand Up @@ -4918,13 +4918,14 @@ _GetLatestFWUpdateVersionFromWebsite_()
}

##------------------------------------------##
## Modified by ExtremeFiretop [2024-May-05] ##
## Modified by ExtremeFiretop [2025-Jun-28] ##
##------------------------------------------##
_GetLatestFWUpdateVersionFromGitHub_()
{
local routerVersion
local routerVersion search_type
local gitURL="$1" # GitHub URL for the latest release #
local firmware_type="$2" # "tuf", "rog" or "pure" #
local grep_pattern downloadURLs theURL urlVersion

local search_type="$firmware_type" # Default to the input firmware_type #

Expand All @@ -4934,6 +4935,12 @@ _GetLatestFWUpdateVersionFromGitHub_()
search_type="pure\|squashfs\|ubi"
fi

case "$gitURL" in
*/releases/latest) gitURL="${gitURL%/latest}?per_page=5" ;;
*/releases) gitURL="${gitURL}?per_page=5" ;;
esac

# Get current router version & product ID #
if ! "$offlineUpdateTrigger"
then
routerVersion="$(_GetLatestFWUpdateVersionFromRouter_)"
Expand All @@ -4946,38 +4953,40 @@ _GetLatestFWUpdateVersionFromGitHub_()
return 1
fi

# Fetch the latest release data from GitHub #
local release_data="$(curl -s "$gitURL")"

# Construct the grep pattern based on search_type #
local grep_pattern="\"browser_download_url\": \".*${PRODUCT_ID}.*\(${search_type}\).*\.\(w\|pkgtb\)\""
grep_pattern="\"browser_download_url\": \".*${PRODUCT_ID}.*\\(${search_type}\\).*\\.\(w\\|pkgtb\)\""

# Extract all matched download URLs #
local downloadURLs="$(echo "$release_data" | \
grep -o "$grep_pattern" | \
grep -o "https://[^ ]*\.\(w\|pkgtb\)")"
downloadURLs="$(curl -s "$gitURL" \
| grep -o "$grep_pattern" \
| grep -o 'https://[^"]*.\(w\|pkgtb\)')"

if [ -z "$downloadURLs" ]
then
echo "**ERROR** **NO_GITHUB_URL**"
return 1
else
local theURL urlVersion
for theURL in $downloadURLs
do
# Extract the version portion from the URL #
urlVersion="$(echo "$theURL" \
| grep -oE "${PRODUCT_ID}_[^ ]*\.(w|pkgtb)" \
| sed "s/${PRODUCT_ID}_//;s/.w$//;s/.pkgtb$//;s/.ubi$//;s/_/./g;s/-gnuton[0-9][0-9]*\$//" | head -n1)"

if [ "$urlVersion" = "$routerVersion" ]
then
echo "$urlVersion"
echo "$theURL"
return 0
fi
| grep -oE "${PRODUCT_ID}_[^/]*\.(w|pkgtb)" \
| sed -e "s/${PRODUCT_ID}_//" \
-e "s/\.w$//" -e "s/\.pkgtb$//" \
-e "s/_ubi$//" -e "s/_puresqubi$//" -e "s/_nand_squashfs$//" \
-e 's/_/./' -e 's/_/./' \
-e "s/-gnuton[0-9][0-9]*\$//" | head -n1)"

case "$urlVersion" in
*"$routerVersion"*)
echo "$urlVersion"
echo "$theURL"
return 0
;;
esac
done
fi
return 1
}

##------------------------------------------##
Expand Down Expand Up @@ -8224,27 +8233,39 @@ _EntwareServicesHandler_()
}

##------------------------------------------##
## Modified by ExtremeFiretop [2024-Nov-15] ##
## Modified by ExtremeFiretop [2025-Jun-28] ##
##------------------------------------------##
_GetOfflineFirmwareVersion_()
{
local zip_file="$1"
local extract_version_regex='[0-9]+_[0-9]+\.[0-9]+_[0-9a-zA-Z]+'
local validate_version_regex='[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(_[0-9a-zA-Z]+)?'
local extract_version_regex='[0-9]+_[0-9]+\.[0-9]+_[0-9a-zA-Z]+(-gnuton[0-9a-zA-Z_]+)?'
local validate_version_regex='[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+([_-][0-9a-zA-Z_]+)?'
local fwVersionFormat firmware_version formatted_version

# Extract the version number using regex #
firmware_version="$(echo "$zip_file" | grep -oE "$extract_version_regex")"
firmware_version="${firmware_version%_ubi*}"

if [ -n "$firmware_version" ]
then
if echo "$firmware_version" | grep -qE '^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+)$'
then
# Numeric patch version
# Numeric patch (Merlin)
formatted_version="$(echo "$firmware_version" | sed -E 's/^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+)/\1.\2.\3.\4/')"

elif echo "$firmware_version" | grep -qE '^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+)-gnuton[0-9]+$'
then
# Stable Gnuton build – drop the “-gnutonN” tail
formatted_version="$(echo "$firmware_version" | sed -E 's/^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+)-gnuton[0-9]+$/\1.\2.\3.\4/')"

elif echo "$firmware_version" | grep -qE '^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+-gnuton[0-9]+_(alpha|beta)[0-9a-zA-Z]*)$'
then
# Gnuton beta/alpha – keep the “-gnuton…_beta/alpha” suffix
formatted_version="$(echo "$firmware_version" | sed -E 's/^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9]+-gnuton[0-9]+_[a-zA-Z]+[0-9a-zA-Z]*)/\1.\2.\3.\4/')"

elif echo "$firmware_version" | grep -qE '^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9a-zA-Z]+)$'
then
# Alphanumeric suffix
# Alphanumeric suffix (Merlin “_beta3”, “_alpha1”, etc.)
formatted_version="$(echo "$firmware_version" | sed -E 's/^([0-9]+)_([0-9]+)\.([0-9]+)_([0-9a-zA-Z]+)/\1.\2.\3.0_\4/')"
else
printf "\nFailed to parse firmware version from the ZIP file name.\n"
Expand Down Expand Up @@ -8274,7 +8295,12 @@ _GetOfflineFirmwareVersion_()
printf "\nFailed to identify firmware version from the ZIP file name."
fi
printf "\nPlease enter the firmware version number in the format ${fwVersionFormat}\n"
printf "\n(Examples: 3004.388.8.0 or 3004.388.8.0_beta1). Enter 'e' to exit: "
if "$isGNUtonFW"
then
printf "\n(Examples: 3004.388.8.0 or 3004.388.8.0-gnuton0_beta3). Enter 'e' to exit: "
else
printf "\n(Examples: 3004.388.8.0 or 3004.388.8.0_beta1). Enter 'e' to exit: "
fi
read -r formatted_version

# Validate user input #
Expand All @@ -8285,7 +8311,12 @@ _GetOfflineFirmwareVersion_()
fi
printf "\n${REDct}**WARNING**${NOct} Invalid format detected!\n"
printf "\nPlease enter the firmware version number in the format ${fwVersionFormat}\n"
printf "\n(i.e 3004.388.8.0 or 3004.388.8.0_beta1). Enter 'e' to exit: "
if "$isGNUtonFW"
then
printf "\n(Examples: 3004.388.8.0 or 3004.388.8.0-gnuton0_beta3). Enter 'e' to exit: "
else
printf "\n(Examples: 3004.388.8.0 or 3004.388.8.0_beta1). Enter 'e' to exit: "
fi
read -r formatted_version
done
printf "\nThe user-provided firmware version: ${GRNct}$formatted_version${NOct}\n"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MerlinAU - AsusWRT-Merlin Firmware Auto Updater
## v1.4.9
## 2025-Jun-19
## v1.5.0
## 2025-Jun-28

## WebUI:
![image](https://github.com/user-attachments/assets/9c1dff99-9c13-491b-a7fa-aff924d5f02e)
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.9
1.5.0
Loading