Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(updater): Alpha version #643

Merged
merged 240 commits into from
Apr 5, 2021
Merged

feat(updater): Alpha version #643

merged 240 commits into from
Apr 5, 2021

Conversation

lemarier
Copy link
Member

@lemarier lemarier commented Jun 6, 2020

Hi guys!

I think I'm ready for the first round of reviews.

To understand how the updater work please refer to the README

This is an early Alpha version allowing us to test if it works. The sequence is not smooth as it should but it should works. It's been tested on mac, windows, and Linux (ubuntu)

Tests with built artifacts

Built on: Thu Mar 23 2021 at 9 AM EDT.

Windows

Download the MSI here -- Once installed launch, it and once you launch the app, you should get asked to update. It should launch a new MSI, follow step, relaunch app you should be updated (no more popup)

Mac

Download the latest app here -- Copy it inside /Applications, launch the app, you should be asked to update, follow step. Restart the app -- You shouldn't be prompted to update.

Linux

Download AppImage from here -- Launch the app, You should be prompted to update. Follow step. Restart should be done automatically. You should be updated to v2

Tests

Known bugs

  • mac -- once installed the app close but do not restart (not implemented yet)
  • mac -- app need to be added inside /Applications for the updater to work? Probably a packager (manifest) issue
  • win -- when MSI is launched, the app do not close (should be spawned)
  • win -- wix can't kill the process as it's not spawned so I guess wix is a child of tauri (force kill the process manually of tauri app) fixed it

Todo

  • Unit/Smoke tests
  • tauri.js (cli) integration for key generation
  • Better error handling
  • Cleanup
  • MacOS tests and fix
  • Windows tests and fix
  • Linux tests and fix
  • If the public key is provided inside tauri.conf.json, when installing an update we need a valid signature
  • KeyPair generation [bundler]
  • Executable signature for the update [bundler]
  • Archive generator (generate tar.gz & zip automatically on release)
  • Allow fallback URLs (if one URL failed or is down, we fallback to next update URL)
  • FIX: When extracting overwrite existing file only without deleting existing
  • Instead of bundling a zip & tar.gz, push AppImage, Wix (Installer) and mac tar.gz of the Application folder)
  • Consume the API via Tauri

Signed-off-by: David L <david@lemarier.ca>
@lemarier lemarier requested review from a team June 6, 2020 12:07
lemarier and others added 27 commits June 8, 2020 14:27
We can request confirmation to the user at different step.

Ther eis now 3 main step.
- check
- download -> DownloadedArchive
- install

Signed-off-by: David L <david@lemarier.ca>
Example we can send event like this:

Usefull for the progress bar and alert (message box)
```
New version available "0.0.2"
DOWNLOAD IN PROGRESS: 0%
DOWNLOAD IN PROGRESS: 1%
DOWNLOAD IN PROGRESS: 2%
[…]
DOWNLOAD IN PROGRESS: 99%
DOWNLOAD IN PROGRESS: 100%
Extracting IN PROGRESS
COPY IN PROGRESS
Installation sucess! Restart now
```

Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Keys and signature are base64 encoded so they can be added to the update manifest (public) and can be easilly added to ENV variable

Supported env variables:
`TAURI_KEY_PASSWORD` Secret key password

```
Sign executables for tauri updater.

USAGE:
    cargo tauri-sign-updates [OPTIONS]

OPTIONS:
    -f, --force                              Overwrite private key even if exist on the specified path
    -g, --generate-key                       Generate keypair to sign files
    -h, --help                               Prints help information
        --no-password                        Set empty password for your private key
    -P, --password <PASSWORD>                Set private key password when signing
        --private-key <STRING>               Load the private key from a string
    -p, --private-key-path <PATH>            Load the private key from a file
    -s, --sign <PATH>                        Sign the specified binary
    -w, --write-private-key <DESTINATION>    Write private key to a file
```

Signed-off-by: David L <david@lemarier.ca>
When running the -w flag (write) we also write the public key

`cargo run tauri-sign-updates -g -w ./test1.key -f`

```
Your keypair was generated successfully
Private: /Users/david/dev/tauri_updater/cli/tauri-bundler/test1.key (Keep it secret!)
Public: /Users/david/dev/tauri_updater/cli/tauri-bundler/test1.key.pub
```

Signed-off-by: David L <david@lemarier.ca>
Check in tauri.conf.json if pubkey is set.

Actually this is what an updater configuration may look:

```
"updater": {
        "active": true,
        "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEY1OTgxQzc0MjVGNjM0Q0IKUldUTE5QWWxkQnlZOWFBK21kekU4OGgzdStleEtkeStHaFR5NjEyRHovRnlUdzAwWGJxWEU2aGYK",
        "endpoints": [
          "http://badurl.www.tld/1",
          "https://gist.githubusercontent.com/lemarier/8e4703d077ebd6470810927ed2205470/raw/329b7ad9f32d439083af40e7f2090ca072d7a1cf/gistfile1.txt?target={{target}}&version={{current_version}}"
        ]
      }
```

TAURI_PRIVATE_KEY is read from environment variable.
It can be a Path or a String

TAURI_KEY_PASSWORD is also an environment variable who can be set (when we bundle) to set the private key password for sining.

If this is a wrong key pasword an error is thrown.

Signed-off-by: David L <david@lemarier.ca>
…ided

When we call `updater.install` a new field has been added. It allow to send the pubkey.

If the pubkey is sent, the updater will expect a `signature` field on the update server.

Example:
https://gist.githubusercontent.com/lemarier/72a2a488f1c87601d11ec44d6a7aff05/raw/f86018772318629b3f15dbb3d15679e7651e36f6/with_sign.json

BEFORE extracting we verify the archive and make sure the signature match. If it don’t the update is stopped.

Signed-off-by: David L <david@lemarier.ca>
Instead of simply rename the source to dest, we walk the source and replace elements in the dest. (Similar to cp -R in OSX/Linux)

It allow to extract our update archive recursively by overwriting what we want.

Signed-off-by: David L <david@lemarier.ca>
Now when we extract we keep previous files in the dest we sinmply overwrite with the files in the update archive.

There is a backup made if something failed the dest is restored from the untouched backup and return a failed error inside the updater.  You can prompt the user to download manually the new version by example.

Signed-off-by: David L <david@lemarier.ca>
Quick codebase cleanup in the updater and use thiserror for better matching with tauri codebase

Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Remove unwanted unwrap

Signed-off-by: David L <david@lemarier.ca>
It’s a complete test who make sure the whole process works fine.

We load the signature validator from the updater api as it use a light version of minisign and we need to make sure it’s compatible.

The test is creating the archive, sign it and make sure the signature is valid.

Maybe we can add more test for archive extraction test.

Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
As we skip the other regular process, we run cargo build in our test project so the executable is available and can be copied

Signed-off-by: David L <david@lemarier.ca>
Signed-off-by: David L <david@lemarier.ca>
@lemarier
Copy link
Member Author

lemarier commented Mar 24, 2021

I think I'm done. Need to update the latest build to test

Edit: Binary updated.
You can find them here: https://github.com/lemarier/tauri-test/releases/tag/v0.1.0 or in the PR description.
OSX and Windows are NOT signed so you can have some weird behavior. I suggest disabling all firewalls for the tests. We made tests with signed binary and everything worked as expected. Also, on OSX you'll need to cmd + click on the app to open it. And move it inside /Applications is a good suggestion to replicate the real environment.

Windows we are relaunching the MSI installation. I think it's OK for now. Maybe we could launch the MSI in silent and let it go. We could also generate specific MSI for the updater if needed. We could also only replace binary like we are doing in OSX/Linux but we should get stability in the updater first I think. Because we all know windows is specific and can drive weird errors. If we can isolate them it's better.

lemarier and others added 20 commits March 25, 2021 08:21
# Conflicts:
#	cli/core/Cargo.toml
#	cli/core/src/build/rust.rs
#	cli/tauri-bundler/src/bundle.rs
#	cli/tauri-bundler/src/bundle/dmg_bundle.rs
#	cli/tauri-bundler/src/bundle/settings.rs
#	cli/tauri.js/bin/tauri.js
#	cli/tauri.js/src/template/defaultConfig.ts
# Conflicts:
#	cli/core/Cargo.lock
#	cli/core/Cargo.toml
#	cli/tauri.js/bin/tauri.js
#	tauri/src/app.rs
# Conflicts:
#	cli/core/Cargo.lock
#	cli/tauri-bundler/src/bundle/dmg_bundle.rs
#	cli/tauri-bundler/src/bundle/settings.rs
#	cli/tauri-bundler/src/error.rs
@lucasfernog lucasfernog merged commit 6d70c8e into dev Apr 5, 2021
@lucasfernog lucasfernog deleted the feature/new_updater branch April 5, 2021 17:51
@HuakunShen
Copy link

Hello! @lemarier @nothingismagick

May I know where I can find this tauri-update-server and how to deploy it?

@HuakunShen
Copy link

OK, I found it https://github.com/lemarier/tauri-update-server

The documentation doesn't seem. to be up to date, some links are expired.

@lemarier
Copy link
Member Author

OK, I found it https://github.com/lemarier/tauri-update-server

The documentation doesn't seem. to be up to date, some links are expired.

Hi @HuakunShen,

These POCs may be a bit outdated, instead of darwin as platform, tauri now expect darwin-x86_64 by example.

You can use a static JSON as well and host it on amazon S3 by example or a gist and use the RAW

doc can be found here;
https://tauri.app/v1/guides/distribution/updater/#update-file-json-format

example can be found here;
https://gist.githubusercontent.com/lemarier/6bc28d06b94958d83eaa2790eef03f32/raw/d920848ad037af5c3781cef04bdb7fff6c23a9c3/static_update.json

If you want to implement you own update server, you can refer to this for the complete spec;
https://tauri.app/v1/guides/distribution/updater/#server-support

Hope this help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants