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 usingupdater get-channels
- list all available release channels for the current applicationupdater use <version>
- replaces the current binary with a specific version of the applicationupdater rollback
- rollback to the previous version of the application used before the last updateupdater 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 tounstable
- Merges into
rc
branch go torc
- Merges into
release
go tostable
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 ofmain
, then create a Github Release (or tag) with arc
pre-release version (v1.0.0-rc.1
for example) - release: Force-push
release
with the contents ofrc
, 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 ¶
- Variables
- func UseUpdater(ctx context.Context, opts ...Option) (*updater, error)
- type Option
- func WithApp(app *cli.App) Option
- func WithChannel(channel string) Option
- func WithCheckInterval(interval time.Duration) Option
- func WithDisabled(disabled bool) Option
- func WithExecutableName(execName string) Option
- func WithExecutablePath(execPath string) Option
- func WithForceCheck(forceCheck bool) Option
- func WithLogger(logger logrus.FieldLogger) Option
- func WithNoProgressBar(noProgressBar bool) Option
- func WithPrereleases(prereleases bool) Optiondeprecated
- func WithRepoURL(repo string) Option
- func WithSkipInstall(skipInstall bool) Option
- func WithSkipMajorVersionPrompt(skip bool) Option
- func WithVersion(version string) Option
Constants ¶
This section is empty.
Variables ¶
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.
var Disabled bool
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.
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 ¶
Types ¶
type Option ¶
type Option func(*updater)
Options configures an updater
func WithChannel ¶
WithChannel sets the channel to use for checking for updates
func WithCheckInterval ¶
WithCheckInterval sets the interval to check for updates. Defaults to 30 minutes.
func WithDisabled ¶
WithDisabled sets if we should disable the updater or not
func WithExecutableName ¶
WithExecutableName overrides the name of the executable. See u.executablePath. Deprecated: Use WithExecutablePath
func WithExecutablePath ¶ added in v1.53.2
WithExecutablePath overrides the path of the executable. See u.executablePath.
func WithForceCheck ¶
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 ¶
WithNoProgressBar sets whether or not to show the progress bar.
func WithPrereleases
deprecated
func WithRepoURL ¶
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 ¶
WithSkipInstall sets whether or not to skip the installation of the update
func WithSkipMajorVersionPrompt ¶
WithSkipMajorVersionPrompt sets whether or not to skip the prompt for major version upgrades
func WithVersion ¶
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. |