fix: switch updater from packages API to releases API for version check
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m5s

Gitea's generic package list endpoint wasn't returning 200. Switched to
/api/v1/repos/{owner}/{repo}/releases/latest which is the standard
Gitea releases API. Download URLs still use the packages registry.
Repo is now public — no auth token needed for version checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell 2026-03-17 12:26:31 -04:00
parent 8b0289d133
commit 4af90bb80d

View File

@ -60,6 +60,11 @@ type giteaPackageVersion struct {
Version string `json:"version"` Version string `json:"version"`
} }
// giteaRelease is the subset of the Gitea releases API response we need.
type giteaRelease struct {
TagName string `json:"tag_name"`
}
// versionJSON is the schema of the version.json file in the package. // versionJSON is the schema of the version.json file in the package.
type versionJSON struct { type versionJSON struct {
Version string `json:"version"` Version string `json:"version"`
@ -75,9 +80,9 @@ func (u *UpdateService) CheckForUpdate() (*UpdateInfo, error) {
} }
// Fetch latest package version from the Gitea API. // Fetch latest package version from the Gitea API.
// Gitea package API — no /v1/ prefix // Use Gitea releases API to find the latest release tag
apiURL := fmt.Sprintf( apiURL := fmt.Sprintf(
"%s/api/packages/%s/generic/%s?limit=1&sort=created_at&direction=desc", "%s/api/v1/repos/%s/%s/releases/latest",
u.baseURL, u.owner, u.pkg, u.baseURL, u.owner, u.pkg,
) )
@ -88,42 +93,36 @@ func (u *UpdateService) CheckForUpdate() (*UpdateInfo, error) {
return nil, fmt.Errorf("build request: %w", err) return nil, fmt.Errorf("build request: %w", err)
} }
// Use GIT_TOKEN for private registries, if available.
if token := os.Getenv("GIT_TOKEN"); token != "" {
req.Header.Set("Authorization", "token "+token)
}
resp, err := u.httpClient.Do(req) resp, err := u.httpClient.Do(req)
if err != nil { if err != nil {
return nil, fmt.Errorf("fetch package versions: %w", err) return nil, fmt.Errorf("fetch latest release: %w", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, fmt.Errorf("read package API response: %w", err) return nil, fmt.Errorf("read release API response: %w", err)
} }
slog.Info("package API response", "status", resp.StatusCode, "body", string(body)[:min(len(body), 500)]) slog.Info("release API response", "status", resp.StatusCode, "body", string(body)[:min(len(body), 500)])
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status %d from package API: %s", resp.StatusCode, string(body)) return nil, fmt.Errorf("unexpected status %d from releases API: %s", resp.StatusCode, string(body))
} }
var versions []giteaPackageVersion var release giteaRelease
if err := json.Unmarshal(body, &versions); err != nil { if err := json.Unmarshal(body, &release); err != nil {
return nil, fmt.Errorf("decode package versions: %w", err) return nil, fmt.Errorf("decode release: %w", err)
} }
slog.Info("parsed versions", "count", len(versions), "currentVersion", u.currentVersion) if release.TagName == "" {
slog.Info("no releases found")
if len(versions) == 0 {
slog.Info("no package versions found")
return info, nil return info, nil
} }
latestVer := strings.TrimPrefix(versions[0].Version, "v") latestVer := strings.TrimPrefix(release.TagName, "v")
info.LatestVer = latestVer info.LatestVer = latestVer
slog.Info("latest release", "tag", release.TagName, "version", latestVer, "current", u.currentVersion)
cmp := CompareVersions(u.currentVersion, latestVer) cmp := CompareVersions(u.currentVersion, latestVer)
if cmp >= 0 { if cmp >= 0 {
@ -132,9 +131,10 @@ func (u *UpdateService) CheckForUpdate() (*UpdateInfo, error) {
} }
// Newer version is available — fetch version.json for SHA256 + download URL. // Newer version is available — fetch version.json for SHA256 + download URL.
tagVersion := release.TagName // e.g. "v0.6.0" or "0.6.0"
versionInfoURL := fmt.Sprintf( versionInfoURL := fmt.Sprintf(
"%s/api/packages/%s/generic/%s/%s/version.json", "%s/api/packages/%s/generic/%s/%s/version.json",
u.baseURL, u.owner, u.pkg, versions[0].Version, u.baseURL, u.owner, u.pkg, tagVersion,
) )
vInfo, err := u.fetchVersionJSON(versionInfoURL) vInfo, err := u.fetchVersionJSON(versionInfoURL)
@ -155,7 +155,7 @@ func (u *UpdateService) CheckForUpdate() (*UpdateInfo, error) {
if info.DownloadURL == "" { if info.DownloadURL == "" {
info.DownloadURL = fmt.Sprintf( info.DownloadURL = fmt.Sprintf(
"%s/api/packages/%s/generic/%s/%s/wraith-%s-setup.exe", "%s/api/packages/%s/generic/%s/%s/wraith-%s-setup.exe",
u.baseURL, u.owner, u.pkg, versions[0].Version, versions[0].Version, u.baseURL, u.owner, u.pkg, tagVersion, tagVersion,
) )
} }