Skip to content

Commit 9134f61

Browse files
committed
feat: Windows code signing from OS X
Closes #314
1 parent 2b959fe commit 9134f61

File tree

11 files changed

+56
-21
lines changed

11 files changed

+56
-21
lines changed

docs/Multi Platform Build.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Don't expect that you can build app for all platforms on one platform.
44
[prebuild](https://www.npmjs.com/package/prebuild) is a solution, but most node modules [don't provide](https://github.com/atom/node-keytar/issues/27) prebuilt binaries.
55

66
* OS Code Signing works only OS X. [Cannot be fixed](http://stackoverflow.com/a/12156576).
7-
* Windows Code Signing works only on Windows. We are going [to fix it](https://developer.mozilla.org/en/docs/Signing_an_executable_with_Authenticode) soon.
7+
* Windows Code Signing doesn't work on Linux. We are going to fix it soon.
88

99
Don't think that mentioned issues are major, you should use build servers — e.g. [AppVeyor](http://www.appveyor.com/) to build Windows app and [Travis](https://travis-ci.org) to build OS X/Linux apps.
1010

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"command-line-args": "^2.1.6",
6060
"deep-assign": "^2.0.0",
6161
"electron-packager": "^7.0.0",
62-
"electron-winstaller-fixed": "~2.3.0-beta.1",
62+
"electron-winstaller-fixed": "~2.3.0-beta.4",
6363
"fs-extra": "^0.28.0",
6464
"fs-extra-p": "^0.2.0",
6565
"globby": "^4.0.0",
@@ -70,6 +70,7 @@
7070
"progress": "^1.1.8",
7171
"progress-stream": "^1.2.0",
7272
"read-package-json": "^2.0.3",
73+
"signcode": "^0.4.0",
7374
"source-map-support": "^0.4.0",
7475
"tmp": "0.0.28"
7576
},

src/macPackager.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ export default class MacPackager extends PlatformPackager<OsXBuildOptions> {
3333

3434
async pack(outDir: string, appOutDir: string, arch: string): Promise<any> {
3535
await super.pack(outDir, appOutDir, arch)
36-
const codeSigningInfo = await this.codeSigningInfo
37-
await this.signMac(path.join(appOutDir, this.appName + ".app"), codeSigningInfo)
36+
await this.signMac(path.join(appOutDir, this.appName + ".app"), await this.codeSigningInfo)
3837
}
3938

4039
private signMac(distPath: string, codeSigningInfo: CodeSigningInfo): Promise<any> {

src/winPackager.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Platform, WinBuildOptions } from "./metadata"
55
import * as path from "path"
66
import { log, statOrNull } from "./util"
77
import { readFile, deleteFile, stat, rename, copy, emptyDir, writeFile, open, close, read } from "fs-extra-p"
8+
import { sign } from "signcode"
89

910
//noinspection JSUnusedLocalSymbols
1011
const __awaiter = require("./awaiter")
@@ -21,9 +22,7 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
2122
constructor(info: BuildInfo, cleanupTasks: Array<() => Promise<any>>) {
2223
super(info)
2324

24-
// https://developer.mozilla.org/en-US/docs/Signing_an_executable_with_Authenticode
25-
// https://github.com/Squirrel/Squirrel.Windows/pull/505
26-
if (this.options.cscLink != null && this.options.cscKeyPassword != null && process.platform !== "darwin") {
25+
if (this.options.cscLink != null && this.options.cscKeyPassword != null) {
2726
this.certFilePromise = downloadCertificate(this.options.cscLink)
2827
.then(path => {
2928
cleanupTasks.push(() => deleteFile(path, true))
@@ -58,16 +57,15 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
5857
await this.iconPath
5958

6059
if (!this.options.dist) {
61-
return super.pack(outDir, appOutDir, arch)
60+
return await super.pack(outDir, appOutDir, arch)
6261
}
6362

6463
const installerOut = computeDistOut(outDir, arch)
6564
log("Removing %s", installerOut)
66-
await
67-
BluebirdPromise.all([
68-
this.doPack(outDir, appOutDir, arch),
69-
emptyDir(installerOut)
70-
])
65+
await BluebirdPromise.all([
66+
this.doPack(outDir, appOutDir, arch),
67+
emptyDir(installerOut)
68+
])
7169

7270
const extraResources = await this.copyExtraResources(appOutDir, arch)
7371
if (extraResources.length > 0) {
@@ -82,6 +80,24 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
8280
}
8381
}
8482

83+
protected async doPack(outDir: string, appOutDir: string, arch: string) {
84+
await super.doPack(outDir, appOutDir, arch)
85+
86+
if (process.platform === "darwin" && this.options.cscLink != null && this.options.cscKeyPassword != null) {
87+
const filename = this.appName + ".exe"
88+
log(`Signing ${filename}`)
89+
await BluebirdPromise.promisify(sign)({
90+
path: path.join(appOutDir, filename),
91+
cert: await this.certFilePromise,
92+
password: this.options.cscKeyPassword,
93+
name: this.appName,
94+
site: await this.computePackageUrl(),
95+
hash: ["sha256"],
96+
overwrite: true,
97+
})
98+
}
99+
}
100+
85101
protected async computeEffectiveDistOptions(appOutDir: string, installerOutDir: string): Promise<any> {
86102
let iconUrl = this.devMetadata.build.iconUrl
87103
if (!iconUrl) {
@@ -98,11 +114,9 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
98114
}
99115
}
100116

101-
const certificateFile = await this.certFilePromise
102-
const projectUrl = await this.computePackageUrl()
103-
104117
use(this.customBuildOptions, checkConflictingOptions)
105118

119+
const projectUrl = await this.computePackageUrl()
106120
const options: any = Object.assign({
107121
name: this.metadata.name,
108122
productName: this.appName,
@@ -115,14 +129,20 @@ export class WinPackager extends PlatformPackager<WinBuildOptions> {
115129
authors: this.metadata.author.name,
116130
iconUrl: iconUrl,
117131
setupIcon: await this.iconPath,
118-
certificateFile: certificateFile,
132+
certificateFile: await this.certFilePromise,
119133
certificatePassword: this.options.cscKeyPassword,
120134
fixUpPaths: false,
121135
skipUpdateIcon: true,
122136
usePackageJson: false,
123137
noMsi: true,
124138
extraFileSpecs: this.extraNuGetFileSources == null ? null : ("\n" + (await this.extraNuGetFileSources).join("\n")),
125139
extraMetadataSpecs: projectUrl == null ? null : `\n<projectUrl>${projectUrl}</projectUrl>`,
140+
sign: {
141+
name: this.appName,
142+
site: projectUrl,
143+
hash: ["sha256"],
144+
overwrite: true,
145+
}
126146
}, this.customBuildOptions)
127147

128148
if (this.loadingGifStat != null) {

test/fixtures/test-app-one/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"author": "Foo Bar <foo@example.com>",
1111
"license": "MIT",
1212
"devDependencies": {
13-
"electron-prebuilt": "^0.37.5"
13+
"electron-prebuilt": "^0.37.6"
1414
},
1515
"build": {
1616
"app-bundle-id": "your.id",

test/fixtures/test-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"start": "electron ."
55
},
66
"devDependencies": {
7-
"electron-prebuilt": "^0.37.5"
7+
"electron-prebuilt": "^0.37.6"
88
},
99
"build": {
1010
"app-bundle-id": "your.id",

test/src/BuildTest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ test("version from electron-prebuilt dependency", () => assertPack("test-app-one
5252
tempDirCreated: projectDir => {
5353
return BluebirdPromise.all([
5454
outputJson(path.join(projectDir, "node_modules", "electron-prebuilt", "package.json"), {
55-
version: "0.37.5"
55+
version: "0.37.6"
5656
}),
5757
modifyPackageJson(projectDir, data => {
5858
data.devDependencies = {}

test/src/helpers/runTests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const rootDir = path.join(__dirname, "..", "..", "..")
1414
const testPackageDir = path.join(require("os").tmpdir(), "electron_builder_published")
1515
const testNodeModules = path.join(testPackageDir, "node_modules")
1616

17-
const electronVersion = "0.37.5"
17+
const electronVersion = "0.37.6"
1818

1919
BluebirdPromise.all([
2020
deleteOldElectronVersion(),

test/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"../typings/node.d.ts",
4242
"../typings/progress-stream.d.ts",
4343
"../typings/read-package-json.d.ts",
44+
"../typings/signcode.d.ts",
4445
"typings/ava.d.ts",
4546
"typings/decompress-zip.d.ts",
4647
"typings/json-parse-helpfulerror.d.ts",

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"typings/node.d.ts",
4646
"typings/progress-stream.d.ts",
4747
"typings/read-package-json.d.ts",
48+
"typings/signcode.d.ts",
4849
"node_modules/typescript/lib/lib.es7.d.ts",
4950
"node_modules/fs-extra-p/index.d.ts",
5051
"node_modules/7zip-bin/index.d.ts",

0 commit comments

Comments
 (0)