mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-13 15:46:22 +00:00
* feat: add browseros-cli self-updater * fix: address review comments for 0327-cli_self_updater * fix: address PR review comments for 0327-cli_self_updater * fix: replace goreleaser with Makefile-based release build Remove .goreleaser.yml (required Pro license for monorepo field) and consolidate cross-compilation into `make release`. CI now uses the same Makefile target, fixing a bug where POSTHOG_API_KEY was missing from release ldflags. * fix: address critical self-updater bugs from code review - Fix SHA256 checksum mismatch: verify archive checksum before extraction instead of verifying extracted binary against archive hash (was always failing). Add VerifyChecksum() and integration test. - Fix JSON field name mismatch: TypeScript was emitting camelCase (publishedAt, archiveFormat) but Go expected snake_case (published_at, archive_format). Manifest parsing was silently broken. - Add decompression size limit (256 MB) to prevent zip/gzip bombs. - Don't update LastCheckedAt on transient errors so retry happens on next CLI invocation instead of waiting 24h.
55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
package update
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLoadStateMissing(t *testing.T) {
|
|
configRoot := t.TempDir()
|
|
t.Setenv("XDG_CONFIG_HOME", configRoot)
|
|
|
|
state, err := LoadState()
|
|
if err != nil {
|
|
t.Fatalf("LoadState() error = %v", err)
|
|
}
|
|
if state == nil {
|
|
t.Fatal("LoadState() returned nil state")
|
|
}
|
|
}
|
|
|
|
func TestSaveStateRoundTrip(t *testing.T) {
|
|
configRoot := t.TempDir()
|
|
t.Setenv("XDG_CONFIG_HOME", configRoot)
|
|
|
|
want := &State{
|
|
LastCheckedAt: time.Unix(100, 0).UTC(),
|
|
LatestVersion: "1.2.3",
|
|
LatestPublishedAt: "2026-03-27T19:00:00Z",
|
|
AssetURL: "https://cdn.example.com/cli/v1.2.3/browseros-cli.tar.gz",
|
|
}
|
|
if err := SaveState(want); err != nil {
|
|
t.Fatalf("SaveState() error = %v", err)
|
|
}
|
|
|
|
got, err := LoadState()
|
|
if err != nil {
|
|
t.Fatalf("LoadState() error = %v", err)
|
|
}
|
|
if got.LatestVersion != want.LatestVersion {
|
|
t.Fatalf("LatestVersion = %q, want %q", got.LatestVersion, want.LatestVersion)
|
|
}
|
|
if StatePath() != filepath.Join(configRoot, "browseros-cli", "update-state.json") {
|
|
t.Fatalf("StatePath() = %q", StatePath())
|
|
}
|
|
}
|
|
|
|
func TestStateIsStale(t *testing.T) {
|
|
now := time.Unix(200, 0).UTC()
|
|
state := &State{LastCheckedAt: time.Unix(0, 0).UTC()}
|
|
if !state.IsStale(now, time.Minute) {
|
|
t.Fatal("IsStale() = false, want true")
|
|
}
|
|
}
|