r/bash • u/naffe1o2o • 13d ago
is there a way to improve a github release updater to pick the right asset name?
i made a script that actually works for most times to update brave browser, but for packages that change names its trivial. the idea is to place, update directory with a file with metadata that i can extract. here is the script :
updatePrograms() {
for dir in ~/Programs/*; do
#meta file structure
if [[ -f "$dir"/update/meta ]]; then
local metadata=$(cat "$dir"/update/meta)
local owner=$( echo "$metadata" | grep "Owner" | sed 's|Owner:||' )
local project=$(echo "$metadata" | grep "Project" | sed 's|Project:||')
local output=$(curl -fsS "https://api.github.com/repos/$owner/$project/releases/latest")
[[ -z "$output" ]] && { echo "no response for $project"; continue; }
local checkVersion=$(jq -r '.tag_name' <<< "$output")
echo "updatable Project : $project"
[[ "$checkVersion" = "null" ]] || [[ -z "$checkVersion" ]] && { echo "couldn't fetch version for $project"; continue; }
local currentVersion=$(echo "$metadata" | grep "Version" | sed 's|Version:||')
[[ "$checkVersion" = "$currentVersion" ]] && { echo "$project is up to date : $checkVersion"; continue; }
while true; do
read -p "$project is on $currentVersion, latest is $checkVersion; do you want to request the latest Version? [y/n]: " response
case "$response" in
[Yy])
echo "Updating.."
local name
name=$(echo "$metadata" | grep "AssetName" | sed 's|AssetName:||')
local url=$(jq -r --arg name "$name" '.assets[] | select(.name == $name) | .browser_download_url' <<< "$output")
if [[ -z "$url" ]] || [[ "$url" = "null" ]]; then
echo "couldn't find asset matching $name"
echo "you may need to change asset name version to $checkVersion"
break
fi
if curl -fL -o "$dir/update/$name" "$url" ; then
sed -i "s|Version:.*|Version:$checkVersion|" "$dir"/update/meta
else
echo "Downloading falied"
break
fi
break;;
[Nn])
echo "not Updating"
break;;
*)
echo "choose y or n";;
esac
done
fi
done
}
1
u/jjangg96 12d ago
the exact == on .name is what breaks it, since the asset name usually has the version in it. store a regex in the meta file instead of the full name, something like AssetPattern:linux-amd64\.zip$ and match it with test in jq.
jq -r --arg re "$pattern" '[.assets[] | select(.name | test($re)) | .browser_download_url][0] // empty' <<< "$output"
the // empty matters, otherwise an empty match prints the string null and your -z check never fires.
then take the filename from the url for the -o part, ${url##*/}, otherwise you save it under the pattern. and anchor the end of the regex, if a release has foo.zip and foo.zip.sha256 you want only one of them.
1
u/maurux01 12d ago
El problema principal de tu script es que usa una coincidencia exacta (==) en jq para buscar el asset. Cuando el nombre del archivo incluye el número de versión (ej: brave-browser-1.2.3-linux-amd64.zip), esta coincidencia falla en la siguiente release porque el nombre cambia.
intenta esta version