From 265ad2077eb4904b12226a38b552eb0b4b73c6f3 Mon Sep 17 00:00:00 2001 From: develar Date: Sun, 6 Nov 2016 17:54:57 +0100 Subject: [PATCH] feat(mac): macOS pkg installer Closes #52 --- README.md | 2 +- docs/Code Signing.md | 3 + docs/Options.md | 2 +- src/codeSign.ts | 4 +- src/macPackager.ts | 104 +++++++++++++++++-------------- src/options/macOptions.ts | 6 +- src/packager.ts | 4 ++ src/packager/mac.ts | 7 +-- src/platformPackager.ts | 4 +- src/targets/dmg.ts | 9 +-- src/targets/pkg.ts | 34 +++++++--- src/targets/targetFactory.ts | 9 ++- src/util/log.ts | 7 ++- src/winPackager.ts | 2 +- test/src/helpers/codeSignData.ts | 2 +- test/src/macPackagerTest.ts | 16 ++--- yarn.lock | 4 +- 17 files changed, 132 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 573cc34521f..679262c8e7f 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A complete solution to package and build a ready for distribution Electron app f * [Build version management](https://github.com/electron-userland/electron-builder/wiki/Options#build-version-management). * Numerous target formats: * All platforms: `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir` (unpacked directory). - * [MacOS](https://github.com/electron-userland/electron-builder/wiki/Options#MacOptions-target): `dmg`, `mas`. + * [MacOS](https://github.com/electron-userland/electron-builder/wiki/Options#MacOptions-target): `dmg`, `pkg`, `mas`. * [Linux](https://github.com/electron-userland/electron-builder/wiki/Options#LinuxBuildOptions-target): `AppImage`, `deb`, `rpm`, `freebsd`, `pacman`, `p5p`, `apk`. * [Windows](https://github.com/electron-userland/electron-builder/wiki/Options#WinBuildOptions-target): NSIS, Squirrel.Windows. * [Publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) to GitHub Releases and Bintray. diff --git a/docs/Code Signing.md b/docs/Code Signing.md index ef2b38cceef..1434acf6774 100644 --- a/docs/Code Signing.md +++ b/docs/Code Signing.md @@ -1,4 +1,5 @@ macOS and Windows code signing is supported. Windows is dual code-signed (SHA1 & SHA256 hashing algorithms). + On a macOS development machine valid and appropriate identity from your keychain will be automatically used. | Env Name | Description @@ -6,6 +7,7 @@ On a macOS development machine valid and appropriate identity from your keychain | `CSC_LINK` | The HTTPS link (or base64-encoded data, or `file://` link) to certificate (`*.p12` or `*.pfx` file). | `CSC_KEY_PASSWORD` | The password to decrypt the certificate given in `CSC_LINK`. | `CSC_NAME` | *macOS-only* Name of certificate (to retrieve from login.keychain). Useful on a development machine (not on CI) if you have several identities (otherwise don't specify it). +| `CSC_IDENTITY_AUTO_DISCOVERY`| `true` or `false`. Defaults to `true` — on a macOS development machine valid and appropriate identity from your keychain will be automatically used. If you are building Windows on macOS and need to set a different certificate and password (than the ones set in `CSC_*` env vars) you can use `WIN_CSC_LINK` and `WIN_CSC_KEY_PASSWORD`. @@ -34,6 +36,7 @@ Please note — Gatekeeper only recognises [Apple digital certificates](http://s 3. Select all required certificates (hint: use cmd-click to select several): * `Developer ID Application:` to sign app for macOS. * `3rd Party Mac Developer Application:` and `3rd Party Mac Developer Installer:` to sign app for MAS (Mac App Store). + * `Developer ID Application:` and `Developer ID Installer` to sign app and installer for distribution outside of the Mac App Store. Please note – you can select as many certificates, as need. No restrictions on electron-builder side. All selected certificates will be imported into temporary keychain on CI server. diff --git a/docs/Options.md b/docs/Options.md index ed7adcb13a5..c502342678b 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -158,7 +158,7 @@ MacOS specific build options. | Name | Description | --- | --- | category |

The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.

For example, "category": "public.app-category.developer-tools" will set the application category to *Developer Tools*.

Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).

-| target | Target package type: list of `default`, `dmg`, `mas`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `default` (dmg and zip for Squirrel.Mac). +| target | The target package type: list of `default`, `dmg`, `mas`, `pkg`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `default` (dmg and zip for Squirrel.Mac). | identity |

The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](https://github.com/electron-userland/electron-builder/wiki/Code-Signing). MAS installer identity is specified in the [.build.mas](#MasBuildOptions-identity).

| icon | The path to application icon. Defaults to `build/icon.icns` (consider using this convention instead of complicating your configuration). | entitlements |

The path to entitlements file for signing the app. build/entitlements.mac.plist will be used if exists (it is a recommended way to set). MAS entitlements is specified in the [.build.mas](#MasBuildOptions-entitlements).

diff --git a/src/codeSign.ts b/src/codeSign.ts index eb819f7b16f..803467d4bb6 100644 --- a/src/codeSign.ts +++ b/src/codeSign.ts @@ -7,9 +7,9 @@ import BluebirdPromise from "bluebird-lst-c" import { randomBytes } from "crypto" import { TmpDir } from "./util/tmp" -const appleCertificatePrefixes = ["Developer ID Application:", "3rd Party Mac Developer Application:", "Developer ID Installer:", "3rd Party Mac Developer Installer:"] +const appleCertificatePrefixes = ["Developer ID Application:", "Developer ID Installer:", "3rd Party Mac Developer Application:", "3rd Party Mac Developer Installer:"] -export type CertType = "Developer ID Application" | "3rd Party Mac Developer Application" | "Developer ID Installer" | "3rd Party Mac Developer Installer" | "Mac Developer" +export type CertType = "Developer ID Application" | "Developer ID Installer" | "3rd Party Mac Developer Application" | "3rd Party Mac Developer Installer" | "Mac Developer" export interface CodeSigningInfo { keychainName?: string | null diff --git a/src/macPackager.ts b/src/macPackager.ts index 339b4957e8f..5a514d5b6c8 100644 --- a/src/macPackager.ts +++ b/src/macPackager.ts @@ -1,4 +1,4 @@ -import { PlatformPackager, BuildInfo, Target } from "./platformPackager" +import { PlatformPackager, BuildInfo, Target, TargetEx } from "./platformPackager" import { Platform, Arch } from "./metadata" import { MasBuildOptions, MacOptions } from "./options/macOptions" import * as path from "path" @@ -6,14 +6,15 @@ import BluebirdPromise from "bluebird-lst-c" import { log, warn, task } from "./util/log" import { createKeychain, CodeSigningInfo, findIdentity } from "./codeSign" import { deepAssign } from "./util/deepAssign" -import { signAsync, BaseSignOptions, SignOptions } from "electron-osx-sign-tf" +import { signAsync, SignOptions } from "electron-osx-sign-tf" import { DmgTarget } from "./targets/dmg" -import { createCommonTarget, DEFAULT_TARGET } from "./targets/targetFactory" +import { createCommonTarget, DEFAULT_TARGET, DIR_TARGET } from "./targets/targetFactory" import { AppInfo } from "./appInfo" -import { flatApplication } from "./targets/pkg" +import { PkgTarget, prepareProductBuildArgs } from "./targets/pkg" +import { exec } from "./util/util" export default class MacPackager extends PlatformPackager { - codeSigningInfo: Promise + readonly codeSigningInfo: Promise constructor(info: BuildInfo) { super(info) @@ -44,19 +45,26 @@ export default class MacPackager extends PlatformPackager { createTargets(targets: Array, mapper: (name: string, factory: () => Target) => void, cleanupTasks: Array<() => Promise>): void { for (let name of targets) { - if (name === "dir") { - continue - } - - if (name === DEFAULT_TARGET) { - mapper("dmg", () => new DmgTarget(this)) - mapper("zip", () => new Target("zip")) - } - else if (name === "dmg") { - mapper("dmg", () => new DmgTarget(this)) - } - else { - mapper(name, () => name === "mas" ? new Target("mas") : createCommonTarget(name)) + switch (name) { + case DIR_TARGET: + break + + case DEFAULT_TARGET: + mapper("dmg", () => new DmgTarget(this)) + mapper("zip", () => new Target("zip")) + break + + case "dmg": + mapper("dmg", () => new DmgTarget(this)) + break + + case "pkg": + mapper("pkg", () => new PkgTarget(this)) + break + + default: + mapper(name, () => name === "mas" ? new Target(name) : createCommonTarget(name)) + break } } } @@ -74,16 +82,12 @@ export default class MacPackager extends PlatformPackager { const appOutDir = this.computeAppOutDir(outDir, arch) nonMasPromise = this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions) .then(() => this.sign(appOutDir, null)) - .then(() => { - this.packageInDistributableFormat(appOutDir, targets, postAsyncTasks) - }) + .then(() => this.packageInDistributableFormat(appOutDir, targets, postAsyncTasks)) } if (hasMas) { - // osx-sign - disable warning const appOutDir = path.join(outDir, "mas") const masBuildOptions = deepAssign({}, this.platformSpecificBuildOptions, (this.devMetadata.build).mas) - //noinspection JSUnusedGlobalSymbols await this.doPack(outDir, appOutDir, "mas", arch, masBuildOptions) await this.sign(appOutDir, masBuildOptions) } @@ -95,11 +99,11 @@ export default class MacPackager extends PlatformPackager { private async sign(appOutDir: string, masOptions: MasBuildOptions | null): Promise { if (process.platform !== "darwin") { - warn("macOS application code signing is not supported on this platform, skipping.") + warn("macOS application code signing is supported only on macOS, skipping.") return } - let keychainName = (await this.codeSigningInfo).keychainName + const keychainName = (await this.codeSigningInfo).keychainName const isMas = masOptions != null const masQualifier = isMas ? (masOptions!!.identity || this.platformSpecificBuildOptions.identity) : null @@ -124,24 +128,14 @@ export default class MacPackager extends PlatformPackager { } } - let installerName: string | null = null - if (masOptions != null) { - installerName = await findIdentity("3rd Party Mac Developer Installer", masQualifier, keychainName) - if (installerName == null) { - throw new Error('Cannot find valid "3rd Party Mac Developer Installer" identity to sign MAS installer, see https://github.com/electron-userland/electron-builder/wiki/Code-Signing') - } - } - - const baseSignOptions: BaseSignOptions = { - app: path.join(appOutDir, `${this.appInfo.productFilename}.app`), - keychain: keychainName || undefined, - } - - const signOptions = Object.assign({ + const appPath = path.join(appOutDir, `${this.appInfo.productFilename}.app`) + const signOptions: any = { identity: name, platform: isMas ? "mas" : "darwin", version: this.info.electronVersion, - }, (this.devMetadata.build)["osx-sign"], baseSignOptions) + app: appPath, + keychain: keychainName || undefined, + } const resourceList = await this.resourceList if (resourceList.includes(`entitlements.osx.plist`)) { @@ -176,29 +170,47 @@ export default class MacPackager extends PlatformPackager { if (masOptions != null) { const pkg = path.join(appOutDir, `${this.appInfo.productFilename}-${this.appInfo.version}.pkg`) - await this.doFlat(baseSignOptions, pkg, installerName!!) + await this.doFlat(appPath, pkg, await this.findInstallerIdentity(true, keychainName), keychainName) this.dispatchArtifactCreated(pkg, `${this.appInfo.name}-${this.appInfo.version}.pkg`) } } + async findInstallerIdentity(isMas: boolean, keychainName: string | n): Promise { + const targetSpecificOptions: MacOptions = (this.devMetadata.build)[isMas ? "mas" : "pkg"] || this.platformSpecificBuildOptions + const name = isMas ? "3rd Party Mac Developer Installer" : "Developer ID Installer" + let installerName = await findIdentity(name, targetSpecificOptions.identity, keychainName) + if (installerName != null) { + return installerName + } + + if (isMas) { + throw new Error(`Cannot find valid "${name}" identity to sign MAS installer, see https://github.com/electron-userland/electron-builder/wiki/Code-Signing`) + } + else { + throw new Error(`Cannot find valid "${name}" to sign standalone installer, see https://github.com/electron-userland/electron-builder/wiki/Code-Signing`) + } + } + //noinspection JSMethodCanBeStatic protected async doSign(opts: SignOptions): Promise { return signAsync(opts) } //noinspection JSMethodCanBeStatic - protected async doFlat(opts: BaseSignOptions, outFile: string, identity: string): Promise { - return flatApplication(opts, outFile, identity) + protected async doFlat(appPath: string, outFile: string, identity: string, keychain: string | n): Promise { + const args = prepareProductBuildArgs(appPath, identity, keychain) + args.push(outFile) + return exec("productbuild", args) } protected packageInDistributableFormat(appOutDir: string, targets: Array, promises: Array>): void { for (let t of targets) { const target = t.name - if (t instanceof DmgTarget) { - promises.push(t.build(appOutDir)) + if (t instanceof TargetEx) { + promises.push(t.build(appOutDir, Arch.x64)) } else if (target !== "mas") { - log(`Creating MacOS ${target}`) + log(`Building macOS ${target}`) // we use app name here - see https://github.com/electron-userland/electron-builder/pull/204 const outFile = path.join(appOutDir, this.generateName2(target, "mac", false)) promises.push(this.archiveApp(target, appOutDir, outFile) diff --git a/src/options/macOptions.ts b/src/options/macOptions.ts index cab770fcde2..bd92350debb 100644 --- a/src/options/macOptions.ts +++ b/src/options/macOptions.ts @@ -1,5 +1,7 @@ import { PlatformSpecificBuildOptions } from "../metadata" +export type MacOsTargetName = "default" | "dmg" | "mas" | "pkg" | "7z" | "zip" | "tar.xz" | "tar.lz" | "tar.gz" | "tar.bz2" | "dir" + /* ### `.build.mac` @@ -16,9 +18,9 @@ export interface MacOptions extends PlatformSpecificBuildOptions { readonly category?: string | null /* - Target package type: list of `default`, `dmg`, `mas`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `default` (dmg and zip for Squirrel.Mac). + The target package type: list of `default`, `dmg`, `mas`, `pkg`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`. Defaults to `default` (dmg and zip for Squirrel.Mac). */ - readonly target?: Array | null + readonly target?: Array | null /* The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](https://github.com/electron-userland/electron-builder/wiki/Code-Signing). diff --git a/src/packager.ts b/src/packager.ts index bf015e34d0d..105304b6c54 100644 --- a/src/packager.ts +++ b/src/packager.ts @@ -200,6 +200,10 @@ export class Packager implements BuildInfo { throw new Error(util.format(errorMessages.buildIsMissed, devAppPackageFile)) } else { + if (build["osx-sign"] != null) { + throw new Error("osx-sign is deprecated and not supported — please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing") + } + const author = appMetadata.author if (author == null) { throw new Error(`Please specify "author" in the application package.json ('${appPackageFile}') — it is used as company name.`) diff --git a/src/packager/mac.ts b/src/packager/mac.ts index ce15ef4e9f1..3b786b98c03 100644 --- a/src/packager/mac.ts +++ b/src/packager/mac.ts @@ -84,11 +84,8 @@ export async function createApp(packager: PlatformPackager, appOutDir: stri helperNPPlist.CFBundleName = `${appInfo.productName} Helper NP` helperNPPlist.CFBundleExecutable = `${appFilename} Helper NP` - use(appInfo.version, it => { - appPlist.CFBundleShortVersionString = it - appPlist.CFBundleVersion = it - }) - use(appInfo.buildVersion, it => appPlist.CFBundleVersion = it) + appPlist.CFBundleShortVersionString = appInfo.version + appPlist.CFBundleVersion = appInfo.buildVersion const protocols = asArray(buildMetadata.protocols).concat(asArray(packager.platformSpecificBuildOptions.protocols)) if (protocols.length > 0) { diff --git a/src/platformPackager.ts b/src/platformPackager.ts index 5253187c7dd..a6a85f445bc 100644 --- a/src/platformPackager.ts +++ b/src/platformPackager.ts @@ -75,7 +75,7 @@ export interface BuildInfo { } export class Target { - constructor(public name: string) { + constructor(public readonly name: string) { } finishBuild(): Promise { @@ -103,7 +103,7 @@ export abstract class PlatformPackager readonly appInfo: AppInfo - constructor(public info: BuildInfo) { + constructor(public readonly info: BuildInfo) { this.devMetadata = info.devMetadata this.platformSpecificBuildOptions = this.normalizePlatformSpecificBuildOptions((info.devMetadata.build)[this.platform.buildConfigurationKey]) this.appInfo = this.prepareAppInfo(info.appInfo) diff --git a/src/targets/dmg.ts b/src/targets/dmg.ts index d1066ef9f2d..1633eb8603c 100644 --- a/src/targets/dmg.ts +++ b/src/targets/dmg.ts @@ -1,25 +1,26 @@ import { deepAssign } from "../util/deepAssign" import * as path from "path" import { log, warn } from "../util/log" -import { Target, PlatformPackager } from "../platformPackager" +import { PlatformPackager, TargetEx } from "../platformPackager" import { MacOptions, DmgOptions, DmgContent } from "../options/macOptions" import BluebirdPromise from "bluebird-lst-c" import { debug, use, exec, statOrNull, isEmptyOrSpaces, spawn } from "../util/util" import { copy, unlink, outputFile, remove } from "fs-extra-p" import { executeFinally } from "../util/promise" import sanitizeFileName from "sanitize-filename" +import { Arch } from "../metadata" -export class DmgTarget extends Target { +export class DmgTarget extends TargetEx { private helperDir = path.join(__dirname, "..", "..", "templates", "dmg") constructor(private packager: PlatformPackager) { super("dmg") } - async build(appOutDir: string) { + async build(appOutDir: string, arch: Arch) { const packager = this.packager const appInfo = packager.appInfo - log("Creating DMG") + log("Building DMG") const specification = await this.computeDmgOptions() diff --git a/src/targets/pkg.ts b/src/targets/pkg.ts index 025d8cecf5e..3e6d56cf737 100644 --- a/src/targets/pkg.ts +++ b/src/targets/pkg.ts @@ -1,14 +1,34 @@ import { exec } from "../util/util" -import { BaseSignOptions } from "electron-osx-sign-tf" +import { TargetEx } from "../platformPackager" +import { Arch } from "../metadata" +import MacPackager from "../macPackager" +import * as path from "path" -export function flatApplication(opts: BaseSignOptions, outFile: string, identity: string): Promise { +export class PkgTarget extends TargetEx { + constructor(private packager: MacPackager) { + super("pkg") + } + + async build(appOutDir: string, arch: Arch): Promise { + const packager = this.packager + const appInfo = packager.appInfo + const outFile = path.join(appOutDir, `${appInfo.productFilename}-${appInfo.version}.pkg`) + const keychainName = (await packager.codeSigningInfo).keychainName + const args = prepareProductBuildArgs(path.join(appOutDir, `${appInfo.productFilename}.app`), await packager.findInstallerIdentity(false, keychainName), keychainName) + args.push("--version", appInfo.buildVersion) + args.push(outFile) + await exec("productbuild", args) + packager.dispatchArtifactCreated(outFile, `${appInfo.name}-${appInfo.version}.pkg`) + } +} + +export function prepareProductBuildArgs(appPath: string, identity: string, keychain: string | n) { const args = [ - "--component", opts.app, "/Applications", + "--component", appPath, "/Applications", "--sign", identity, ] - if (opts.keychain != null) { - args.push("--keychain", opts.keychain) + if (keychain != null) { + args.push("--keychain", keychain) } - args.push(outFile) - return exec("productbuild", args) + return args } \ No newline at end of file diff --git a/src/targets/targetFactory.ts b/src/targets/targetFactory.ts index 19328c5c45f..681126cd941 100644 --- a/src/targets/targetFactory.ts +++ b/src/targets/targetFactory.ts @@ -1,6 +1,6 @@ import { PlatformPackager, Target } from "../platformPackager" -export const commonTargets = ["dir", "zip", "7z", "tar.xz", "tar.lz", "tar.gz", "tar.bz2"] +const commonTargets = new Set(["dir", "zip", "7z", "tar.xz", "tar.lz", "tar.gz", "tar.bz2"]) export const DEFAULT_TARGET = "default" export const DIR_TARGET = "dir" @@ -31,9 +31,8 @@ function normalizeTargets(targets: Array | string | null | undefined): A } export function createCommonTarget(target: string): Target { - if (!commonTargets.includes(target)) { - throw new Error(`Unknown target: ${target}`) + if (commonTargets.has(target)) { + return new Target(target) } - - return new Target(target) + throw new Error(`Unknown target: ${target}`) } \ No newline at end of file diff --git a/src/util/log.ts b/src/util/log.ts index 49f1c684730..4ff297dc991 100644 --- a/src/util/log.ts +++ b/src/util/log.ts @@ -42,7 +42,12 @@ class Logger { } warn(message: string): void { - this.log((this.isTTY ? (getEmoji("warning") + " ") : "Warning: ") + yellow(message)) + if (this.isTTY) { + this.log(getEmoji("warning") + " " + yellow(message)) + } + else { + this.log(yellow(`Warning: ${message}`)) + } } log(message: string): void { diff --git a/src/winPackager.ts b/src/winPackager.ts index 3a086bdbc7b..dfabcceb97b 100644 --- a/src/winPackager.ts +++ b/src/winPackager.ts @@ -185,7 +185,7 @@ export class WinPackager extends PlatformPackager { } else { const format = target.name - log(`Creating Windows ${format}`) + log(`Building Windows ${format}`) // we use app name here - see https://github.com/electron-userland/electron-builder/pull/204 const outFile = path.join(outDir, this.generateName(format, arch, false, "win")) promises.push(this.archiveApp(format, appOutDir, outFile) diff --git a/test/src/helpers/codeSignData.ts b/test/src/helpers/codeSignData.ts index d852b64bb54..6f2a7ec2973 100644 --- a/test/src/helpers/codeSignData.ts +++ b/test/src/helpers/codeSignData.ts @@ -1 +1 @@ -export const CSC_LINK = "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" \ No newline at end of file +export const CSC_LINK = "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" \ No newline at end of file diff --git a/test/src/macPackagerTest.ts b/test/src/macPackagerTest.ts index a0f97acbf18..09973a1d2fc 100644 --- a/test/src/macPackagerTest.ts +++ b/test/src/macPackagerTest.ts @@ -7,7 +7,7 @@ import { BuildInfo } from "out/platformPackager" import BluebirdPromise from "bluebird-lst-c" import { assertThat } from "./helpers/fileAssert" import { Platform, MacOptions, createTargets } from "out" -import { SignOptions, FlatOptions } from "electron-osx-sign-tf" +import { SignOptions } from "electron-osx-sign-tf" import { Arch } from "out" import { Target } from "out/platformPackager" import { DmgTarget } from "out/targets/dmg" @@ -15,12 +15,13 @@ import { DIR_TARGET } from "out/targets/targetFactory" import { attachAndExecute } from "out/targets/dmg" import { getTempName } from "out/util/util" import { exec } from "out/util/util" +import { MacOsTargetName } from "out/options/macOptions" test.ifOsx("two-package", () => assertPack("test-app", {targets: createTargets([Platform.MAC], null, "all")}, {signed: true, useTempDir: true})) test.ifOsx("one-package", app(platform(Platform.MAC), {signed: true})) -function createTargetTest(target: Array, expectedContents: Array) { +function createTargetTest(target: Array, expectedContents: Array) { return app({ targets: Platform.MAC.createTarget(), devMetadata: { @@ -33,7 +34,7 @@ function createTargetTest(target: Array, expectedContents: Array }, { useTempDir: true, expectedContents: expectedContents, - signed: target.includes("mas"), + signed: target.includes("mas") || target.includes("pkg"), packed: async (context) => { if (!target.includes("tar.gz")) { return @@ -49,12 +50,14 @@ function createTargetTest(target: Array, expectedContents: Array test("only zip", createTargetTest(["zip"], ["Test App ßW-1.1.0-mac.zip"])) +test("pkg", createTargetTest(["pkg"], ["Test App ßW-1.1.0.pkg"])) + test("tar.gz", createTargetTest(["tar.gz"], ["Test App ßW-1.1.0-mac.tar.gz"])) // todo failed on Travis CI //test("tar.xz", createTargetTest(["tar.xz"], ["Test App ßW-1.1.0-mac.tar.xz"])) -test.ifOsx("invalid target", t => t.throws(createTargetTest(["ttt"], [])(), "Unknown target: ttt")) +test.ifOsx("invalid target", t => t.throws(createTargetTest(["ttt"], [])(), "Unknown target: ttt")) if (process.env.CSC_KEY_PASSWORD == null || process.platform !== "darwin") { console.warn("Skip mas tests because CSC_KEY_PASSWORD is not defined") @@ -276,7 +279,6 @@ test.ifOsx("electronDist", appThrows(/ENOENT: no such file or directory/, { class CheckingMacPackager extends OsXPackager { effectiveDistOptions: any effectiveSignOptions: SignOptions - effectiveFlatOptions: FlatOptions constructor(info: BuildInfo) { super(info) @@ -302,8 +304,8 @@ class CheckingMacPackager extends OsXPackager { this.effectiveSignOptions = opts } - async doFlat(opts: FlatOptions): Promise { - this.effectiveFlatOptions = opts + async doFlat(appPath: string, outFile: string, identity: string, keychain?: string | null): Promise { + // skip } packageInDistributableFormat(appOutDir: string, targets: Array, promises: Array>): void { diff --git a/yarn.lock b/yarn.lock index 99cea376577..016b8346b1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3986,8 +3986,8 @@ typedarray@~0.0.5: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" typescript@^2.1.0-dev.20161101: - version "2.1.0-dev.20161105" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.1.0-dev.20161105.tgz#be261e6cfeccaad5026aeab22f938ae0d91f5897" + version "2.1.0-dev.20161106" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.1.0-dev.20161106.tgz#f6197280f92e2b306f40c0bc89ccece954b5764d" uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3"