Skip to content

Commit

Permalink
feat: nsis target for windows by default
Browse files Browse the repository at this point in the history
BREAKING CHANGE: "nsis" target is default now. Not "squirrel" (Squirrel.Windows)
If you have existing app, please set "build.win.target" to "squirrel".
Auto-update — please see https://github.com/electron-userland/electron-builder/wiki/Auto-Update
  • Loading branch information
develar committed Nov 10, 2016
1 parent aa05ac0 commit 1bc8d57
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 42 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ _Note: Platform specific `7zip-bin-*` packages are `optionalDependencies`, which

Real project example — [onshape-desktop-shell](https://github.com/develar/onshape-desktop-shell).

Consider to use `nsis` target for Windows ([auto-update](https://github.com/electron-userland/electron-builder/issues/529) will be implemented this month) for new projects.

# Configuration

See [options](https://github.com/electron-userland/electron-builder/wiki/Options) for a full reference but consider following the simple guide outlined below first.
Expand Down
14 changes: 7 additions & 7 deletions docs/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ Don't customize paths to background and icon, — just follow conventions.
| linux | <a name="BuildMetadata-linux"></a>See [.build.linux](#LinuxBuildOptions).
| compression | <a name="BuildMetadata-compression"></a>The compression level, one of `store`, `normal`, `maximum` (default: `normal`). If you want to rapidly test build, `store` can reduce build time significantly.
| afterPack | <a name="BuildMetadata-afterPack"></a>*programmatic API only* The function to be run after pack (but before pack into distributable format and sign). Promise must be returned.
| npmRebuild | <a name="BuildMetadata-npmRebuild"></a>*two package.json structure only* Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies (`npm rebuild`) before starting to package the app. Defaults to `true`.
| npmSkipBuildFromSource | <a name="BuildMetadata-npmSkipBuildFromSource"></a>*two package.json structure only* Whether to omit using [--build-from-source](https://github.com/mapbox/node-pre-gyp#options) flag when installing app native deps. Defaults to `false`.
| npmArgs | <a name="BuildMetadata-npmArgs"></a>*two package.json structure only* Additional command line arguments to use when installing app native deps. Defaults to `null`.
| npmRebuild | <a name="BuildMetadata-npmRebuild"></a>Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies (`npm rebuild`) before starting to package the app. Defaults to `true`.
| npmSkipBuildFromSource | <a name="BuildMetadata-npmSkipBuildFromSource"></a>Whether to omit using [--build-from-source](https://github.com/mapbox/node-pre-gyp#options) flag when installing app native deps. Defaults to `false`.
| npmArgs | <a name="BuildMetadata-npmArgs"></a>Additional command line arguments to use when installing app native deps. Defaults to `null`.
| nodeGypRebuild | <a name="BuildMetadata-nodeGypRebuild"></a>Whether to execute `node-gyp rebuild` before starting to package the app. Defaults to `false`.
| electronDist | <a name="BuildMetadata-electronDist"></a>The path to custom Electron build (e.g. `~/electron/out/R`). Only macOS supported, file issue if need for Linux or Windows.
| publish | <a name="BuildMetadata-publish"></a>See [.build.publish](#PublishConfiguration).
Expand Down Expand Up @@ -255,9 +255,9 @@ Amazon S3 — `https` must be used, so, if you use direct Amazon S3 endpoints, f
| --- | ---
| iconUrl | <a name="SquirrelWindowsOptions-iconUrl"></a><p>A URL to an ICO file to use as the application icon (displayed in Control Panel &gt; Programs and Features). Defaults to the Electron icon.</p> <p>Please note — [local icon file url is not accepted](https://github.com/atom/grunt-electron-installer/issues/73), must be https/http.</p> <ul> <li>If you don’t plan to build windows installer, you can omit it.</li> <li>If your project repository is public on GitHub, it will be <code>https://github.com/${u}/${p}/blob/master/build/icon.ico?raw=true</code> by default.</li> </ul>
| loadingGif | <a name="SquirrelWindowsOptions-loadingGif"></a><p>The path to a .gif file to display during install. <code>build/install-spinner.gif</code> will be used if exists (it is a recommended way to set) (otherwise [default](https://github.com/electron/windows-installer/blob/master/resources/install-spinner.gif)).</p>
| msi | <a name="SquirrelWindowsOptions-msi"></a>*Squirrel.Windows-only.* Whether to create an MSI installer. Defaults to `false` (MSI is not created).
| remoteReleases | <a name="SquirrelWindowsOptions-remoteReleases"></a>*Squirrel.Windows-only.* A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.
| remoteToken | <a name="SquirrelWindowsOptions-remoteToken"></a>*Squirrel.Windows-only.* Authentication token for remote updates
| msi | <a name="SquirrelWindowsOptions-msi"></a>Whether to create an MSI installer. Defaults to `false` (MSI is not created).
| remoteReleases | <a name="SquirrelWindowsOptions-remoteReleases"></a>A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.
| remoteToken | <a name="SquirrelWindowsOptions-remoteToken"></a>Authentication token for remote updates
| useAppIdAsId | <a name="SquirrelWindowsOptions-useAppIdAsId"></a>Use `appId` to identify package instead of `name`.

<a name="WinBuildOptions"></a>
Expand All @@ -267,7 +267,7 @@ Windows specific build options.

| Name | Description
| --- | ---
| target | <a name="WinBuildOptions-target"></a>Target package type: list of `nsis`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `squirrel`.
| target | <a name="WinBuildOptions-target"></a>Target package type: list of `nsis`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `nsis`.
| signingHashAlgorithms | <a name="WinBuildOptions-signingHashAlgorithms"></a>Array of signing algorithms used. Defaults to `['sha1', 'sha256']`
| icon | <a name="WinBuildOptions-icon"></a>The path to application icon. Defaults to `build/icon.ico` (consider using this convention instead of complicating your configuration).
| legalTrademarks | <a name="WinBuildOptions-legalTrademarks"></a>The trademarks and registered trademarks.
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@
"transform-es2015-spread",
"transform-es2015-destructuring",
"array-includes",
"transform-inline-imports-commonjs"
[
"transform-inline-imports-commonjs",
{
"excludeModules": "path"
}
]
]
},
"ava": {
Expand Down
6 changes: 3 additions & 3 deletions src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,17 @@ export interface BuildMetadata {
readonly afterPack?: (context: AfterPackContext) => Promise<any> | null

/*
*two package.json structure only* Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies (`npm rebuild`) before starting to package the app. Defaults to `true`.
Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies (`npm rebuild`) before starting to package the app. Defaults to `true`.
*/
readonly npmRebuild?: boolean

/*
*two package.json structure only* Whether to omit using [--build-from-source](https://github.com/mapbox/node-pre-gyp#options) flag when installing app native deps. Defaults to `false`.
Whether to omit using [--build-from-source](https://github.com/mapbox/node-pre-gyp#options) flag when installing app native deps. Defaults to `false`.
*/
readonly npmSkipBuildFromSource?: boolean

/*
*two package.json structure only* Additional command line arguments to use when installing app native deps. Defaults to `null`.
Additional command line arguments to use when installing app native deps. Defaults to `null`.
*/
readonly npmArgs?: Array<string> | string | null

Expand Down
8 changes: 4 additions & 4 deletions src/options/winOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PlatformSpecificBuildOptions } from "../metadata"
*/
export interface WinBuildOptions extends PlatformSpecificBuildOptions {
/*
Target package type: list of `nsis`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `squirrel`.
Target package type: list of `nsis`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `nsis`.
*/
readonly target?: Array<string> | null

Expand Down Expand Up @@ -143,17 +143,17 @@ export interface SquirrelWindowsOptions extends WinBuildOptions {
readonly loadingGif?: string | null

/*
*Squirrel.Windows-only.* Whether to create an MSI installer. Defaults to `false` (MSI is not created).
Whether to create an MSI installer. Defaults to `false` (MSI is not created).
*/
readonly msi?: boolean

/*
*Squirrel.Windows-only.* A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.
A URL to your existing updates. Or `true` to automatically set to your GitHub repository. If given, these will be downloaded to create delta updates.
*/
readonly remoteReleases?: string | boolean | null

/*
*Squirrel.Windows-only.* Authentication token for remote updates
Authentication token for remote updates
*/
readonly remoteToken?: string | null

Expand Down
6 changes: 3 additions & 3 deletions src/platformPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AsarOptions } from "asar-electron-builder"
import { archiveApp } from "./targets/archive"
import { Minimatch } from "minimatch"
import { checkFileInArchive, createAsarArchive } from "./asarUtil"
import { warn, log, task } from "./util/log"
import { warn, log } from "./util/log"
import { AppInfo } from "./appInfo"
import { copyFiltered } from "./util/filter"
import { pack } from "./packager/dirPackager"
Expand Down Expand Up @@ -182,7 +182,8 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>

const resourcesPath = this.platform === Platform.MAC ? path.join(appOutDir, "Electron.app", "Contents", "Resources") : path.join(appOutDir, "resources")

const p = pack(this, appOutDir, platformName, Arch[arch], this.info.electronVersion, async() => {
log(`Packaging for ${platformName} ${Arch[arch]} using electron ${this.info.electronVersion} to ${path.relative(this.projectDir, appOutDir)}`)
await pack(this, appOutDir, platformName, Arch[arch], this.info.electronVersion, async () => {
const ignoreFiles = new Set([path.resolve(this.info.appDir, outDir), path.resolve(this.info.appDir, this.buildResourcesDir)])
// prune dev or not listed dependencies
await dependencies(this.info.appDir, true, ignoreFiles)
Expand Down Expand Up @@ -244,7 +245,6 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
promises.push(this.postInitApp(appOutDir))
await BluebirdPromise.all(promises)
})
await task(`Packaging for platform ${platformName} ${Arch[arch]} using electron ${this.info.electronVersion} to ${path.relative(this.projectDir, appOutDir)}`, p)

await this.doCopyExtraFiles(extraResourceMatchers)
await this.doCopyExtraFiles(extraFileMatchers)
Expand Down
20 changes: 12 additions & 8 deletions src/targets/nsis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import * as path from "path"
import BluebirdPromise from "bluebird-lst-c"
import { getBinFromBintray } from "../util/binDownload"
import { v5 as uuid5 } from "uuid-1345"
import {
normalizeExt, TargetEx, getPublishConfigs, getResolvedPublishConfig,
ArtifactCreated
} from "../platformPackager"
import { normalizeExt, TargetEx, getPublishConfigs, getResolvedPublishConfig, ArtifactCreated } from "../platformPackager"
import { archiveApp } from "./archive"
import { subTask, task, log } from "../util/log"
import { subTask, log } from "../util/log"
import { unlink, readFile, writeFile, createReadStream } from "fs-extra-p"
import { SemVer } from "semver"
import { NsisOptions } from "../options/winOptions"
Expand Down Expand Up @@ -56,6 +53,8 @@ export default class NsisTarget extends TargetEx {
}

private async doBuild(appOutDir: string, arch: Arch) {
log(`Packaging NSIS installer for arch ${Arch[arch]}`)

const publishConfigs = await this.publishConfigs
if (publishConfigs != null) {
await writeFile(path.join(appOutDir, "resources", "app-update.yml"), safeDump(publishConfigs[0]))
Expand All @@ -66,9 +65,14 @@ export default class NsisTarget extends TargetEx {
return await archiveApp(packager.devMetadata.build.compression, "7z", archiveFile, appOutDir, false, true)
}

finishBuild(): Promise<any> {
return task("Building NSIS installer", this.buildInstaller()
.then(() => BluebirdPromise.map(this.archs.values(), it => unlink(it))))
async finishBuild(): Promise<any> {
log("Building NSIS installer")
try {
await this.buildInstaller()
}
finally {
await BluebirdPromise.map(this.archs.values(), it => unlink(it))
}
}

private async buildInstaller(): Promise<any> {
Expand Down
2 changes: 2 additions & 0 deletions src/targets/squirrelWindows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export default class SquirrelWindowsTarget extends TargetEx {
}

async build(appOutDir: string, arch: Arch) {
log(`Building Squirrel.Windows for arch ${Arch[arch]}`)

if (arch === Arch.ia32) {
warn("For windows consider only distributing 64-bit or use nsis target, see https://github.com/electron-userland/electron-builder/issues/359#issuecomment-214851130")
}
Expand Down
8 changes: 4 additions & 4 deletions src/winPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import BluebirdPromise from "bluebird-lst-c"
import { PlatformPackager, BuildInfo, Target, TargetEx } from "./platformPackager"
import { Platform, Arch } from "./metadata"
import * as path from "path"
import { log, task } from "./util/log"
import { log } from "./util/log"
import { exec, use } from "./util/util"
import { open, close, read } from "fs-extra-p"
import { sign, SignOptions, getSignVendorPath } from "./windowsCodeSign"
Expand Down Expand Up @@ -73,13 +73,13 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
continue
}

if (name === DEFAULT_TARGET || name === "squirrel") {
if (name === "squirrel") {
mapper("squirrel", () => {
const targetClass: typeof SquirrelWindowsTarget = require("./targets/squirrelWindows").default
return new targetClass(this)
})
}
else if (name === "nsis") {
else if (name === DEFAULT_TARGET || name === "nsis") {
mapper(name, outDir => {
const targetClass: typeof NsisTarget = require("./targets/nsis").default
return new targetClass(this, outDir)
Expand Down Expand Up @@ -181,7 +181,7 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
protected packageInDistributableFormat(outDir: string, appOutDir: string, arch: Arch, targets: Array<Target>, promises: Array<Promise<any>>): void {
for (let target of targets) {
if (target instanceof TargetEx) {
promises.push(task(`Building ${target.name} ${Arch[arch]}`, target.build(appOutDir, arch)))
promises.push(target.build(appOutDir, arch))
}
else {
const format = target.name
Expand Down
2 changes: 1 addition & 1 deletion test/src/globTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ test("extraResources", async () => {
//noinspection SpellCheckingInspection
await assertPack("test-app", {
// to check NuGet package
targets: platform.createTarget(platform === Platform.WINDOWS ? null : DIR_TARGET),
targets: platform.createTarget(platform === Platform.WINDOWS ? "squirrel" : DIR_TARGET),
}, {
projectDirCreated: projectDir => {
return BluebirdPromise.all([
Expand Down
15 changes: 6 additions & 9 deletions test/src/winPackagerTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { SignOptions } from "out/windowsCodeSign"
import SquirrelWindowsTarget from "out/targets/squirrelWindows"
import { Target } from "out/platformPackager"

test.ifNotCiOsx("win", app({targets: Platform.WINDOWS.createTarget(["default", "zip"])}, {signed: true}))
test.ifNotCiOsx("win", app({targets: Platform.WINDOWS.createTarget(["squirrel", "zip"])}, {signed: true}))

// very slow
test.skip("delta and msi", app({
targets: Platform.WINDOWS.createTarget(null, Arch.ia32),
targets: Platform.WINDOWS.createTarget("squirrel", Arch.ia32),
devMetadata: {
build: {
squirrelWindows: {
Expand All @@ -39,8 +39,7 @@ test.ifDevOrWinCi("beta version", app({
}
}))

test.ifNotCiOsx("msi as string", t => t.throws(assertPack("test-app-one", platform(Platform.WINDOWS),
{
test.ifNotCiOsx("msi as string", t => t.throws(assertPack("test-app-one", {targets: Platform.WINDOWS.createTarget("squirrel")}, {
projectDirCreated: it => modifyPackageJson(it, data => {
data.build.win = {
msi: "false",
Expand All @@ -54,7 +53,7 @@ test("detect install-spinner, certificateFile/password", () => {
let loadingGifPath: string = null

return assertPack("test-app-one", {
targets: Platform.WINDOWS.createTarget(),
targets: Platform.WINDOWS.createTarget("squirrel"),
platformPackagerFactory: (packager, platform, cleanupTasks) => platformPackager = new CheckingWinPackager(packager),
devMetadata: {
build: {
Expand All @@ -75,11 +74,10 @@ test("detect install-spinner, certificateFile/password", () => {
}
})])
},
packed: () => {
packed: async () => {
assertThat(platformPackager.effectiveDistOptions.loadingGif).isEqualTo(loadingGifPath)
assertThat(platformPackager.signOptions.cert).isEqualTo("secretFile")
assertThat(platformPackager.signOptions.password).isEqualTo("pass")
return BluebirdPromise.resolve(null)
},
})
})
Expand All @@ -95,7 +93,7 @@ test.ifNotCiOsx("icon not an image", t => t.throws(assertPack("test-app-one", pl
test.ifOsx("custom icon", () => {
let platformPackager: CheckingWinPackager = null
return assertPack("test-app-one", {
targets: Platform.WINDOWS.createTarget(),
targets: Platform.WINDOWS.createTarget("squirrel"),
platformPackagerFactory: (packager, platform, cleanupTasks) => platformPackager = new CheckingWinPackager(packager)
}, {
projectDirCreated: projectDir => BluebirdPromise.all([
Expand All @@ -108,7 +106,6 @@ test.ifOsx("custom icon", () => {
]),
packed: async context => {
assertThat(await platformPackager.getIconPath()).isEqualTo(path.join(context.projectDir, "customIcon.ico"))
return BluebirdPromise.resolve()
},
})
})
Expand Down

0 comments on commit 1bc8d57

Please sign in to comment.