vegaprotocol / vegawallet-desktop

Desktop application for Vega Protocol's wallet
MIT License
15 stars 12 forks source link

SPIKE: Spot updated version and download it #590

Closed ValentinTrinque closed 1 year ago

ValentinTrinque commented 1 year ago

As a user I want to be able to update the software, When there is a new update that matches the network I am connected to, And this without having to browse the GitHub release page.

Hopefully, it will replace my current version, and relaunch the app when ready.

Notes

Technical implications

References

wwestgarth commented 1 year ago

Autoself updating the binaries

I think this is a solved problem. There is a discussion about this on the Wails repo and support for it is in their roadmap, but its not deemed important because its possible to it without any changes to wails: https://github.com/wailsapp/wails/issues/1178#issuecomment-1368282024

Riftshare, which is mentioned as an example, is a wails based application that is open source and has a self-update mechanism: https://github.com/achhabra2/riftshare

It uses this go-package which wraps up checking for releases on GitHub, downloading them replaces the running binary: https://github.com/minio/selfupdate

The interesting bit in riftshare is here: https://github.com/achhabra2/riftshare/blob/main/internal/update/selfupdate.go

The selfupdate package doesn’t work for macOS application but luckily riftshare has a workaround for that already: https://github.com/achhabra2/riftshare/blob/main/internal/update/selfupdate.go#L34

So we can leverage a lot of this. The main difference for us will be the CheckUpdate method because we will want to do more than just check for github releases.

Automatically restarting the application

Unfortunately riftshare gives us nothing on this and they just have a prompt that says "you can restart us now".

Digging around I found a package called “goagain” which seems sufficiently fancy, maybe even too fancy. It allows for a parent app to start a child application, where the child application can then kill the parent when it’s ready. The idea is that is allows for 0 downtime.

Do we need all of that? Probably not, as we only need to be able to start the desktop-wallet anew and instantly kill ourselves but we can still learn from the package and can take what we need from this function: https://github.com/rcrowley/goagain/blob/master/goagain.go#L77

The problem here is, again, it doesn't work for mac applications and only for launching binaries. Results from more googling into how to do it for Mac were sparse, and then were in relation to swift or apple-script and then still inconclusive.

I was able make something basic work by doing the below:

// start the App again with the replaced updated application
cmdPath, _ := os.Executable()
appPath := strings.TrimSuffix(cmdPath, "Contents/MacOS/BlahBlahBlah)
cmd := exec.Command("open", "-n", "-a", appPath)

// kill itself
log.Fatal("we killed ourselves")

And maybe that’s enough.