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.
This commit is contained in:
David Baker 2016-12-05 14:08:27 +00:00
parent 970a029cea
commit 72de35a2a1
3 changed files with 50 additions and 47 deletions

View file

@ -17,11 +17,13 @@ See the License for the specific language governing permissions and
limitations under the License. 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 const electron = require('electron');
// auto-update support (not the one that comes with electron).
const autoUpdater = require('electron-auto-updater').autoUpdater;
const url = require('url'); const url = require('url');
const VectorMenu = require('./vectormenu'); const VectorMenu = require('./vectormenu');
@ -43,7 +45,7 @@ const PERMITTED_URL_SCHEMES = [
]; ];
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000; 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 mainWindow = null;
let appQuitting = false; let appQuitting = false;
@ -88,47 +90,44 @@ function installUpdate() {
// for some reason, quitAndInstall does not fire the // for some reason, quitAndInstall does not fire the
// before-quit event, so we need to set the flag here. // before-quit event, so we need to set the flag here.
appQuitting = true; appQuitting = true;
autoUpdater.quitAndInstall(); electron.autoUpdater.quitAndInstall();
} }
function pollForUpdates() { function pollForUpdates() {
try { try {
autoUpdater.checkForUpdates(); electron.autoUpdater.checkForUpdates();
} catch (e) { } catch (e) {
console.log("Couldn't check for update", e); console.log("Couldn't check for update", e);
} }
} }
function startAutoUpdate() { function startAutoUpdate(update_base_url) {
if (process.platform != 'darwin' && process.platform != 'win32') { if (update_base_url.slice(-1) !== '/') {
return; update_base_url = update_base_url + '/';
} }
try { try {
// Since writing, the electron auto update process has changed from being // For reasons best known to Squirrel, the way it checks for updates
// completely different between platforms to being differently completely // is completely different between macOS and windows. On macOS, it
// different. On Mac, we set the feed URL here. On Windows, it uses a // hits a URL that either gives it a 200 with some json or
// yaml file bundled at build time from the 'publish' entry in the // 204 No Content. On windows it takes a base path and looks for
// package.json. There is no autoupdate for Linux: it's expected that // files under that path.
// the distro will provide it.
if (process.platform == 'darwin') { if (process.platform == 'darwin') {
const update_base_url = vectorConfig.update_base_url; electron.autoUpdater.setFeedURL(update_base_url + 'macos/');
if (!update_base_url) { } else if (process.platform == 'win32') {
console.log("No update_base_url: disabling auto-update"); electron.autoUpdater.setFeedURL(update_base_url + 'win32/' + process.arch + '/');
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);
} else { } 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 // 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: // 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) // every hour should be just fine for a desktop app)
// However, we still let the main window listen for the update events. // 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); setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS); setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
} catch (err) { } catch (err) {
@ -150,7 +149,12 @@ process.on('uncaughtException', function (error) {
electron.ipcMain.on('install_update', installUpdate); electron.ipcMain.on('install_update', installUpdate);
electron.app.on('ready', () => { 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({ mainWindow = new electron.BrowserWindow({
icon: `${__dirname}/../img/riot.ico`, icon: `${__dirname}/../img/riot.ico`,

View file

@ -58,7 +58,6 @@
"browser-request": "^0.3.3", "browser-request": "^0.3.3",
"classnames": "^2.1.2", "classnames": "^2.1.2",
"draft-js": "^0.8.1", "draft-js": "^0.8.1",
"electron-auto-updater": "^0.6.2",
"extract-text-webpack-plugin": "^0.9.1", "extract-text-webpack-plugin": "^0.9.1",
"favico.js": "^0.3.10", "favico.js": "^0.3.10",
"filesize": "^3.1.2", "filesize": "^3.1.2",
@ -137,13 +136,15 @@
"files": [ "files": [
"electron/src/**", "electron/src/**",
"electron/img/**", "electron/img/**",
"node_modules/electron-auto-updater/**",
"webapp/**", "webapp/**",
"package.json" "package.json"
], ],
"linux": { "linux": {
"target": "deb", "target": "deb",
"maintainer": "support@riot.im" "maintainer": "support@riot.im"
},
"win": {
"target": "squirrel"
} }
}, },
"directories": { "directories": {

View file

@ -81,18 +81,6 @@ if [ -n "$conffile" ]; then
pushd "$builddir" pushd "$builddir"
fi 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 install
npm run build:electron 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" mkdir -p "$pubdir/install/macos"
cp $distdir/mac/*.dmg "$pubdir/install/macos/" cp $distdir/mac/*.dmg "$pubdir/install/macos/"
mkdir -p "$pubdir/install/win32/" mkdir -p "$pubdir/install/win32/ia32/"
cp $distdir/*.exe "$pubdir/install/win32/" cp $distdir/win-ia32/*.exe "$pubdir/install/win32/ia32/"
cp $distdir/latest.yml "$pubdir/install/win32/"
# 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" mkdir -p "$pubdir/update/macos"
cp $distdir/mac/*.zip "$pubdir/update/macos/" cp $distdir/mac/*.zip "$pubdir/update/macos/"
echo "$ver" > "$pubdir/update/macos/latest" 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 # Move the debs to the main project dir's dist folder
rm -r "$projdir/electron/dist" || true rm -r "$projdir/electron/dist" || true
mkdir -p "$projdir/electron/dist" mkdir -p "$projdir/electron/dist"