cargo-packager-updater 0.2.0

Rust executable updater.
Documentation
# cargo-packager-updater

Updater for apps that was packaged by [`cargo-packager`](https://docs.rs/cargo-packager).

## Checking for an update

you can check for an update using [`check_update`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/fn.check_update.html) function or construct a new [`Updater`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/struct.Updater.html)
using [`UpdaterBuilder`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/struct.UpdaterBuilder.html), both methods require the current version of the app and
a [`Config`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/struct.Config.html) that specifies the endpoints to request updates from and the public key of the update signature.

```rs
use cargo_packager_updater::{check_update, Config};

let config = Config {
  endpoints: vec!["http://myserver.com/updates".parse().unwrap()],
  pubkey: "<pubkey here>".into(),
  ..Default::default()
};
if let Some(update) = check_update("0.1.0".parse().unwrap(), config).expect("failed while checking for update") {
  update.download_and_install().expect("failed to download and install update");
} else {
  // there is no updates
}

```

## Endpoints

Each endpoint optionally could have `{{arch}}`, `{{target}}` or `{{current_version}}`
which will be detected and replaced with the appropriate value 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}}"
```

will turn into

```
 "https://releases.myapp.com/windows/x86_64/0.1.0"
```

if you need more data, you can set additional request headers [`UpdaterBuilder::header`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/struct.UpdaterBuilder.html#method.header) to your liking.

## Endpoint Response

The updater expects the endpoint to respond with 2 possible reponses:

1.  [`204 No Content`]https://datatracker.ietf.org/doc/html/rfc2616#section-10.2.5 in case there is no updates available.
2.  [`200 OK`]https://datatracker.ietf.org/doc/html/rfc2616#section-10.2.1 and a JSON response that could be either a JSON representing all available platform updates
    or if using endpoints variables (see above) or a header to attach the current updater target,
    then it can just return information for the requested target.

The JSON response is expected to have these fields set:

- `version`: must be a valid semver, with or without a leading `v``, meaning that both `1.0.0`and`v1.0.0`are valid.
- `url`or`platforms.[target].url`: must be a valid url to the update bundle.
- `signature`or`platforms.[target].signature`: must be the content of the generated `.sig`file. The signature may change each time you run build your app so make sure to always update it.
- `format`or`platforms.[target].format`: must be one of `app`, `appimage`, `nsis`or`wix`.

> [!NOTE]
> if using `platforms` object, each key is in the `OS-ARCH` format, where `OS` is one of `linux`, `macos` or `windows`, and `ARCH` is one of `x86_64`, `aarch64`, `i686` or `armv7`, see the example below.

It can also contain these optional fields:

- `notes`: Here you can add notes about the update, like release notes.
- `pub_date`: must be formatted according to [RFC 3339]https://datatracker.ietf.org/doc/html/rfc3339#section-5.8 if present.

Here is an example of the two expected JSON formats:

- **JSON for all platforms**

  ```json
  {
    "version": "v1.0.0",
    "notes": "Test version",
    "pub_date": "2020-06-22T19:25:57Z",
    "platforms": {
      "darwin-x86_64": {
        "signature": "Content of app.tar.gz.sig",
        "url": "https://github.com/username/reponame/releases/download/v1.0.0/app-x86_64.app.tar.gz",
        "format": "app"
      },
      "darwin-aarch64": {
        "signature": "Content of app.tar.gz.sig",
        "url": "https://github.com/username/reponame/releases/download/v1.0.0/app-aarch64.app.tar.gz",
        "format": "app"
      },
      "linux-x86_64": {
        "signature": "Content of app.AppImage.sig",
        "url": "https://github.com/username/reponame/releases/download/v1.0.0/app-amd64.AppImage.tar.gz",
        "format": "appimage"
      },
      "windows-x86_64": {
        "signature": "Content of app-setup.exe.sig or app.msi.sig, depending on the chosen format",
        "url": "https://github.com/username/reponame/releases/download/v1.0.0/app-x64-setup.nsis.zip",
        "format": "nsis or wix depending on the chosen format"
      }
    }
  }
  ```

- **JSON for one platform**

  ```json
  {
    "version": "0.2.0",
    "pub_date": "2020-09-18T12:29:53+01:00",
    "url": "https://mycompany.example.com/myapp/releases/myrelease.tar.gz",
    "signature": "Content of the relevant .sig file",
    "format": "app or nsis or wix or appimage depending on the release target and the chosen format",
    "notes": "These are some release notes"
  }
  ```

## Update install mode on Windows

You can specify which install mode to use on Windows using [`WindowsConfig::install_mode`](https://docs.rs/cargo-packager-updater/latest/cargo_packager_updater/struct.WindowsConfig.html#structfield.install_mode) which can be on of:

- `"Passive"`: There will be a small window with a progress bar. The update will be installed without requiring any user interaction. Generally recommended and the default mode.
- `"BasicUi"`: There will be a basic user interface shown which requires user interaction to finish the installation.
- `"Quiet"`: There will be no progress feedback to the user. With this mode the installer cannot request admin privileges by itself so it only works in user-wide installations or when your app itself already runs with admin privileges. Generally not recommended.

## Licenses

MIT or MIT/Apache 2.0 where applicable.