updater

package
v1.92.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2024 License: Apache-2.0 Imports: 33 Imported by: 0

README

Updater

This package implements an updater in Golang that automatically updates binaries.

Usage

There's a few different ways to use the updater. Our best integration is with the urfave/cli framework, which is a very popular framework for writing command line applications.

urfave/cli integration

To use this, simply take your existing cli.App and create a new one with the NewUpdater function.

func main() {
  a := &cli.App{}

  // Note: If you're using logrus (highly recommended) you'll also want to do
  // updater.WithLogger(log)
	if _, err := updater.UseUpdater(ctx, updater.WithApp(a)); err != nil {
    // Do something better than panic ;)
		panic(err)
	}
}

This will automatically update your application if there's an update available, as well as expose commands on the updater sub-command, such as:

  • updater set-channel <channel> - set the current channel (release channel) this application is using
  • updater get-channels - list all available release channels for the current application
  • updater use <version> - replaces the current binary with a specific version of the application
  • updater rollback - rollback to the previous version of the application used before the last update
  • updater status - get information on the updater
Other Places

You can use the updater.UseUpdater function in other places as well, but you will not get the tooling provided by the urfave/cli framework version (such as the ability to set the current release channel).

Example:

func main() {
  updated, err := updater.UseUpdater(context.Background())
  if err != nil {
    panic(err)
  }

  if updated {
    // tell user to restart their application
    fmt.Println("Updated. Please restart your application")
  }
}

How the Updater Works / Requirements

The updater works by reading version information out of the current binary and using git tags on the remote repository to source release versions / channels. The only hard requirement, at a minimum, of the updater is that the binary must use the pkg/app package as well as use semantic versioning.

The updater derives the current version and release channel from a version string. The version string comes from normal semantic versioning, e.g. v1.0.0 -> 1.0.0. A channel comes from the pre-release field of a semantic-version, e.g. v1.0.0-alpha.1 -> alpha. If there is no pre-release field, the channel is stable.

Mutable Tags

Another concept supported by the updater is a concept called "mutable tags", this allows you to release code with binaries while not increase the version number. This is useful for HEAD based development where you don't want to release a new version every time you make a change, but you do want it to still be testable.

For example, and this is how Outreach does CLI tooling releasing, you could use mutable tags to create a flow like this:

  • Merges into main go to unstable
  • Merges into rc branch go to rc
  • Merges into release go to stable

This would be done by doing the following via CI:

  • main: Create a Github Release (or tag) named unstable on the latest commit
  • rc: Force-push rc with the contents of main, then create a Github Release (or tag) with a rc pre-release version (v1.0.0-rc.1 for example)
  • release: Force-push release with the contents of rc, then create a Github Release (or tag) without a pre-release version (v1.0.0 for example)

The updater would then consider the list of channels to be stable, unstable, and rc respectively

Note: This doesn't cover uploading release binaries to CI, which is also something you'd need to do. The updater supports the following archive types: .tar .tar.gz .tar.xz .tar.bz2 .zip. The name must be of a certain format, which is documented in updater_test.go (Test_generatePossibleAssetNames) and must contain the binary with the same name as the current executable.

Documentation

Overview

Description: Provides miscellaneous helpers for the updater

Package updater implements an updater for CLIs that support multiple channels and version checks

Index

Constants

This section is empty.

Variables

View Source
var (
	// ConfigVersion is the current version of the configuration schema.
	ConfigVersion = 1

	// ConfigFile is the non-HOME containing path to the config file for the updater
	ConfigFile = filepath.Join(".outreach", ".config", "updater", "config.yaml")
)

This block contains constants for the updater's configuration and cache files.

View Source
var Disabled = "false"

Disabled globally disables the automatic updater. This is helpful for when using an external package manager, such as brew. This should usually be done with an ldflag:

go run -ldflags "-X github.com/getoutreach/gobox/pkg/cli/updater.Disabled=true" ...

or you can do it in main() before UseUpdater is called:

updater.Disabled = "true"

Any value other than "true" is considered false. The type is string to allow for invoking via `go run -ldflags "-X ..."`.

View Source
var UpdaterFlags = []cli.Flag{
	&cli.BoolFlag{
		Name:  "skip-update",
		Usage: "skips the updater check",
	},
	&cli.BoolFlag{
		Name:  "force-update-check",
		Usage: "Force checking for an update",
	},
}

The urfave flags the updater will inject.

Functions

func UseUpdater

func UseUpdater(ctx context.Context, opts ...Option) (*updater, error)

UseUpdater creates an automatic updater.

Types

type Option

type Option func(*updater)

Options configures an updater

func WithApp

func WithApp(app *cli.App) Option

WithApp sets the cli.App to setup commands on.

func WithChannel

func WithChannel(channel string) Option

WithChannel sets the channel to use for checking for updates

func WithCheckInterval

func WithCheckInterval(interval time.Duration) Option

WithCheckInterval sets the interval to check for updates. Defaults to 30 minutes.

func WithDisabled

func WithDisabled(disabled bool) Option

WithDisabled sets if we should disable the updater or not

func WithExecutableName

func WithExecutableName(execName string) Option

WithExecutableName overrides the name of the executable. See u.executablePath. Deprecated: Use WithExecutablePath

func WithExecutablePath added in v1.53.2

func WithExecutablePath(execPath string) Option

WithExecutablePath overrides the path of the executable. See u.executablePath.

func WithForceCheck

func WithForceCheck(forceCheck bool) Option

WithForceCheck sets whether or not to force the updater to check for updates otherwise updates are checked for only if the last check was more than the update check interval.

func WithLogger

func WithLogger(logger logrus.FieldLogger) Option

WithLogger sets the logger to use for logging. If not set a io.Discard logger is created.

func WithNoProgressBar

func WithNoProgressBar(noProgressBar bool) Option

WithNoProgressBar sets whether or not to show the progress bar.

func WithPrereleases deprecated

func WithPrereleases(_ bool) Option

Deprecated: Set the channel via the WithChannel option. WithPrereleases sets whether or not to include prereleases in the update check.

func WithRepoURL

func WithRepoURL(repo string) Option

WithRepoURL sets the repository to use for checking for updates. The expected format is: https://<host>/<repo> Note: It should not contain .git at the end

func WithSkipInstall

func WithSkipInstall(skipInstall bool) Option

WithSkipInstall sets whether or not to skip the installation of the update

func WithSkipMajorVersionPrompt

func WithSkipMajorVersionPrompt(skip bool) Option

WithSkipMajorVersionPrompt sets whether or not to skip the prompt for major version upgrades

func WithVersion

func WithVersion(version string) Option

WithVersion sets the version to use as the current version when checking for updates. Defaults to app.Info().Version.

Directories

Path Synopsis
Package archive contains methods for extracting file(s) from arbitrary archive types.
Package archive contains methods for extracting file(s) from arbitrary archive types.
Package release contains methods that interact with releases from VCS providers that do not exist natively in git.
Package release contains methods that interact with releases from VCS providers that do not exist natively in git.
Package resolver contains a git tag aware version resolver that supports channels to determine the latest version.
Package resolver contains a git tag aware version resolver that supports channels to determine the latest version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL