From 72de35a2a11f1be25a10f8e40b4eca7dd3570e98 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 5 Dec 2016 14:08:27 +0000 Subject: [PATCH] Switch back to Squirrel installer which it turns out is by far the lesser of two evils. * Auto-update works with a proxy * The update process is reasonably atomic & faster, rather than running the uninstaller then the installer, leaving you with a broken install if you shut down your machine at the wrong time * Gets the update URL the same way as on mac, rather than baking it into the app at build time from package.json. We don't want it in package.json because only our builds want our update URL. --- electron/src/electron-main.js | 62 +++++++++++++++++++---------------- package.json | 5 +-- scripts/electron-package.sh | 30 ++++++++--------- 3 files changed, 50 insertions(+), 47 deletions(-) diff --git a/electron/src/electron-main.js b/electron/src/electron-main.js index a8bdc7f97a..2ca0b9d3bd 100644 --- a/electron/src/electron-main.js +++ b/electron/src/electron-main.js @@ -17,11 +17,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -const electron = require('electron'); +// Squirrel on windows starts the app with various flags +// as hooks to tell us when we've been installed/uninstalled +// etc. +const check_squirrel_hooks = require('./squirrelhooks'); +if (check_squirrel_hooks()) return; -// Auto updater from the 'electron-auto-updater' package for NSIS -// auto-update support (not the one that comes with electron). -const autoUpdater = require('electron-auto-updater').autoUpdater; +const electron = require('electron'); const url = require('url'); const VectorMenu = require('./vectormenu'); @@ -43,7 +45,7 @@ const PERMITTED_URL_SCHEMES = [ ]; const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000; -const INITIAL_UPDATE_DELAY_MS = 5 * 1000; +const INITIAL_UPDATE_DELAY_MS = 30 * 1000; let mainWindow = null; let appQuitting = false; @@ -88,47 +90,44 @@ function installUpdate() { // for some reason, quitAndInstall does not fire the // before-quit event, so we need to set the flag here. appQuitting = true; - autoUpdater.quitAndInstall(); + electron.autoUpdater.quitAndInstall(); } function pollForUpdates() { try { - autoUpdater.checkForUpdates(); + electron.autoUpdater.checkForUpdates(); } catch (e) { console.log("Couldn't check for update", e); } } -function startAutoUpdate() { - if (process.platform != 'darwin' && process.platform != 'win32') { - return; +function startAutoUpdate(update_base_url) { + if (update_base_url.slice(-1) !== '/') { + update_base_url = update_base_url + '/'; } try { - // Since writing, the electron auto update process has changed from being - // completely different between platforms to being differently completely - // different. On Mac, we set the feed URL here. On Windows, it uses a - // yaml file bundled at build time from the 'publish' entry in the - // package.json. There is no autoupdate for Linux: it's expected that - // the distro will provide it. + // For reasons best known to Squirrel, the way it checks for updates + // is completely different between macOS and windows. On macOS, it + // hits a URL that either gives it a 200 with some json or + // 204 No Content. On windows it takes a base path and looks for + // files under that path. if (process.platform == 'darwin') { - const update_base_url = vectorConfig.update_base_url; - if (!update_base_url) { - console.log("No update_base_url: disabling auto-update"); - return; - } - if (update_base_url.slice(-1) !== '/') { - update_base_url = update_url + '/'; - } - const update_url = update_base_url + 'update/macos/tmp/'; - console.log("Starting auto update with URL: " + update_url); - autoUpdater.setFeedURL(update_url); + electron.autoUpdater.setFeedURL(update_base_url + 'macos/'); + } else if (process.platform == 'win32') { + electron.autoUpdater.setFeedURL(update_base_url + 'win32/' + process.arch + '/'); } else { - console.log("Starting auto update with baked-in URL"); + // Squirrel / electron only supports auto-update on these two platforms. + // I'm not even going to try to guess which feed style they'd use if they + // implemented it on Linux, or if it would be different again. + console.log("Auto update not supported on this platform"); } // We check for updates ourselves rather than using 'updater' because we need to // do it in the main process (and we don't really need to check every 10 minutes: // every hour should be just fine for a desktop app) // However, we still let the main window listen for the update events. + // We also wait a short time before checking for updates the first time because + // of squirrel on windows and it taking a small amount of time to release a + // lock file. setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS); setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS); } catch (err) { @@ -150,7 +149,12 @@ process.on('uncaughtException', function (error) { electron.ipcMain.on('install_update', installUpdate); electron.app.on('ready', () => { - startAutoUpdate(); + if (vectorConfig.update_base_url) { + console.log("Starting auto update with base URL: " + vectorConfig.update_base_url); + startAutoUpdate(vectorConfig.update_base_url); + } else { + console.log("No update_base_url is defined: auto update is disabled"); + } mainWindow = new electron.BrowserWindow({ icon: `${__dirname}/../img/riot.ico`, diff --git a/package.json b/package.json index e8377a0d58..ea9d32039a 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,6 @@ "browser-request": "^0.3.3", "classnames": "^2.1.2", "draft-js": "^0.8.1", - "electron-auto-updater": "^0.6.2", "extract-text-webpack-plugin": "^0.9.1", "favico.js": "^0.3.10", "filesize": "^3.1.2", @@ -137,13 +136,15 @@ "files": [ "electron/src/**", "electron/img/**", - "node_modules/electron-auto-updater/**", "webapp/**", "package.json" ], "linux": { "target": "deb", "maintainer": "support@riot.im" + }, + "win": { + "target": "squirrel" } }, "directories": { diff --git a/scripts/electron-package.sh b/scripts/electron-package.sh index 8b1ccd4b03..5830c62dbe 100755 --- a/scripts/electron-package.sh +++ b/scripts/electron-package.sh @@ -81,18 +81,6 @@ if [ -n "$conffile" ]; then pushd "$builddir" fi -if [ "$update_base_url" != "null" ]; then - # Inject a 'publish' configuration into the package.json. This is what - # electron-builder needs for auto-update on windows but we don't want to - # keep it in the package.json as we don't want everyone cloning the source - # and building it for themselves to get our auto-update URL. - update_url=$update_base_url/install/win32/ - jq '.build.publish.provider="generic"' package.json \ - | jq '.build.publish.url="$update_url"' \ - > package.json.tmp - mv package.json.tmp package.json -fi - npm install npm run build:electron @@ -113,15 +101,25 @@ vername=`python -c 'import yaml; import sys; print yaml.load(sys.stdin)["version mkdir -p "$pubdir/install/macos" cp $distdir/mac/*.dmg "$pubdir/install/macos/" -mkdir -p "$pubdir/install/win32/" -cp $distdir/*.exe "$pubdir/install/win32/" -cp $distdir/latest.yml "$pubdir/install/win32/" +mkdir -p "$pubdir/install/win32/ia32/" +cp $distdir/win-ia32/*.exe "$pubdir/install/win32/ia32/" -# Packages for auto-update on mac (Windows (NSIS) uses the installer exe) +mkdir -p "$pubdir/install/win32/x64/" +cp $distdir/win/*.exe "$pubdir/install/win32/x64/" + +# Packages for auto-update mkdir -p "$pubdir/update/macos" cp $distdir/mac/*.zip "$pubdir/update/macos/" echo "$ver" > "$pubdir/update/macos/latest" +mkdir -p "$pubdir/update/win32/ia32/" +cp $distdir/win-ia32/*.nupkg "$pubdir/update/win32/ia32/" +cp $distdir/win-ia32/RELEASES "$pubdir/install/win32/ia32/" + +mkdir -p "$pubdir/update/win32/x64/" +cp $distdir/win/*.nupkg "$pubdir/update/win32/x64/" +cp $distdir/win/RELEASES "$pubdir/update/win32x64ia32/" + # Move the debs to the main project dir's dist folder rm -r "$projdir/electron/dist" || true mkdir -p "$projdir/electron/dist"