Skip to content

Auto-Updater

The Packager includes support for auto updates for Rust and Node.js applications by providing APIs for your application to securely update itself by fetching new releases on a remote server, installing updates and restarting itself.

Signing Keys

To securely deliver updates, the Packager signs your application generating a signature that is verified by the updater. To generate a new keypair, use the CLI signer generate command:

cargo packager signer generate

The command will prompt you for the keypair password. Do not lose that password, you will need to define it as the CARGO_PACKAGER_SIGN_PRIVATE_KEY_PASSWORD environment variable for the packager to sign your update packages.

After generating the keys, the CLI prints the private key and the public key. The private key must be defined as the CARGO_PACKAGER_SIGN_PRIVATE_KEY environment variable and must be treated as a secret, DO NOT share it, if it is compromised you will need to replace it immediately.

Along with the private key, the CLI also prints the public key that must be configured in the application to verify updates. The configuration object is documented later in this guide.

Rust

To configure the updater for your Rust application, add the cargo-packager-updater crate:

cargo add cargo-packager-updater

Start off by importing packager updater:

use cargo_packager_updater::{semver::Version, url::Url};

Create the updater configuration object, with the endpoint of the remote server hosting your app updates and your signing public key and use the cargo_packager_updater::check_update API to fetch an update if there is one:

let config = cargo_packager_updater::Config {
endpoints: vec![Url::parse("http://myserver.com/updates").expect("Failed to parse URL")],
pubkey: String::from("<pubkey here>"),
..Default::default()
};
let current_version =
Version::parse(env!("CARGO_PKG_VERSION")).expect("Failed to parse version");
println!("Current version: {}", current_version);
if let Some(update) = cargo_packager_updater::check_update(current_version.clone(), config)
.expect("Failed to check for update")
{
update
.download_and_install()
.expect("Failed to download and install update");
println!("Update installed")
} else {
println!("No update available")
}

Check out the complete configuration documentation.

Node.js

To configure the updater for your Node.js application, install the @crabnebula/updater package:

pnpm add @crabnebula/updater

Create the updater configuration object, with the endpoint of the remote server hosting your app updates and your signing public key:

const config = {
endpoints: ["http://myserver.com/updates"],
pubkey: "<pubkey here>",
};

Check out the complete configuration documentation.

Use the checkUpdate API to fetch an update if there is one:

import { checkUpdate } from "@crabnebula/updater";
// insert your config object here
const config = { ... };
// here you must use the current app version
// usually an environment variable that is injected in your app
// (framework-specific), check your framework documentation for ideas on how to do this
const currentVersion = "0.1.0";
const update = await checkUpdate(currentVersion, config);
if (update !== null) {
update.downloadAndInstall();
} else {
// there is no updates
}

Configuration

The updater configuration object allows you to define a list of endpoints to connect,

Endpoints

The endpoints required configuration is a list of URLs that are used to check if a new update is available. The endpoints are queried in order until a valid response is found (subsequent URLs are used as fallback in case the first one cannot be reached).

Each endpoint can use the {{arch}}, {{target}} or {{current_version}} variables which are detected and replaced with the appropriate values before making a request to the endpoint:

  • {{current_version}}: The version of the app that is requesting the update.
  • {{target}}: The operating system name (one of linux, windows or macos).
  • {{arch}}: The architecture of the machine (one of x86_64, i686, aarch64 or armv7).

for example https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}} can evaluate to https://releases.myapp.com/windows/x86_64/0.1.0.

Pubkey

The pubkey is a required configuration that defines the public key generated with the signer generate Packager CLI command. It is used to verify the authenticity of the update, ensuring it was built using your private key.

Windows

Under the windows object you can define the installerArgs, a list of string arguments that are given to the NSIS or WiX installers, and the installMode, an enum (one of basicUi, quiet and passive) which furthers configure the installer (defaults to passive, a mode that does not require the user to interact with the update installation).