PolyMC icon indicating copy to clipboard operation
PolyMC copied to clipboard

Implement Windows Updater

Open d-513 opened this issue 3 years ago • 19 comments
trafficstars

Role

To update polymc

Suggestion

We should have a compile option like DLauncher_updater_enable which would add an update button which would download the latest platform build.

Benefit

Manually installed packages would be easier to update. Especially for non-techy pepole

This suggestion is unique

  • [X] I have searched the issue tracker and did not find an issue describing my suggestion, especially not one that has been rejected.

You may use the editor below to elaborate further.

Again, this should be optional and a compile flag. For packages that are in repositories, like the RPM Copr, Flathub package and probably soon others, they should use their update channels, not the button. This only for manually installed packages.

I think it would be fine to open a download like MMC does. Or AppImage/windows could automatically install the thing when the button is clicked

d-513 avatar Jan 13 '22 09:01 d-513

I agree this sounds like a great idea especially windows users.

ZekeZDev avatar Jan 13 '22 09:01 ZekeZDev

Traditionally MultiMC provided just a small bootstrapping script for linux that downloaded the entire client. The client then self updated depending on the user's needs. This is all very similar to how steam works or even tor-launcher. This did however have the possibility of breaking due to incompatibilities(lets for example assume Qt Incompatibilities) and packaging the libraries PolyMC needs is a bad idea. It would however be a neat options for those that can run the latest version with no issues.

svin24 avatar Jan 29 '22 09:01 svin24

Traditionally MultiMC provided just a small bootstrapping script for linux that downloaded the entire client. The client then self updated depending on the user's needs.

This is all very similar to how steam works or even tor-launcher.

This did however have the possibility of breaking due to incompatibilities(lets for example assume Qt Incompatibilities) and packaging the libraries PolyMC needs is a bad idea. It would however be a neat options for those that can run the latest version with no issues.

This is probably better for windows and Mac as on Linux you have an actual package manager

I can see it being useful for appimage users though

d-513 avatar Jan 29 '22 09:01 d-513

This would not really work for AppImage, as you'd have to replace the entire file. We literally have no clue where the user put the AppImage, so we have no way to replace it.

For lin-nodeps, generally, we're only replacing the binary, not the libraries. Same goes for Mac and Windows.

This also reminds me that we need to setup notifications. If there's an RCE that got released or an otherwise serious bug, we need to let users know ASAP. This can be done simply with a small RSS feed.

binex-dsk avatar Feb 04 '22 03:02 binex-dsk

You definitely could do it with appimages https://docs.appimage.org/packaging-guide/optional/updates.html Although honestly I feel like this is a stretch goal of some sorts

svin24 avatar Feb 04 '22 04:02 svin24

We should have a compile option like DLauncher_updater_enable which would add an update button which would download the latest platform build.

Do these build config options work for this, or is something else needed?

https://github.com/PolyMC/PolyMC/blob/fa870bc026b21aca7b3859cde8ba3f843a98e023/buildconfig/BuildConfig.h#L60-L75

https://github.com/PolyMC/PolyMC/blob/4899d3c4585d92ae46fcabf0a16695687bbce885/buildconfig/BuildConfig.cpp.in#L74-L76

If the updater is not needed, just don't set UPDATER_BASE.


It looks like upstream used a modified form of GoUpdate, and PolyMC still has that code: https://github.com/PolyMC/PolyMC/blob/develop/launcher/updater/GoUpdate.cpp

  1. UPDATER_BASE is set to some URL (e.g. https://example.com/update/).
  2. It gets channels from UPDATER_BASE/[platform]/channels.json (e.g. https://example.com/update/osx64-5.15.2/channels.json).
  3. Get versions within a channel from UPDATER_BASE/[platform]/[channel]/index.json (e.g. https://example.com/update/osx64-5.15.2/stable/index.json).
  4. Get information about the version from UPDATER_BASE/[platform]/[channel]/[version_id].json (e.g. https://example.com/update/osx64-5.15.2/stable/3246.json), which includes a URL/md5/other attributes for every file to download and replace

And it seems like they used this tool to manage their GoUpdate repo: https://github.com/MultiMC/repoman2 (I didn't try it or look much into it though, so I'm not entirely sure how to use it)

Not sure how this works for AppImage though.


Edit: did some experimentation with repoman, and looks like this is how you use it:

  1. Clone the repoman repo and pip install it
  2. Make a directory for your repo /path/to/repo, cd /path/to/repo
  3. Make a directory for files /path/to/repo/files
  4. Make a directory for each platform /path/to/repo/lin64, etc.
  5. Make a directory for each channel within each platform, /path/to/repo/lin64/stable, etc.
  6. repoman create /path/to/repo https://example.com/update/ /path/to/repo/files https://example.com/update/files/ to create the repo
  7. repoman add-platform [platform-name] to create the platforms (they must match the names of the directories you made)
  8. Whenever you release a new version, repoman push [platform] [channel] [vsn_id] [vsn_name] [vsn_path] (vsn_path is where the built program files are)
  9. Upload the repo to somewhere people can download it

This could probably be automated with GitHub Actions/some other CI.

kthchew avatar Apr 16 '22 18:04 kthchew

Wouldn't it work if released through winget on windows too? since winget is also available on windows 10.

Image

Hexality avatar May 24 '22 02:05 Hexality

I was about to make a small updater for myself but ended up getting caught by this, why is the building process not updating file version for windows builds? image

Hexality avatar May 29 '22 07:05 Hexality

See #644 — I accidentally wrote the commit hash as the version instead of the actual version number. I haven’t had time to get around to fixing this yet, unfortunately.

edit: actually maybe that specific one was fixed in #669, not sure

kthchew avatar May 29 '22 14:05 kthchew

This will be partly implemented for 1.4.0, at least for macOS. We will probably bring a similar updating system to Windows as well.

Scrumplex avatar Jul 11 '22 12:07 Scrumplex

For anyone who wants to try to implement the Windows updater, #479 provides some code to make that easier. It'll essentially boil down to the following:

  1. Link to the WinSparkle library
  2. Create a new subclass of ExternalUpdater (https://github.com/PolyMC/PolyMC/blob/develop/launcher/updater/ExternalUpdater.h) and implement the pure virtual functions. (Note that some, e.g. setBetaAllowed aren't used at all; I only added those just in case, but a stub should work for those.)
  3. Initialize the updater here (macOS example given): https://github.com/PolyMC/PolyMC/blob/ac8ee9f981ea509c04ce64d70a47429a1207e18e/launcher/updater/UpdateChecker.cpp#L28-L38
  4. Have GitHub Actions automatically sign the installer exe.

There may be a few considerations for the Windows updater:

  1. It needs to run the Windows installer (likely in silent mode). The following command line options for the installer should be helpful: /S (silent mode), /NoShortcuts (do not install desktop/start menu shortcuts), /NoUninstaller (do not install an uninstaller, applies to portable installs)
  2. It must install PolyMC in the same place it is currently installed from. Although this should happen automatically if the original installation was done with an installer (as the install location is stored in the registry), this may be more challenging if a user tries to update a portable installation.

kthchew avatar Jul 11 '22 20:07 kthchew

Another thing we must consider(Windows): When we press the button to update and the installer runs in the background it don’t have to re-install/interact with the polyMc.exe because it will be running.

elchupe123 avatar Aug 07 '22 15:08 elchupe123

Another thing we must consider(Windows): When we press the button to update and the installer runs in the background it don’t have to re-install/interact with the polyMc.exe because it will be running.

Well it does need to interact with the existing PolyMC.exe in order to update it, the solution I've seen online is to rename the old exe then delete it on the next launch.

LennyMcLennington avatar Aug 07 '22 15:08 LennyMcLennington

IIRC I had the installer close PolyMC if it is running before installation.

kthchew avatar Aug 07 '22 15:08 kthchew

IIRC I had the installer close PolyMC if it is running before installation.

Oh yeah that also works because the installer is a separate program. Then there shouldn't be any problem with the exe file being currently in use.

LennyMcLennington avatar Aug 07 '22 15:08 LennyMcLennington

IIRC I had the installer close PolyMC if it is running before installation.

Oh yeah that also works because the installer is a separate program. Then there shouldn't be any problem with the exe file being currently in use.

So if we do that the updater should re-open the .exe after closing it.

elchupe123 avatar Aug 07 '22 15:08 elchupe123

Leaving this here in case anyone wants to work on this:

https://packages.msys2.org/base/mingw-w64-winsparkle

Scrumplex avatar Aug 21 '22 19:08 Scrumplex

On modern versions of windows, you have the winget package manager per-installed (or obtainable from the MS Store) which would make auto-update one command jsut like on Linux. So it would potentially be as easy as running winget upgrade -e --id PolyMC.PolyMC or whatever else you call it.

osfanbuff63 avatar Aug 25 '22 13:08 osfanbuff63

That doesn't work with, let's say, portable installs

DioEgizio avatar Aug 25 '22 13:08 DioEgizio

Perhaps a temporary workaround could be to make a changelog popup similar to macOS, but upon clicking install it would simply open the installer exe download in the default browser. Would that be easier to implement?

Madis0 avatar Oct 17 '22 10:10 Madis0