Add 64-bit Windows build

Right now all Windows users are running a 32-bit app, even if their OS
is 64-bit.

Here's the plan to improve things:

1. We release a 64-bit installer, in addition to the 32-bit installer.

2. We auto-detect in the browser when a visitor is on a 32-bit vs.
64-bit OS and try to offer them the right installer. When in doubt, we
give them the 32-bit installer since that's safest.

3. The auto-updater will return the right binaries for the architecture
the user is on. This means that all our existing users who have 64-bit
OSs but are running the 32-bit app will get updated to the 64-bit app
on the next update. Also, 64-bit users who accidentally download the
32-bit installer will also get the 64-bit app on the next update.

---

Other notes:

- We don't generate 32-bit delta files. See reasoning inline.
- The package script now deletes extraneous Squirrel files (i.e.
*.nupkg delta files for older versions of the app) which should make
uploading the right files to GitHub easier. :)

The binary file naming works like this:

- Most users are on 64-bit systems, so they get nice clean file names
that don't specify an architecture (WebTorrentSetup-v1.0.0.exe). The
32-bit build files have the same naming but contain the string "-ia32"
at the end. In a few years, we will be able to just stop producing the
32-bit build files entirely.

- This means that the "WebTorrent-v0.15.0-linux-x64.zip" linux build
file is changing to "WebTorrent-v0.15.0-linux.zip" to match the Windows
naming convention. The .deb installer files must contain to
architecture in order to install correctly, so those do not change.

- Mac is 100% 64-bit, so it does not change.
This commit is contained in:
Feross Aboukhadijeh
2016-09-17 19:37:50 -07:00
parent 7415d3cee5
commit 77534d650a

View File

@@ -112,7 +112,7 @@ var darwin = {
// Build for Mac // Build for Mac
platform: 'darwin', platform: 'darwin',
// Build 64 bit binaries only. // Build x64 binaries only.
arch: 'x64', arch: 'x64',
// The bundle identifier to use in the application's plist (Mac only). // The bundle identifier to use in the application's plist (Mac only).
@@ -133,8 +133,8 @@ var win32 = {
// Build for Windows. // Build for Windows.
platform: 'win32', platform: 'win32',
// Build 32 bit binaries only. // Build ia32 and x64 binaries.
arch: 'ia32', arch: 'all',
// Object hash of application metadata to embed into the executable (Windows only) // Object hash of application metadata to embed into the executable (Windows only)
'version-string': { 'version-string': {
@@ -167,7 +167,7 @@ var linux = {
// Build for Linux. // Build for Linux.
platform: 'linux', platform: 'linux',
// Build 32 and 64 bit binaries. // Build ia32 and x64 binaries.
arch: 'all' arch: 'all'
// Note: Application icon for Linux is specified via the BrowserWindow `icon` option. // Note: Application icon for Linux is specified via the BrowserWindow `icon` option.
@@ -388,19 +388,25 @@ function buildWin32 (cb) {
} }
var tasks = [] var tasks = []
if (argv.package === 'exe' || argv.package === 'all') { buildPath.forEach(function (filesPath) {
tasks.push((cb) => packageInstaller(cb)) var destArch = filesPath.split('-').pop()
}
if (argv.package === 'portable' || argv.package === 'all') { if (argv.package === 'exe' || argv.package === 'all') {
tasks.push((cb) => packagePortable(cb)) tasks.push((cb) => packageInstaller(filesPath, destArch, cb))
} }
if (argv.package === 'portable' || argv.package === 'all') {
tasks.push((cb) => packagePortable(filesPath, destArch, cb))
}
})
series(tasks, cb) series(tasks, cb)
function packageInstaller (cb) { function packageInstaller (filesPath, destArch, cb) {
console.log('Windows: Creating installer...') console.log(`Windows: Creating ${destArch} installer...`)
var archStr = destArch === 'ia32' ? '-ia32' : ''
installer.createWindowsInstaller({ installer.createWindowsInstaller({
appDirectory: buildPath[0], appDirectory: filesPath,
authors: config.APP_TEAM, authors: config.APP_TEAM,
description: config.APP_NAME, description: config.APP_NAME,
exe: config.APP_NAME + '.exe', exe: config.APP_NAME + '.exe',
@@ -410,8 +416,21 @@ function buildWin32 (cb) {
noMsi: true, noMsi: true,
outputDirectory: DIST_PATH, outputDirectory: DIST_PATH,
productName: config.APP_NAME, productName: config.APP_NAME,
remoteReleases: config.GITHUB_URL, /**
setupExe: config.APP_NAME + 'Setup-v' + config.APP_VERSION + '.exe', * Only create delta updates for the Windows x64 build because 90% of our
* users have Windows x64 and the delta files take a *very* long time to
* generate. Also, the ia32 files on GitHub have non-standard Squirrel
* names (i.e. RELEASES-ia32 instead of RELEASES) and so Squirrel won't
* find them unless we proxy the requests.
*/
remoteReleases: destArch === 'x64'
? config.GITHUB_URL
: undefined,
/**
* If you hit a "GitHub API rate limit exceeded" error, set this token!
*/
remoteToken: process.env.WEBTORRENT_GITHUB_API_TOKEN,
setupExe: config.APP_NAME + 'Setup-v' + config.APP_VERSION + archStr + '.exe',
setupIcon: config.APP_ICON + '.ico', setupIcon: config.APP_ICON + '.ico',
signWithParams: signWithParams, signWithParams: signWithParams,
title: config.APP_NAME, title: config.APP_NAME,
@@ -419,23 +438,61 @@ function buildWin32 (cb) {
version: pkg.version version: pkg.version
}) })
.then(function () { .then(function () {
console.log('Windows: Created installer.') console.log(`Windows: Created ${destArch} installer.`)
/**
* Delete extraneous Squirrel files (i.e. *.nupkg delta files for older
* versions of the app)
*/
fs.readdirSync(DIST_PATH)
.filter((name) => name.endsWith('.nupkg') && !name.includes(pkg.version))
.forEach((filename) => {
fs.unlinkSync(path.join(DIST_PATH, filename))
})
if (destArch === 'ia32') {
/**
* Rename ia32 Squirrel files to contain "-ia32". Specifically:
* - RELEASES -> RELEASES-ia32
* - WebTorrent-x.x.x-delta.nupkg -> WebTorrent-x.x.x-delta-ia32.nupkg
* - WebTorrent-x.x.x-full.nupkg -> WebTorrent-x.x.x-full-ia32.nupkg
*/
console.log('Windows: Renaming ia32 installer files...')
fs.renameSync(
path.join(DIST_PATH, 'RELEASES'),
path.join(DIST_PATH, 'RELEASES-ia32')
)
fs.readdirSync(DIST_PATH)
.filter((filename) => filename.endsWith('.nupkg'))
.forEach((filename) => {
fs.renameSync(
path.join(DIST_PATH, filename),
path.join(DIST_PATH, filename.replace(/\.nupkg$/, '-ia32.nupkg'))
)
})
console.log('Windows: Renamed ia32 installer files.')
}
cb(null) cb(null)
}) })
.catch(cb) .catch(cb)
} }
function packagePortable (cb) { function packagePortable (filesPath, destArch, cb) {
console.log('Windows: Creating portable app...') console.log(`Windows: Creating ${destArch} portable app...`)
var portablePath = path.join(buildPath[0], 'Portable Settings') var portablePath = path.join(filesPath, 'Portable Settings')
mkdirp.sync(portablePath) mkdirp.sync(portablePath)
var inPath = path.join(DIST_PATH, path.basename(buildPath[0])) var archStr = destArch === 'ia32' ? '-ia32' : ''
var outPath = path.join(DIST_PATH, BUILD_NAME + '-win.zip')
var inPath = path.join(DIST_PATH, path.basename(filesPath))
var outPath = path.join(DIST_PATH, BUILD_NAME + '-win' + archStr + '.zip')
zip.zipSync(inPath, outPath) zip.zipSync(inPath, outPath)
console.log('Windows: Created portable app.') console.log(`Windows: Created ${destArch} portable app.`)
cb(null) cb(null)
} }
}) })
@@ -500,8 +557,10 @@ function buildLinux (cb) {
// Create .zip file for Linux // Create .zip file for Linux
console.log(`Linux: Creating ${destArch} zip...`) console.log(`Linux: Creating ${destArch} zip...`)
var archStr = destArch === 'ia32' ? '-ia32' : ''
var inPath = path.join(DIST_PATH, path.basename(filesPath)) var inPath = path.join(DIST_PATH, path.basename(filesPath))
var outPath = path.join(DIST_PATH, BUILD_NAME + '-linux-' + destArch + '.zip') var outPath = path.join(DIST_PATH, BUILD_NAME + '-linux' + archStr + '.zip')
zip.zipSync(inPath, outPath) zip.zipSync(inPath, outPath)
console.log(`Linux: Created ${destArch} zip.`) console.log(`Linux: Created ${destArch} zip.`)