From fc1e822d4998de3a0d738fb5067f969045c739b2 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Tue, 20 Oct 2026 01:14:28 +0000 Subject: [PATCH] install.sh: resolve the latest release without the rate-limited API tron upgrade died with 'curl: (22) ... 403' once an IP passed GitHub's 60 unauthenticated API requests an hour. Fall back to the tag the releases/latest page redirects to, which is not limited that way. Co-Authored-By: Claude Opus 5.5 --- apps/web/public/install.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/web/public/install.sh b/apps/web/public/install.sh index 4aaf608..b401541 100755 --- a/apps/web/public/install.sh +++ b/apps/web/public/install.sh @@ -51,8 +51,23 @@ fetch() { # url dest } latest_tag() { - fetch "https://api.github.com/repos/$REPO/releases/latest" /tmp/tb_rel.json - sed -n 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p' /tmp/tb_rel.json | head -n1 + # The API allows 60 unauthenticated requests an hour per IP and answers 403 + # past that, which a shared or busy address reaches easily. The web page's + # releases/latest redirect is not rate-limited that way, so fall back to + # reading the tag from where it lands. + _tag="" + if fetch "https://api.github.com/repos/$REPO/releases/latest" /tmp/tb_rel.json 2>/dev/null; then + _tag="$(sed -n 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/p' /tmp/tb_rel.json | head -n1)" + fi + if [ -z "$_tag" ]; then + _page="https://github.com/$REPO/releases/latest" + if command -v curl >/dev/null 2>&1; then + _tag="$(curl -fsSIL -o /dev/null -w '%{url_effective}' "$_page" 2>/dev/null | sed -n 's#.*/releases/tag/##p')" + elif command -v wget >/dev/null 2>&1; then + _tag="$(wget -S --spider --max-redirect=0 "$_page" 2>&1 | sed -n 's#^ *Location: .*/releases/tag/\([^[:space:]]*\).*#\1#p' | head -n1)" + fi + fi + printf '%s\n' "$_tag" } # Writes the `tron` management CLI to $PREFIX/bin/tron.