Skip to content

Commit ba326ff

Browse files
committed
fix: downgrade and upgrade, switch release track
1 parent 8f508f4 commit ba326ff

File tree

1 file changed

+64
-5
lines changed

1 file changed

+64
-5
lines changed

clientupdate/clientupdate_android.go

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"regexp"
1515
"runtime"
1616
"strings"
17+
18+
"tailscale.com/util/cmpver"
1719
)
1820

1921
const androidGitHubRepoURL = "https://api.github.com/repos/anasfanani/tailscale-magisk-build/releases"
@@ -31,17 +33,20 @@ func (up *Updater) updateAndroid() error {
3133
repoURL := androidGitHubRepoURL
3234
if up.Version != "" {
3335
repoURL = fmt.Sprintf(repoURL+"/tags/v%s-android", up.Version)
36+
} else if up.Track == UnstableTrack {
37+
// For unstable track, fetch all releases to get the latest (including pre-releases)
38+
repoURL = androidGitHubRepoURL
3439
} else {
35-
repoURL = fmt.Sprintf(repoURL + "/latest")
40+
repoURL = repoURL + "/latest"
3641
}
3742

3843
release, ver, err := fetchAndroidRelease(repoURL, up.Track)
3944
if err != nil {
4045
return err
4146
}
4247

43-
// Confirm the update with the user
44-
if !up.confirm(ver) {
48+
// Confirm the update with the user (allow downgrades when specific version is requested)
49+
if !confirmAndroidUpdate(up, ver) {
4550
return nil
4651
}
4752

@@ -69,6 +74,33 @@ func (up *Updater) updateAndroid() error {
6974
return nil
7075
}
7176

77+
// confirmAndroidUpdate confirms the update with the user, allowing downgrades when a specific version is requested
78+
func confirmAndroidUpdate(up *Updater, ver string) bool {
79+
// Allow downgrades when a specific version is requested
80+
if up.Version != "" {
81+
if up.Confirm != nil {
82+
return up.Confirm(ver)
83+
}
84+
return true
85+
}
86+
87+
// Only check version when we're not switching tracks.
88+
if up.Track == "" || up.Track == CurrentTrack {
89+
switch c := cmpver.Compare(up.currentVersion, ver); {
90+
case c == 0:
91+
up.Logf("already running %v version %v; no update needed", up.Track, ver)
92+
return false
93+
case c > 0:
94+
up.Logf("installed %v version %v is newer than the latest available version %v; no update needed", up.Track, up.currentVersion, ver)
95+
return false
96+
}
97+
}
98+
if up.Confirm != nil {
99+
return up.Confirm(ver)
100+
}
101+
return true
102+
}
103+
72104
// androidDirectories returns the download and extract directories for Android updates
73105
// downloadDir: uses TempDir, fallback to current working directory
74106
// extractDir: uses the directory of the current executable
@@ -135,8 +167,35 @@ func fetchAndroidRelease(repoURL, track string) (release struct {
135167
return release, "", fmt.Errorf("unexpected status code: %d", resp.StatusCode)
136168
}
137169

138-
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
139-
return release, "", fmt.Errorf("failed to decode release metadata: %w", err)
170+
// Check if we're fetching all releases (for unstable track)
171+
if strings.HasSuffix(repoURL, "/releases") {
172+
// Fetch all releases and find the latest one (including pre-releases)
173+
var releases []struct {
174+
TagName string `json:"tag_name"`
175+
Assets []struct {
176+
Name string `json:"name"`
177+
URL string `json:"browser_download_url"`
178+
} `json:"assets"`
179+
Prerelease bool `json:"prerelease"`
180+
}
181+
182+
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
183+
return release, "", fmt.Errorf("failed to decode releases metadata: %w", err)
184+
}
185+
186+
if len(releases) == 0 {
187+
return release, "", fmt.Errorf("no releases found")
188+
}
189+
190+
// Get the first release (latest)
191+
release.TagName = releases[0].TagName
192+
release.Assets = releases[0].Assets
193+
release.Prerelease = releases[0].Prerelease
194+
} else {
195+
// Single release (latest or specific tag)
196+
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
197+
return release, "", fmt.Errorf("failed to decode release metadata: %w", err)
198+
}
140199
}
141200

142201
// If fetching latest and it's a pre-release, skip it for stable track

0 commit comments

Comments
 (0)