Skip to content

Commit

Permalink
circleci learns update install to automate updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomorain committed Jul 31, 2018
1 parent e58a277 commit 5a9e599
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 43 deletions.
78 changes: 77 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@
[[constraint]]
name = "github.com/manifoldco/promptui"
version = "0.3.0"

[[constraint]]
name = "github.com/tj/go-update"
version = "2.2.1"

[[constraint]]
name = "github.com/blang/semver"
version = "3.5.1"

[[constraint]]
branch = "master"
name = "github.com/rhysd/go-github-selfupdate"
83 changes: 42 additions & 41 deletions cmd/update.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package cmd

import (
"encoding/json"
"io/ioutil"
"net/http"
"unicode/utf8"

"github.com/CircleCI-Public/circleci-cli/version"
"github.com/pkg/errors"
"github.com/rhysd/go-github-selfupdate/selfupdate"

"github.com/blang/semver"
"github.com/spf13/cobra"
)

Expand All @@ -22,62 +21,64 @@ func newUpdateCommand() *cobra.Command {
RunE: checkForUpdates,
})

update.AddCommand(&cobra.Command{
Use: "install",
Short: "Update the tool to the latest version",
RunE: installUpdate,
})

return update
}

func trimFirstRune(s string) string {
_, i := utf8.DecodeRuneInString(s)
return s[i:]
func checkForUpdates(cmd *cobra.Command, args []string) error {
return update(true)

}

func checkForUpdates(cmd *cobra.Command, args []string) error {
func installUpdate(cmd *cobra.Command, args []string) error {
return update(false)

url := "https://api.github.com/repos/CircleCI-Public/circleci-cli/releases/latest"
}

req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
func update(dryRun bool) error {
updater := selfupdate.DefaultUpdater()

req.Header.Set("User-Agent", version.UserAgent())
slug := "CircleCI-Public/circleci-cli"

client := http.Client{}
res, err := client.Do(req)
if err != nil {
return err
}
latest, found, err := updater.DetectLatest(slug)

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
return errors.Wrap(err, "error finding latest release")
}

var release struct {
// There are other fields in this response that we could use to download the
// binaries on behalf of the user.
// https://developer.github.com/v3/repos/releases/#get-the-latest-release
HTML string `json:"html_url"`
Tag string `json:"tag_name"`
Published string `json:"published_at"`
if !found {
return errors.New("no updates were found")
}

if err := json.Unmarshal(body, &release); err != nil {
return err
current := semver.MustParse(version.Version)

Logger.Debug("Latest version: %s", latest.Version)
Logger.Debug("Published: %s", latest.PublishedAt)
Logger.Debug("Current Version: %s", current)

if latest.Version.Equals(current) {
Logger.Info("Already up-to-date.")
return nil
}

latest := trimFirstRune(release.Tag)
if dryRun {
Logger.Infof("A new release is available (%s)", latest.Version)
Logger.Infof("You are running %s", current)
Logger.Infof("You can update with `circleci update install`")
return nil
}

Logger.Debug("Latest version: %s", latest)
Logger.Debug("Published: %s", release.Published)
Logger.Debug("Current Version: %s", version.Version)
release, err := updater.UpdateSelf(current, slug)

if latest == version.Version {
Logger.Info("Already up-to-date.")
} else {
Logger.Infof("A new release is available (%s)", release.Tag)
Logger.Infof("You are running %s", version.Version)
Logger.Infof("You can download it from %s", release.HTML)
if err != nil {
return errors.Wrap(err, "failed to install update")
}

Logger.Infof("Updated to %s", release.Version)
return nil
}
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
// These vars set by `goreleaser`:
var (
// Version is the current Git tag (the v prefix is stripped) or the name of the snapshot, if you’re using the --snapshot flag
Version = "local-dev-build"
Version = "0.0.0-dev"
// Commit is the current git commit SHA
Commit = "dirty-local-tree"
)
Expand Down

0 comments on commit 5a9e599

Please sign in to comment.