feat(notifications): on update available (#352)

This commit is contained in:
Ludvig Lundgren 2022-07-12 14:47:08 +02:00 committed by GitHub
parent b4589243de
commit 2a3a839081
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 326 additions and 18 deletions

101
pkg/version/version.go Normal file
View file

@ -0,0 +1,101 @@
package version
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/autobrr/autobrr/pkg/errors"
goversion "github.com/hashicorp/go-version"
)
// Release is a GitHub release
type Release struct {
TagName string `json:"tag_name,omitempty"`
TargetCommitish *string `json:"target_commitish,omitempty"`
Name *string `json:"name,omitempty"`
Body *string `json:"body,omitempty"`
Draft *bool `json:"draft,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
}
func (r *Release) IsPreOrDraft() bool {
if *r.Draft || *r.Prerelease {
return true
}
return false
}
type Checker struct {
// user/repo-name or org/repo-name
Owner string
Repo string
}
func (c *Checker) get(ctx context.Context) (*Release, error) {
url := fmt.Sprintf("https://api.github.com/repos/%v/%v/releases/latest", c.Owner, c.Repo)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/vnd.github.v3+json")
client := http.DefaultClient
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error getting releases for %v: %s", c.Repo, resp.Status)
}
var release Release
dec := json.NewDecoder(resp.Body)
if err := dec.Decode(&release); err != nil {
return nil, err
}
return &release, nil
}
func (c *Checker) CheckNewVersion(ctx context.Context, version string) (bool, string, error) {
if version == "dev" {
return false, "", nil
}
release, err := c.get(ctx)
if err != nil {
return false, "", err
}
return c.checkNewVersion(version, release)
}
func (c *Checker) checkNewVersion(version string, release *Release) (bool, string, error) {
currentVersion, err := goversion.NewVersion(version)
if err != nil {
return false, "", errors.Wrap(err, "error parsing current version")
}
releaseVersion, err := goversion.NewVersion(release.TagName)
if err != nil {
return false, "", errors.Wrap(err, "error parsing release version")
}
if len(currentVersion.Prerelease()) == 0 && len(releaseVersion.Prerelease()) > 0 {
return false, "", nil
}
if releaseVersion.GreaterThan(currentVersion) {
// new update available
return true, releaseVersion.String(), nil
}
return false, "", nil
}

109
pkg/version/version_test.go Normal file
View file

@ -0,0 +1,109 @@
package version
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGitHubReleaseChecker_checkNewVersion(t *testing.T) {
type fields struct {
Repo string
}
type args struct {
version string
release *Release
}
tests := []struct {
name string
fields fields
args args
wantNew bool
wantVersion string
wantErr bool
}{
{
name: "outdated new available",
fields: fields{},
args: args{
version: "v0.2.0",
release: &Release{
TagName: "v0.3.0",
TargetCommitish: nil,
},
},
wantNew: true,
wantVersion: "0.3.0",
wantErr: false,
},
{
name: "same version",
fields: fields{},
args: args{
version: "v0.2.0",
release: &Release{
TagName: "v0.2.0",
TargetCommitish: nil,
},
},
wantNew: false,
wantVersion: "",
wantErr: false,
},
{
name: "no new version",
fields: fields{},
args: args{
version: "v0.3.0",
release: &Release{
TagName: "v0.2.0",
TargetCommitish: nil,
},
},
wantNew: false,
wantVersion: "",
wantErr: false,
},
{
name: "new rc available",
fields: fields{},
args: args{
version: "v0.3.0",
release: &Release{
TagName: "v0.3.0-rc1",
TargetCommitish: nil,
},
},
wantNew: false,
wantVersion: "",
wantErr: false,
},
{
name: "new rc available",
fields: fields{},
args: args{
version: "v0.3.0-RC1",
release: &Release{
TagName: "v0.3.0-RC2",
TargetCommitish: nil,
},
},
wantNew: true,
wantVersion: "0.3.0-RC2",
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := &Checker{
Repo: tt.fields.Repo,
}
got, gotVersion, err := g.checkNewVersion(tt.args.version, tt.args.release)
if tt.wantErr && assert.Error(t, err) {
assert.Equal(t, tt.wantErr, err)
}
assert.Equal(t, tt.wantNew, got)
assert.Equal(t, tt.wantVersion, gotVersion)
})
}
}