fix(upgrade): fetch releases from TorrentClaw app, not GitHub

The org GitHub shadow-ban 404s releases/raw/API to anonymous clients, so the
self-updater (api.github.com/releases/latest + github.com/.../releases/download)
was broken: `unarr upgrade` could neither check nor download.

- fetchLatestVersion → GET {base}/version (plain text)
- releaseURL → {base}/releases/download/v{ver}/{file}
- base resolves from cfg.Auth.APIURL via upgrade.SetBaseURL (PersistentPreRun),
  so mirrors / onion / staging / UNARR_API_URL all route updates correctly
- tests updated to the new endpoints
This commit is contained in:
Deivid Soto 2026-05-21 14:46:10 +02:00
parent 7de8955c4f
commit 0537de0ec1
5 changed files with 71 additions and 52 deletions

View file

@ -6,7 +6,6 @@ import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
@ -182,36 +181,35 @@ func verifyChecksumWithOptions(ctx context.Context, version, archivePath string,
return nil
}
// fetchLatestVersion queries GitHub API for the latest release tag.
// fetchLatestVersion queries the TorrentClaw release endpoint (/version) for the
// latest version string (e.g. "0.8.1"). No GitHub dependency.
func fetchLatestVersion(ctx context.Context) (string, error) {
url := fmt.Sprintf("https://api.github.com/repos/%s/releases/latest", githubRepo)
url := updateBaseURL + "/version"
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return "", err
}
req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("User-Agent", "unarr-updater")
resp, err := httpClient.Do(req)
if err != nil {
return "", fmt.Errorf("fetch latest release: %w", err)
return "", fmt.Errorf("fetch latest version: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("GitHub API: HTTP %d", resp.StatusCode)
return "", fmt.Errorf("version endpoint: HTTP %d", resp.StatusCode)
}
var release struct {
TagName string `json:"tag_name"`
}
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
return "", fmt.Errorf("decode response: %w", err)
body, err := io.ReadAll(io.LimitReader(resp.Body, 64))
if err != nil {
return "", fmt.Errorf("read version: %w", err)
}
if release.TagName == "" {
return "", fmt.Errorf("empty tag_name in release")
version := strings.TrimPrefix(strings.TrimSpace(string(body)), "v")
if version == "" {
return "", fmt.Errorf("empty version from %s", url)
}
return strings.TrimPrefix(release.TagName, "v"), nil
return version, nil
}