Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gitpod-cli] Add auto-updating capabilities #19056

Merged
merged 10 commits into from
Nov 13, 2023
Prev Previous commit
Next Next commit
Better update failure behavior
  • Loading branch information
csweichel committed Nov 10, 2023
commit 311b321880cb36c23eb0180def08d79397bf72a9
6 changes: 5 additions & 1 deletion components/local-app/pkg/selfupdate/selfupdate.go
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ func GenerateManifest(version *semver.Version, loc string, filenameParser Filena
func DownloadManifest(ctx context.Context, baseURL string) (res *Manifest, err error) {
defer func() {
if err != nil {
err = fmt.Errorf("download manifest from %s: %w", baseURL, err)
err = fmt.Errorf("download manifest from %s/manifest.json: %w", baseURL, err)
}
}()

@@ -121,6 +121,10 @@ func DownloadManifest(ctx context.Context, baseURL string) (res *Manifest, err e
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf(resp.Status)
}

var mf Manifest
err = json.NewDecoder(resp.Body).Decode(&mf)
if err != nil {
83 changes: 83 additions & 0 deletions components/local-app/pkg/selfupdate/selfupdate_test.go
Original file line number Diff line number Diff line change
@@ -84,6 +84,89 @@ func TestGenerateManifest(t *testing.T) {
}
}

func TestDownloadManifest(t *testing.T) {
marshal := func(mf *Manifest) []byte {
fc, err := json.Marshal(mf)
if err != nil {
t.Fatal(err)
}
return fc
}

type Expectation struct {
Error string
Manifest *Manifest
}
tests := []struct {
Name string
Expectation func(url string) Expectation
Manifest []byte
}{
{
Name: "happy path",
Manifest: marshal(&Manifest{
Version: semver.MustParse("0.2.0"),
Binaries: []Binary{
{
Filename: "gitpod-linux-amd64",
OS: "linux",
Arch: "amd64",
Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
},
},
}),
Expectation: func(url string) Expectation {
return Expectation{
Manifest: &Manifest{
Version: semver.MustParse("0.2.0"),
Binaries: []Binary{
{
URL: url + "/gitpod-linux-amd64",
Filename: "gitpod-linux-amd64",
OS: "linux",
Arch: "amd64",
Digest: "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
},
},
},
}
},
},
{
Name: "not found",
Expectation: func(url string) Expectation {
return Expectation{
Error: "download manifest from " + url + "/manifest.json: 404 Not Found",
}
},
},
}

for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
mux := http.NewServeMux()
if test.Manifest != nil {
mux.Handle("/manifest.json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(test.Manifest)
}))
}
srv := httptest.NewServer(mux)
t.Cleanup(func() { srv.Close() })

var act Expectation
res, err := DownloadManifest(context.Background(), srv.URL)
if err != nil {
act.Error = err.Error()
}
act.Manifest = res

if diff := cmp.Diff(test.Expectation(srv.URL), act); diff != "" {
t.Errorf("DownloadManifest() mismatch (-want +got):\n%s", diff)
}
})
}
}

func TestReplaceSelf(t *testing.T) {
type File struct {
OS string